]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java
Merge commit '876ede6'
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / scl / AbstractCompileStructuralValueRequest.java
1 package org.simantics.structural2.scl;\r
2 \r
3 import java.util.Collections;\r
4 import java.util.Map;\r
5 \r
6 import org.simantics.databoard.Bindings;\r
7 import org.simantics.db.ReadGraph;\r
8 import org.simantics.db.Resource;\r
9 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
10 import org.simantics.db.common.request.ResourceRead2;\r
11 import org.simantics.db.exception.DatabaseException;\r
12 import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext;\r
13 import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest;\r
14 import org.simantics.db.layer0.util.RuntimeEnvironmentRequest;\r
15 import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2;\r
16 import org.simantics.db.layer0.variable.Variable;\r
17 import org.simantics.layer0.Layer0;\r
18 import org.simantics.scl.compiler.elaboration.expressions.EApply;\r
19 import org.simantics.scl.compiler.elaboration.expressions.EConstant;\r
20 import org.simantics.scl.compiler.elaboration.expressions.EVariable;\r
21 import org.simantics.scl.compiler.elaboration.expressions.Expression;\r
22 import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
23 import org.simantics.scl.compiler.environment.Environment;\r
24 import org.simantics.scl.compiler.environment.Environments;\r
25 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
26 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;\r
27 import org.simantics.scl.compiler.types.Type;\r
28 import org.simantics.structural2.scl.AbstractCompileStructuralValueRequest.CompilationContext;\r
29 \r
30 /**\r
31  * Compiles an SCL expression that is attached to a literal\r
32  * whose parent is a component that is a part of a component type.\r
33  * \r
34  * @author Antti Villberg\r
35  */\r
36 abstract public class AbstractCompileStructuralValueRequest extends AbstractExpressionCompilationRequest<CompilationContext, Variable> {\r
37     \r
38     protected final Resource relation;\r
39     \r
40     public static class CompilationContext extends AbstractExpressionCompilationContext {\r
41         public final Map<String, ComponentTypeProperty> propertyMap;\r
42         \r
43         public CompilationContext(RuntimeEnvironment runtimeEnvironment,\r
44                 Map<String, ComponentTypeProperty> propertyMap) {\r
45             super(runtimeEnvironment);\r
46             this.propertyMap = propertyMap;\r
47         }\r
48     }\r
49     \r
50     public AbstractCompileStructuralValueRequest(Resource relation) {\r
51         this.relation = relation;\r
52     }\r
53 \r
54     @Override\r
55     abstract protected String getExpressionText(ReadGraph graph) throws DatabaseException;\r
56     abstract protected Resource getIndexRoot(ReadGraph graph) throws DatabaseException;\r
57     abstract protected Resource getComponentType(ReadGraph graph) throws DatabaseException;\r
58     \r
59     @Override\r
60     protected Type getExpectedType(ReadGraph graph, CompilationContext context)\r
61             throws DatabaseException {\r
62         Layer0 L0 = Layer0.getInstance(graph);\r
63         String valueType = graph.getPossibleRelatedValue(relation, L0.RequiresValueType, Bindings.STRING);\r
64         if(valueType != null) {\r
65             try {\r
66                 return Environments.getType(context.runtimeEnvironment.getEnvironment(), valueType);\r
67             } catch (SCLExpressionCompilationException e) {\r
68                 e.printStackTrace();\r
69             }\r
70         }\r
71         return super.getExpectedType(graph, context);\r
72     }\r
73     \r
74     \r
75 \r
76     @Override\r
77     protected CompilationContext getCompilationContext(ReadGraph graph)\r
78             throws DatabaseException {\r
79         Resource indexRoot = getIndexRoot(graph);\r
80         Resource componentType = getComponentType(graph);\r
81         if(componentType == null) {\r
82             RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot));\r
83             return new CompilationContext(runtimeEnvironment, Collections.<String,ComponentTypeProperty>emptyMap());\r
84         } else {\r
85                 return graph.syncRequest(new ResourceRead2<CompilationContext>(componentType, indexRoot) {\r
86                     @Override\r
87                     public CompilationContext perform(ReadGraph graph)\r
88                             throws DatabaseException {\r
89                         RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest2(resource, resource2));\r
90                         Map<String, ComponentTypeProperty> propertyMap =\r
91                                 graph.syncRequest(new ReadComponentTypeInterfaceRequest(resource, runtimeEnvironment.getEnvironment()),\r
92                                         TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());\r
93                         return new CompilationContext(runtimeEnvironment, propertyMap);\r
94                     }\r
95                 });\r
96         }\r
97     }\r
98 \r
99     @Override\r
100     protected Type getContextVariableType() {\r
101         return VARIABLE; \r
102     }\r
103 \r
104     protected static Expression accessInputVariable(Environment environment,\r
105             org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) {\r
106         SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT);\r
107         return new EApply(new EConstant(variableParentFunction),\r
108                 new EApply(new EConstant(variableParentFunction),\r
109                         new EVariable(contextVariable)));\r
110     }\r
111     \r
112     @Override\r
113     protected Expression getVariableAccessExpression(\r
114             ReadGraph graph,\r
115             CompilationContext context,\r
116             org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,\r
117             String name) throws DatabaseException {\r
118         ComponentTypeProperty property = context.propertyMap.get(name);\r
119         if(property != null) {\r
120             Environment environment = context.runtimeEnvironment.getEnvironment();\r
121             return getPropertyFlexible(environment,\r
122                     accessInputVariable(environment, contextVariable),\r
123                     name,\r
124                     property.type);\r
125         }\r
126         else if(name.equals("input")) {\r
127             Environment environment = context.runtimeEnvironment.getEnvironment();\r
128             return accessInputVariable(environment, contextVariable);\r
129         }\r
130         else if(name.equals("self"))\r
131             return new EVariable(contextVariable);\r
132         else\r
133             return null;\r
134     }\r
135     \r
136 }\r