package org.simantics.scl.compiler.compilation; import java.util.ArrayList; import org.simantics.scl.compiler.elaboration.contexts.TypingContext; import org.simantics.scl.compiler.elaboration.expressions.Variable; import org.simantics.scl.compiler.elaboration.modules.SCLValue; import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint; import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents; import org.simantics.scl.compiler.types.TPred; import org.simantics.scl.compiler.types.TVar; import gnu.trove.impl.Constants; import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TObjectIntHashMap; import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; /** * Schedules the order of type checking. * * @author Hannu Niemistö */ public class TypeCheckingScheduler { private final CompilationContext compilationContext; private final ArrayList definitions = new ArrayList(); private final ArrayList postTypeCheckingRunnables = new ArrayList(); public TypeCheckingScheduler(CompilationContext compilationContext) { this.compilationContext = compilationContext; } public void addTypeInferableDefinition(TypeInferableDefinition definition) { definitions.add(definition); } public void addPostTypeCheckingRunnable(Runnable runnable) { postTypeCheckingRunnables.add(runnable); } public void schedule() { final TObjectIntHashMap allRefs = new TObjectIntHashMap(definitions.size(), Constants.DEFAULT_LOAD_FACTOR, -1); for(int i=0;i(); for(int c : component) definitions.get(c).initializeTypeChecking(context); for(int c : component) definitions.get(c).checkType(context); context.solveSubsumptions(definitions.get(component[0]).getLocation()); for(int c : component) definitions.get(c).solveConstraints(); THashSet varSet = new THashSet(); for(int c : component) definitions.get(c).collectFreeTypeVariables(varSet); TVar[] vars = varSet.toArray(new TVar[varSet.size()]); THashSet constraintSet = new THashSet(); for(int c : component) for(Variable evidence : definitions.get(c).getFreeEvidence()) constraintSet.add((TPred)evidence.getType()); TPred[] constraints = constraintSet.toArray(new TPred[constraintSet.size()]); THashMap constraintMap = null; for(TPred constraint : constraints) if(constraint.containsMetaVars()) { if(constraintMap == null) { constraintMap = new THashMap(); for(int c : component) for(Constraint cons : definitions.get(c).getUnsolvedConstraints()) constraintMap.put(cons.constraint, cons); } Constraint cons = constraintMap.get(constraint); compilationContext.errorLog.log(cons.getDemandLocation(), "Constrain " + constraint + " contains free variables not mentioned in the type of the value."); } for(int c : component) definitions.get(c).injectEvidence(vars, constraints); } }