X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fexpressions%2FEEntityTypeAnnotation.java;h=f0363dcdffa349fc8f85870ac211fff5085d3036;hb=refs%2Fchanges%2F38%2F238%2F2;hp=108b4b707557ce188a44761f693b56c5588c0951;hpb=969bd23cab98a79ca9101af33334000879fb60c5;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEntityTypeAnnotation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEntityTypeAnnotation.java index 108b4b707..f0363dcdf 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEntityTypeAnnotation.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EEntityTypeAnnotation.java @@ -1,119 +1,120 @@ -package org.simantics.scl.compiler.elaboration.expressions; - -import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*; -import gnu.trove.map.hash.THashMap; - -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; - -public class EEntityTypeAnnotation extends ASTExpression { - - Expression expression; - Token entityTypeName; - SCLEntityType entityType; - Query query; // optional - THashMap 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(); - 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); - } - -} +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 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(); + 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); + } + +}