]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java
(refs #7278, refs #7279) Small fixes to InternalCompilerExceptions
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / scl / GraphPropertyRelation.java
1 package org.simantics.modeling.scl;
2
3 import org.simantics.db.Resource;
4 import org.simantics.scl.compiler.common.names.Name;
5 import org.simantics.scl.compiler.common.names.Names;
6 import org.simantics.scl.compiler.compilation.CompilationContext;
7 import org.simantics.scl.compiler.elaboration.chr.plan.PlanContext;
8 import org.simantics.scl.compiler.elaboration.expressions.EApply;
9 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
10 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
11 import org.simantics.scl.compiler.elaboration.expressions.Expression;
12 import org.simantics.scl.compiler.elaboration.expressions.Variable;
13 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
14 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
15 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
16 import org.simantics.scl.compiler.environment.Environment;
17 import org.simantics.scl.compiler.errors.Locations;
18 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
19 import org.simantics.scl.compiler.types.TPred;
20 import org.simantics.scl.compiler.types.TVar;
21 import org.simantics.scl.compiler.types.Type;
22 import org.simantics.scl.compiler.types.Types;
23
24 public class GraphPropertyRelation implements SCLRelation {
25
26     Resource propertyRelation;
27     Type valueType;
28     Type[] parameterTypes;
29
30     private static final Type RESOURCE = Types.con("Simantics/DB", "Resource");
31
32     public GraphPropertyRelation(Resource propertyRelation, Type valueType) {
33         this.propertyRelation = propertyRelation;
34         this.valueType = valueType;
35         this.parameterTypes = new Type[] { RESOURCE, valueType };
36     }
37
38     @Override
39     public TVar[] getTypeVariables() {
40         return TVar.EMPTY_ARRAY;
41     }
42
43     @Override
44     public TPred[] getTypeConstraints() {
45         return new TPred[] {Types.pred(Types.SERIALIZABLE, valueType)};
46     }
47
48     @Override
49     public Type[] getParameterTypes() {
50         return parameterTypes;
51     }
52
53     @Override
54     public double getSelectivity(int boundVariables) {
55         switch(boundVariables) {
56         case FF:
57         case FB: return Double.POSITIVE_INFINITY;
58         case BF: return 1.0;
59         case BB: return 0.01;
60         default: throw new IllegalArgumentException();
61         }
62     }
63
64     @Override
65     public int getRequiredVariablesMask() {
66         return BF;
67     }
68
69     private static final Name POSSIBLE_RELATED_VALUE = Name.create("Simantics/DB", "possibleRelatedValue");
70
71     @Override
72     public void generate(long location, QueryCompilationContext context,
73             Type[] typeParameters, Variable[] parameters, int boundVariables) {
74         Expression possibleValue = new EApply(
75                 Locations.NO_LOCATION,
76                 Types.READ_GRAPH,
77                 context.getCompilationContext().getConstant(POSSIBLE_RELATED_VALUE, valueType),
78                 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
79                 new EVariable(parameters[0]),
80                 new EExternalConstant(propertyRelation, RESOURCE)
81                 );
82         switch(boundVariables) {
83         case BB: {
84             Variable temp = new Variable("temp", valueType);
85             context.condition(new EApply(
86                     context.getCompilationContext().getConstant(Names.Builtin_equals, valueType),
87                     new Expression[] {
88                             new EVariable(temp),
89                             new EVariable(parameters[1])
90                     }
91                     ));
92             context.iterateMaybe(temp, possibleValue);
93         } break;
94         case BF: context.iterateMaybe(parameters[1], possibleValue);
95         break;
96         default: throw new IllegalArgumentException();
97         }
98     }
99
100     private static final Name CLAIM_RELATED_VALUE = Name.create("Simantics/DB", "claimRelatedValue");
101
102     @Override
103     public Expression generateEnforce(long location, EnforcingContext context,
104             Type[] typeParameters, Variable[] parameters) {
105         return new EApply(
106                 Locations.NO_LOCATION,
107                 Types.WRITE_GRAPH,
108                 context.getCompilationContext().getConstant(CLAIM_RELATED_VALUE, valueType),
109                 context.getEvidence(location, Types.pred(Types.SERIALIZABLE, valueType)),
110                 new EVariable(parameters[0]),
111                 new EExternalConstant(propertyRelation, RESOURCE),
112                 new EVariable(parameters[1])
113                 );
114     }
115
116     @Override
117     public int getPhase() {
118         return 0;
119     }
120
121     @Override
122     public void generateIterate(PlanContext context, CodeWriter w, long location, int boundMask, Variable[] variables,
123             Expression[] expressions, Expression[] typeConstraintEvidenceParameters) {
124         CompilationContext compilationContext = context.context;
125         switch(boundMask) {
126         case BF:
127             context.iterateMaybe(location, w, variables[1],
128                     w.apply(location,
129                             compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
130                             typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
131                             expressions[0].toVal(compilationContext, w),
132                             w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
133             break;
134         case BB:
135             context.checkEqualsJust(location, w, expressions[1].toVal(compilationContext, w),
136                     w.apply(location,
137                             compilationContext.environment.getValue(POSSIBLE_RELATED_VALUE).getValue().createSpecialization(valueType),
138                             typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
139                             expressions[0].toVal(compilationContext, w),
140                             w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE)));
141             break;
142         default: throw new IllegalArgumentException();
143         }
144     }
145
146     @Override
147     public void generateEnforce(PlanContext context, CodeWriter w, long location, Expression[] parameters, Expression[] typeConstraintEvidenceParameters) {
148         CompilationContext compilationContext = context.context;
149         w.apply(location,
150                 compilationContext.environment.getValue(CLAIM_RELATED_VALUE).getValue().createSpecialization(valueType),
151                 typeConstraintEvidenceParameters[0].toVal(compilationContext, w),
152                 parameters[0].toVal(compilationContext, w),
153                 w.getModuleWriter().getExternalConstant(propertyRelation, Types.RESOURCE),
154                 parameters[1].toVal(compilationContext, w));
155     }
156 }