1 package org.simantics.scl.compiler.compilation;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
6 import org.simantics.scl.compiler.elaboration.expressions.Variable;
7 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
8 import org.simantics.scl.compiler.internal.elaboration.constraints.Constraint;
9 import org.simantics.scl.compiler.internal.elaboration.utils.StronglyConnectedComponents;
10 import org.simantics.scl.compiler.types.TPred;
11 import org.simantics.scl.compiler.types.TVar;
13 import gnu.trove.impl.Constants;
14 import gnu.trove.map.hash.THashMap;
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.set.hash.THashSet;
17 import gnu.trove.set.hash.TIntHashSet;
20 * Schedules the order of type checking.
22 * @author Hannu Niemistö
24 public class TypeCheckingScheduler {
25 private final CompilationContext compilationContext;
27 private final ArrayList<TypeInferableDefinition> definitions = new ArrayList<TypeInferableDefinition>();
28 private final ArrayList<Runnable> postTypeCheckingRunnables = new ArrayList<Runnable>();
30 public TypeCheckingScheduler(CompilationContext compilationContext) {
31 this.compilationContext = compilationContext;
34 public void addTypeInferableDefinition(TypeInferableDefinition definition) {
35 definitions.add(definition);
38 public void addPostTypeCheckingRunnable(Runnable runnable) {
39 postTypeCheckingRunnables.add(runnable);
42 public void schedule() {
43 final TObjectIntHashMap<Object> allRefs =
44 new TObjectIntHashMap<Object>(definitions.size(), Constants.DEFAULT_LOAD_FACTOR, -1);
46 for(int i=0;i<definitions.size();++i)
47 for(Object definedObject : definitions.get(i).getDefinedObjects())
48 allRefs.put(definedObject, i);
49 new StronglyConnectedComponents(definitions.size()) {
51 TIntHashSet set = new TIntHashSet();
54 protected void reportComponent(int[] component) {
59 protected int[] findDependencies(int u) {
60 definitions.get(u).collectRefs(allRefs, set);
61 int[] result = set.toArray();
68 for(Runnable runnable : postTypeCheckingRunnables)
72 private void typeCheck(int[] component) {
73 TypingContext context = new TypingContext(compilationContext);
74 context.recursiveValues = new THashSet<SCLValue>();
76 for(int c : component)
77 definitions.get(c).initializeTypeChecking(context);
78 for(int c : component)
79 definitions.get(c).checkType(context);
80 context.solveSubsumptions(definitions.get(component[0]).getLocation());
81 for(int c : component)
82 definitions.get(c).solveConstraints();
84 THashSet<TVar> varSet = new THashSet<TVar>();
85 for(int c : component)
86 definitions.get(c).collectFreeTypeVariables(varSet);
87 TVar[] vars = varSet.toArray(new TVar[varSet.size()]);
89 THashSet<TPred> constraintSet = new THashSet<TPred>();
90 for(int c : component)
91 for(Variable evidence : definitions.get(c).getFreeEvidence())
92 constraintSet.add((TPred)evidence.getType());
93 TPred[] constraints = constraintSet.toArray(new TPred[constraintSet.size()]);
95 THashMap<TPred, Constraint> constraintMap = null;
96 for(TPred constraint : constraints)
97 if(constraint.containsMetaVars()) {
98 if(constraintMap == null) {
99 constraintMap = new THashMap<TPred, Constraint>();
100 for(int c : component)
101 for(Constraint cons : definitions.get(c).getUnsolvedConstraints())
102 constraintMap.put(cons.constraint, cons);
104 Constraint cons = constraintMap.get(constraint);
105 compilationContext.errorLog.log(cons.getDemandLocation(),
106 "Constrain " + constraint +
107 " contains free variables not mentioned in the type of the value.");
110 for(int c : component)
111 definitions.get(c).injectEvidence(vars, constraints);