-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;\r
-\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.java.EqRelation;\r
-import org.simantics.scl.compiler.elaboration.query.QAtom;\r
-import org.simantics.scl.compiler.elaboration.query.Query;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.Attribute;\r
-import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.AttributeBinding;\r
-import org.simantics.scl.compiler.environment.AmbiguousNameException;\r
-import org.simantics.scl.compiler.environment.Environments;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.parsing.Token;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-\r
-public class EEntityTypeAnnotation extends ASTExpression {\r
- \r
- Expression expression;\r
- Token entityTypeName;\r
- SCLEntityType entityType;\r
- Query query; // optional\r
- THashMap<String, AttributeBinding> attributeBindingMap;\r
-\r
- public EEntityTypeAnnotation(Expression expression, Token entityTypeName,\r
- Query query) {\r
- this.expression = expression;\r
- this.entityTypeName = entityTypeName;\r
- this.query = query;\r
- }\r
-\r
- @Override\r
- public Expression resolve(TranslationContext context) {\r
- // Resolve a subexpression\r
- expression = expression.resolve(context);\r
- \r
- // Check that we are inside a query\r
- if(context.currentPreQuery == null) {\r
- context.getErrorLog().log(location, "Entity type annotations can be used only in queries.");\r
- return new EError(location);\r
- }\r
- \r
- // Resolve entity type\r
- try {\r
- entityType = Environments.getEntityType(context.getEnvironment(), entityTypeName.text);\r
- } catch (AmbiguousNameException e) {\r
- context.getErrorLog().log(location, e.getMessage());\r
- return new EError(location);\r
- }\r
- if(entityType == null) {\r
- context.getErrorLog().log(location, "Couldn't resolve entity type " + entityTypeName.text + ".");\r
- return new EError(location);\r
- }\r
-\r
- // Rewrite the subexpression as a separate query if it is not a variable\r
- Variable base;\r
- if(expression instanceof EVariable)\r
- base = ((EVariable)expression).variable;\r
- else {\r
- base = new Variable("?" + entityTypeName.text);\r
- context.currentPreQuery.extraVariables.add(base);\r
- context.currentPreQuery.sideQueries.add(loc(expression.location,\r
- new QAtom(EqRelation.INSTANCE, new EVariable(base), expression)));\r
- expression = loc(expression.location, new EVariable(base));\r
- }\r
- \r
- // Resolve a related query if it exists\r
- if(query != null) {\r
- EEntityTypeAnnotation oldEntityTypeAnnotation = context.currentEntityTypeAnnotation;\r
- attributeBindingMap = new THashMap<String, AttributeBinding>();\r
- context.currentEntityTypeAnnotation = this;\r
- query = query.resolve(context);\r
- context.currentPreQuery.sideQueries.add(query);\r
- context.currentEntityTypeAnnotation = oldEntityTypeAnnotation;\r
- AttributeBinding[] attributeBindings;\r
- if(attributeBindingMap.isEmpty())\r
- attributeBindings = AttributeBinding.EMPTY_ARRAY;\r
- else {\r
- attributeBindings = attributeBindingMap.values().toArray(new AttributeBinding[attributeBindingMap.size()]);\r
- for(AttributeBinding binding : attributeBindings)\r
- context.currentPreQuery.extraVariables.add(binding.variable);\r
- }\r
- context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, attributeBindings));\r
- }\r
- else\r
- context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, AttributeBinding.EMPTY_ARRAY));\r
- return expression;\r
- }\r
- \r
- @Override\r
- public void setLocationDeep(long loc) {\r
- if(location == Locations.NO_LOCATION) {\r
- location = loc;\r
- expression.setLocationDeep(loc);\r
- query.setLocationDeep(loc);\r
- }\r
- }\r
-\r
- public Expression resolveAttribute(TranslationContext context, long location, String name) {\r
- AttributeBinding binding = attributeBindingMap.get(name);\r
- if(binding == null) {\r
- Attribute attribute = entityType.getAttribute(name);\r
- if(attribute == null) {\r
- context.getErrorLog().log(location, "Attribute " + name + " is not defined in entity type " + entityTypeName.text + ".");\r
- return new EError(location);\r
- }\r
- binding = new AttributeBinding(attribute, new Variable("#"+name));\r
- attributeBindingMap.put(name, binding);\r
- }\r
- return new EVariable(binding.variable);\r
- }\r
- \r
- @Override\r
- public Expression accept(ExpressionTransformer transformer) {\r
- return transformer.transform(this);\r
- }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.loc;
+
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.java.EqRelation;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+import org.simantics.scl.compiler.elaboration.query.Query;
+import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
+import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.Attribute;
+import org.simantics.scl.compiler.elaboration.relations.SCLEntityType.AttributeBinding;
+import org.simantics.scl.compiler.environment.AmbiguousNameException;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.parsing.Token;
+
+import gnu.trove.map.hash.THashMap;
+
+public class EEntityTypeAnnotation extends ASTExpression {
+
+ Expression expression;
+ Token entityTypeName;
+ SCLEntityType entityType;
+ Query query; // optional
+ THashMap<String, AttributeBinding> attributeBindingMap;
+
+ public EEntityTypeAnnotation(Expression expression, Token entityTypeName,
+ Query query) {
+ this.expression = expression;
+ this.entityTypeName = entityTypeName;
+ this.query = query;
+ }
+
+ @Override
+ public Expression resolve(TranslationContext context) {
+ // Resolve a subexpression
+ expression = expression.resolve(context);
+
+ // Check that we are inside a query
+ if(context.currentPreQuery == null) {
+ context.getErrorLog().log(location, "Entity type annotations can be used only in queries.");
+ return new EError(location);
+ }
+
+ // Resolve entity type
+ try {
+ entityType = Environments.getEntityType(context.getEnvironment(), entityTypeName.text);
+ } catch (AmbiguousNameException e) {
+ context.getErrorLog().log(location, e.getMessage());
+ return new EError(location);
+ }
+ if(entityType == null) {
+ context.getErrorLog().log(location, "Couldn't resolve entity type " + entityTypeName.text + ".");
+ return new EError(location);
+ }
+
+ // Rewrite the subexpression as a separate query if it is not a variable
+ Variable base;
+ if(expression instanceof EVariable)
+ base = ((EVariable)expression).variable;
+ else {
+ base = new Variable("?" + entityTypeName.text);
+ context.currentPreQuery.extraVariables.add(base);
+ context.currentPreQuery.sideQueries.add(loc(expression.location,
+ new QAtom(EqRelation.INSTANCE, new EVariable(base), expression)));
+ expression = loc(expression.location, new EVariable(base));
+ }
+
+ // Resolve a related query if it exists
+ if(query != null) {
+ EEntityTypeAnnotation oldEntityTypeAnnotation = context.currentEntityTypeAnnotation;
+ attributeBindingMap = new THashMap<String, AttributeBinding>();
+ context.currentEntityTypeAnnotation = this;
+ query = query.resolve(context);
+ context.currentPreQuery.sideQueries.add(query);
+ context.currentEntityTypeAnnotation = oldEntityTypeAnnotation;
+ AttributeBinding[] attributeBindings;
+ if(attributeBindingMap.isEmpty())
+ attributeBindings = AttributeBinding.EMPTY_ARRAY;
+ else {
+ attributeBindings = attributeBindingMap.values().toArray(new AttributeBinding[attributeBindingMap.size()]);
+ for(AttributeBinding binding : attributeBindings)
+ context.currentPreQuery.extraVariables.add(binding.variable);
+ }
+ context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, attributeBindings));
+ }
+ else
+ context.currentPreQuery.sideQueries.add(entityType.generateQuery(context, base, AttributeBinding.EMPTY_ARRAY));
+ return expression;
+ }
+
+ @Override
+ public void setLocationDeep(long loc) {
+ if(location == Locations.NO_LOCATION) {
+ location = loc;
+ expression.setLocationDeep(loc);
+ query.setLocationDeep(loc);
+ }
+ }
+
+ public Expression resolveAttribute(TranslationContext context, long location, String name) {
+ AttributeBinding binding = attributeBindingMap.get(name);
+ if(binding == null) {
+ Attribute attribute = entityType.getAttribute(name);
+ if(attribute == null) {
+ context.getErrorLog().log(location, "Attribute " + name + " is not defined in entity type " + entityTypeName.text + ".");
+ return new EError(location);
+ }
+ binding = new AttributeBinding(attribute, new Variable("#"+name));
+ attributeBindingMap.put(name, binding);
+ }
+ return new EVariable(binding.variable);
+ }
+
+ @Override
+ public Expression accept(ExpressionTransformer transformer) {
+ return transformer.transform(this);
+ }
+
+}