All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.core.function.index.FunctionPathFinder Maven / Gradle / Ivy

package org.snapscript.core.function.index;

import static org.snapscript.core.type.Phase.DEFINE;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.snapscript.common.Progress;
import org.snapscript.core.EntityCache;
import org.snapscript.core.constraint.AnyConstraint;
import org.snapscript.core.constraint.Constraint;
import org.snapscript.core.convert.TypeInspector;
import org.snapscript.core.error.InternalStateException;
import org.snapscript.core.scope.Scope;
import org.snapscript.core.type.Phase;
import org.snapscript.core.type.Type;

public class FunctionPathFinder {
   
   private final EntityCache> paths;  
   private final TypeInspector inspector;  
   private final Constraint any;
   private final long wait;
   
   public FunctionPathFinder() {
      this(60000);
   }
   
   public FunctionPathFinder(long wait) {
      this.paths = new EntityCache>();
      this.inspector = new TypeInspector();
      this.any = new AnyConstraint();
      this.wait = wait;
   }

   public List findPath(Type type) {
      List path = paths.fetch(type);
      
      if(path == null) {
         List result = new ArrayList();
      
         findTypes(type, result);
         paths.cache(type, result);
         
         return result;
      }
      return path;
   }

   private void findTypes(Type type, List done) {
      Progress progress = type.getProgress();
      Scope scope = type.getScope();
      Type base = any.getType(scope);
      Class real = type.getType();
      
      if(!progress.wait(DEFINE, wait)) {
         throw new InternalStateException("Type '" + type +"' has not been defined");
      }
      findClasses(type, done);
      
      if(real == null) {
         findTraits(type, done);
      }
      done.add(base); // any is very last
   }
   
   private void findTraits(Type type, List done) {
      List types = type.getTypes();
      Iterator iterator = types.iterator();
      
      if(iterator.hasNext()) {
         Scope scope = type.getScope();
         Constraint next = iterator.next(); // next in line, i.e base
         
         while(iterator.hasNext()) {
            Constraint trait = iterator.next();
            Type match = trait.getType(scope);
            
            if(!done.contains(match)) {
               done.add(match);
            }
         }
         Type match = next.getType(scope);
         
         if(!done.contains(match)) {
            findTraits(match, done);
         }
      }
   }
   
   private void findClasses(Type type, List done) {
      List types = type.getTypes();
      Iterator iterator = types.iterator();
      Scope scope = type.getScope();
      
      if(!inspector.isProxy(type) && !inspector.isAny(type)) {
         done.add(type);
      }
      while(iterator.hasNext()) {
         Constraint next = iterator.next();
         Type match = next.getType(scope);
         
         if(!done.contains(match)) {
            findClasses(match, done);
         }
      }
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy