]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/query/Query.java
(refs #7375) Replaced collectFreeVariables method by a visitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / query / Query.java
1 package org.simantics.scl.compiler.elaboration.query;
2
3 import java.util.ArrayList;
4 import java.util.Set;
5
6 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
7 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
8 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
9 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
10 import org.simantics.scl.compiler.elaboration.expressions.EError;
11 import org.simantics.scl.compiler.elaboration.expressions.Expression;
12 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
13 import org.simantics.scl.compiler.elaboration.expressions.Variable;
14 import org.simantics.scl.compiler.elaboration.expressions.VariableProcedure;
15 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
16 import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor;
17 import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor;
18 import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor;
19 import org.simantics.scl.compiler.elaboration.query.compilation.ConstraintCollectionContext;
20 import org.simantics.scl.compiler.elaboration.query.compilation.DerivateException;
21 import org.simantics.scl.compiler.elaboration.query.compilation.DynamicProgrammingOrdering;
22 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
23 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
24 import org.simantics.scl.compiler.elaboration.query.compilation.QueryConstraint;
25 import org.simantics.scl.compiler.elaboration.query.compilation.UnsolvableQueryException;
26 import org.simantics.scl.compiler.elaboration.relations.CompositeRelation;
27 import org.simantics.scl.compiler.elaboration.relations.LocalRelation;
28 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
29 import org.simantics.scl.compiler.internal.parsing.Symbol;
30
31 import gnu.trove.map.hash.THashMap;
32 import gnu.trove.map.hash.TIntObjectHashMap;
33 import gnu.trove.map.hash.TObjectIntHashMap;
34 import gnu.trove.set.hash.TIntHashSet;
35
36 public abstract class Query extends Symbol {
37     public static final Query[] EMPTY_ARRAY = new Query[0];
38     
39     public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
40     public abstract void checkType(TypingContext context);
41     
42     public Query resolve(TranslationContext context) {
43         throw new InternalCompilerError(location, getClass().getSimpleName() + " does not support resolve.");
44     }
45     
46     public Expression generateEnforce(EnforcingContext context) {
47         context.getErrorLog().log(location, getClass().getSimpleName() + " does not support enforcing.");
48         return new EError(location);
49     }
50     
51     public abstract void collectConstraints(ConstraintCollectionContext context) throws UnsolvableQueryException;
52     
53     protected QueryConstraint[] getOrderedConstraints(QueryCompilationContext context) throws UnsolvableQueryException {
54         ConstraintCollectionContext collectionContext = new ConstraintCollectionContext(context);
55         collectConstraints(collectionContext);
56         QueryConstraint[] constraints = collectionContext.getConstraints();
57         DynamicProgrammingOrdering.order(collectionContext, constraints, 0L);
58         return constraints;
59     }
60     
61     protected void applyConstraints(QueryCompilationContext context, QueryConstraint[] constraints) {
62         for(int i=constraints.length-1;i>=0;--i)
63             constraints[i].generateAndUpdateCost(context);
64     }
65     
66     public void generate(QueryCompilationContext context) throws UnsolvableQueryException {
67         applyConstraints(context, getOrderedConstraints(context));
68     }
69     
70     protected static final TIntObjectHashMap<ArrayList<Query>> NO_DERIVATE = new TIntObjectHashMap<ArrayList<Query>>();
71     
72     public static class Diffable {
73         public int id;
74         SCLRelation relation;
75         public Variable[] parameters;
76         public Diffable(int id, SCLRelation relation, Variable[] parameters) {
77             this.id = id;
78             this.relation = relation;
79             this.parameters = parameters;
80         }
81     }
82     
83     public static class Diff {
84         public int id;
85         public Query query;
86         
87         public Diff(int id, Query query) {
88             this.id = id;
89             this.query = query;
90         }
91     }
92     
93     public static final Diff[] NO_DIFF = new Diff[0];
94     
95     public Diff[] derivate(THashMap<LocalRelation, Diffable> diffables) throws DerivateException {
96         throw new DerivateException(location);
97     }
98     
99     public static final QDisjunction EMPTY_QUERY = new QDisjunction();
100     
101     public Query removeRelations(Set<SCLRelation> relations) {
102         throw new UnsupportedOperationException();
103     }
104     
105     public Query copy() {
106         return replace(new ReplaceContext(null));
107     }
108     
109     public Query copy(TypingContext context) {
110         return replace(new ReplaceContext(context));
111     }
112     
113     public abstract Query replace(ReplaceContext context);
114
115     public abstract void setLocationDeep(long loc);
116
117     public abstract void accept(QueryVisitor visitor);
118
119     public void collectRelationRefs(
120             final TObjectIntHashMap<SCLRelation> allRefs, final TIntHashSet refs) {
121         accept(new StandardExpressionVisitor() {
122             @Override
123             public void visit(QAtom query) {
124                 visit(query.relation);
125             }
126             private void visit(SCLRelation relation) {
127                 int id = allRefs.get(relation);
128                 if(id >= 0)
129                     refs.add(id);
130                 else if(relation instanceof CompositeRelation)
131                     for(SCLRelation subrelation : ((CompositeRelation)relation).getSubrelations())
132                         visit(subrelation);
133             }
134         });
135     }
136     
137     public TIntObjectHashMap<ArrayList<Query>> splitToPhases() {
138         TIntObjectHashMap<ArrayList<Query>> result = new TIntObjectHashMap<ArrayList<Query>>(2);
139         splitToPhases(result);
140         return result;
141     }
142
143     public void splitToPhases(TIntObjectHashMap<ArrayList<Query>> result) {
144         throw new UnsupportedOperationException(getClass().getSimpleName() + " does not support splitToPhases.");
145     }
146     
147     @Override
148     public String toString() {
149         StringBuilder b = new StringBuilder();
150         ExpressionToStringVisitor visitor = new ExpressionToStringVisitor(b);
151         accept(visitor);
152         return b.toString();
153     }
154     
155     public abstract Query accept(QueryTransformer transformer);
156     
157     public void forVariables(VariableProcedure procedure) {
158         accept(new ForVariablesUsesVisitor(procedure));
159     }
160     public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
161         accept(new CollectRefsVisitor(allRefs, refs));
162     }
163 }