diff options
author | Ed Willink | 2016-05-08 12:37:17 +0000 |
---|---|---|
committer | Ed Willink | 2016-05-18 13:17:45 +0000 |
commit | d502fb47d034b908725565ab50f7300d952bd570 (patch) | |
tree | 40967e9a1713d08ccbc11cfc3a26be251d706b0a | |
parent | 187b5ad74de61061f4b489760be78e873f012431 (diff) | |
download | org.eclipse.qvtd-d502fb47d034b908725565ab50f7300d952bd570.tar.gz org.eclipse.qvtd-d502fb47d034b908725565ab50f7300d952bd570.tar.xz org.eclipse.qvtd-d502fb47d034b908725565ab50f7300d952bd570.zip |
[486722] Introduce VariablesAnalysis
10 files changed, 1432 insertions, 1217 deletions
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java index 25dc67a8b..3b6d77555 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/AbstractQVTr2QVTcRelations.java @@ -24,20 +24,18 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.CollectionLiteralExp; import org.eclipse.ocl.pivot.CollectionLiteralPart; import org.eclipse.ocl.pivot.CollectionType; -import org.eclipse.ocl.pivot.CompleteClass; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.IntegerLiteralExp; -import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.NavigationCallExp; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.OperationCallExp; -import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.VariableExp; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.CompilerChainException; +import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.VariablesAnalysis.VariableAnalysis; import org.eclipse.qvtd.pivot.qvtbase.Domain; import org.eclipse.qvtd.pivot.qvtbase.Pattern; import org.eclipse.qvtd.pivot.qvtbase.Predicate; @@ -49,8 +47,6 @@ import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern; import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain; import org.eclipse.qvtd.pivot.qvtcorebase.CorePattern; import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern; -import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment; -import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory; import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable; import org.eclipse.qvtd.pivot.qvtcorebase.VariableAssignment; import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern; @@ -64,6 +60,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp; import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem; import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; +/** + * AbstractQVTr2QVTcRelations defines the mapping from a Relation, with a nested AbstractEnforceableRelationDomain2CoreMapping + * for each distinct enforcement of that relation and a further nested AbstractOtherRelationDomain2CoreDomain for each + * other domain of the distinct enforcement. + */ /*public*/ abstract class AbstractQVTr2QVTcRelations extends QVTcoreHelper { protected abstract class AbstractEnforceableRelationDomain2CoreMapping @@ -77,21 +78,242 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; protected final @NonNull CoreDomain cOtherDomain; protected final @NonNull GuardPattern cOtherGuardPattern; protected final @NonNull BottomPattern cOtherBottomPattern; + protected final @NonNull Set<@NonNull Variable> rOtherBoundVariables; // All variables defined in this other domain + protected final @NonNull Set<@NonNull Variable> rOtherReferredVariables; // All variables defined or referenced in this other domain + protected final @NonNull List<@NonNull Variable> rOtherRootVariables; // The template expression variable (the root variable of this other domain pattern) public AbstractOtherRelationDomain2CoreDomain(@NonNull RelationDomain rOtherDomain) { this.rOtherDomain = rOtherDomain; this.rOtherDomainName = ClassUtil.nonNullState(rOtherDomain.getName()); this.rOtherTypedModel = ClassUtil.nonNullState(rOtherDomain.getTypedModel()); this.cOtherTypedModel = getCoreTypedModel(rOtherTypedModel); - this.cOtherDomain = qvtr2qvtc.whenCoreDomain(cMapping, rOtherDomainName); - cOtherDomain.setTypedModel(cOtherTypedModel); + this.cOtherDomain = createCoreDomain(cOtherTypedModel, false); cOtherDomain.setIsCheckable(rOtherDomain.isIsCheckable()); - cOtherDomain.setIsEnforceable(false); this.cOtherGuardPattern = ClassUtil.nonNullState(cOtherDomain.getGuardPattern()); this.cOtherBottomPattern = ClassUtil.nonNullState(cOtherDomain.getBottomPattern()); + + this.rOtherBoundVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherBoundVariables(rOtherBoundVariables, rOtherDomain); + this.rOtherReferredVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherReferredVariables(rOtherReferredVariables, rOtherDomain); + this.rOtherRootVariables = getRootVariables(rOtherDomain); + + for (@NonNull Variable rVariable : rOtherBoundVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setOtherBound(cOtherDomain); + } + for (@NonNull Variable rVariable : rOtherReferredVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setOtherReferred(cOtherDomain); + } + for (@NonNull Variable rVariable : rOtherRootVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot(); + } + } + + // new + private void mapOtherCollectionTemplateExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull CollectionTemplateExp cte) throws CompilerChainException { + /** + * Each PropertyTemplateItem whose value is a CollectionTemplateExp + * converts to a VariableAssignment and Predicates. + * + * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; + */ + Variable vcte = ClassUtil.nonNullState(cte.getBindsTo()); + Variable mvcte = variablesAnalysis.getCoreVariable(vcte); + NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), traceProperty); + VariableAssignment a = createVariableAssignment(mvcte, pce); + cMiddleBottomPattern.getAssignment().add(a); + /** + * Each CollectionTemplateExp member that is not a variable + * converts to a VariableAssignment of a new variable the member expression. + * + * ve1:T1{tp = ve2:Collection{a++b}} => a := a; + */ + Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<@NonNull OCLExpression, @NonNull Variable>(); + List<@NonNull OCLExpression> rMembers = ClassUtil.nullFree(cte.getMember()); + for (@NonNull OCLExpression rMember : rMembers) { + Variable mVariable; + if (rMember instanceof TemplateExp) { + TemplateExp rTemplateExp = (TemplateExp)rMember; + mapOtherTemplateExpression(rTemplateExp); + Variable rVariable = ClassUtil.nonNullState(rTemplateExp.getBindsTo()); + mVariable = variablesAnalysis.getCoreVariable(rVariable); + } + else if (rMember instanceof VariableExp) { + Variable rVariable = ClassUtil.nonNullState((Variable)((VariableExp)rMember).getReferredVariable()); + mVariable = variablesAnalysis.getCoreVariable(rVariable); + } + else { + OCLExpression mMember = mapExpression(rMember); + String uniqueName = variablesAnalysis.getUniqueVariableName("member", mMember); + mVariable = createVariable(uniqueName, mMember); // FIXME orphan + } + rMember2mVariable.put(rMember, mVariable); + } +// CollectionTemplateExp cte = (CollectionTemplateExp) ptv; +// Variable vcte = ClassUtil.nonNullState(cte.getBindsTo()); +// Variable mvcte = doRVarToMVar(vcte); +// PropertyCallExp pce = createPropertyCallExp(ve1, tp); +// VariableAssignment a = createVariableAssignment(mvcte, pce); +// mb.getAssignment().add(a); + + + CollectionType collectionType = ClassUtil.nonNullState(cte.getReferredCollectionType()); + int size = rMembers.size(); + Variable rRest = cte.getRest(); + if (rRest == null) { + /** + * The predicate for a CollectionTemplateExp without a rest variable is a total comparison. + * + * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; ve2 = Collection{a,b}; + */ + List<@NonNull CollectionLiteralPart> mParts = new ArrayList<@NonNull CollectionLiteralPart>(); + for (@NonNull OCLExpression rMember : rMembers) { + Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); + CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable)); + mParts.add(mItem); + } + CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts); + addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle); + } + else { + Variable mRest = variablesAnalysis.getCoreVariable(rRest); + if (collectionType.isOrdered()) { + /** + * The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment. + * + * ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->subCollection(3,ve2->size()); + */ + VariableExp vRest = createVariableExp(rRest); + String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence"; + IntegerLiteralExp eStart = createIntegerLiteralExp(size); + OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size"); + OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, vRest, eStart, eFinish); + VariableAssignment aRest = createVariableAssignment(mRest, eTail); + cMiddleBottomPattern.getAssignment().add(aRest); + /** + * The predicates for each ordered CollectionTemplateExp member variable is an element comparison. + * + * ve1:T1{tp = ve2:Collection{a,b++c}} => a = ve2->at(1); + */ + for (int i = 0; i < size; i++) { + IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1); + OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex); + OCLExpression rMember = rMembers.get(i); + Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); + addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement); + } + } + else { + /** + * The assignment for an unordered CollectionTemplateExp rest variable is a cumulative exclusion. + * + * ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->excluding(a)->excluding(b); + */ + OCLExpression exclusions = createVariableExp(mvcte); + for (@NonNull OCLExpression rMember : rMembers) { + Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); + exclusions = createOperationCallExp(exclusions, "excluding", createVariableExp(mVariable)); + } + VariableAssignment aRest = createVariableAssignment(mRest, exclusions); + cMiddleBottomPattern.getAssignment().add(aRest); + /** + * The predicates for each unordered CollectionTemplateExp member variable is an excluded inclusion test. + * + * ve1:T1{tp = ve2:Collection{a,b++c}} => ve2->excluding(a)->includes(b); + */ + for (int i = 0; i < size; i++) { + @NonNull OCLExpression eTerm = createVariableExp(mvcte); + for (int j = 0; j < i; j++) { + OCLExpression rMember = rMembers.get(j); + Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); + eTerm = createOperationCallExp(eTerm, "excluding", createVariableExp(mVariable)); + } + OCLExpression rMember = rMembers.get(i); + Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); + eTerm = createOperationCallExp(eTerm, "includes", createVariableExp(mVariable)); + addPredicate(cMiddleBottomPattern, eTerm); + } + } + } + } + + // loop body of RDomainPatternToMDBottomPatternComposite + private void mapOtherObjectTemplateExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull ObjectTemplateExp pte) throws CompilerChainException { + /** + * Each PropertyTemplateItem whose value is an ObjectTemplateExp + * converts to a PropertyAssignment. + * + * ve1:T1{tp = ve2:T2{...}} => ve1.tp := ve2; + */ + Variable vpte = ClassUtil.nonNullState(pte.getBindsTo()); + Variable mvpte = variablesAnalysis.getCoreVariable(vpte); + mapOtherTemplateExpression(pte); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, createVariableExp(mvpte)); + } + + // loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr + private void mapOtherSimpleNonVariableExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull OCLExpression ptv) { + /** + * Each PropertyTemplateItem whose value is not a TemplateExp and not a VariableExp + * converts to a PropertyAssignment. + * + * ve1:T{tp = me} => ve1.tp := me; + */ + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, mapExpression(ptv)); } - public abstract void mapOtherDomainToDomainVariablesAndPatterns() throws CompilerChainException; + // body of RDomainPatternToMDBottomPatternSimpleSharedVarExpr and RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr + private void mapOtherSimpleVariableExpression(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull VariableExp e) { + /** + * Each PropertyTemplateItem whose value is a simple VariableExp + * converts to a domain(unshared) / middle(shared) PropertyAssignment. + * + * ve1:T{tp = ve2} => ve1.tp := ve2; + */ + Variable rVariable/*vpte*/ = ClassUtil.nonNullState((Variable) e.getReferredVariable()); + Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable); + BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern; + qvtr2qvtc.addNavigationAssignment(cBottomPattern, cTemplateVariable, traceProperty, createVariableExp(cVariable)); + } + + // RDomainPatternToMDBottomPattern + protected void mapOtherTemplateExpression(@NonNull TemplateExp rTemplateExpression) throws CompilerChainException { + Variable rTemplateVariable = ClassUtil.nonNullState(rTemplateExpression.getBindsTo()); + if (rTemplateExpression instanceof ObjectTemplateExp) { + for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(((ObjectTemplateExp)rTemplateExpression).getPart())) { + Property rProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty()); + Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable); + Property traceProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rProperty); + OCLExpression propertyTemplateValue = ClassUtil.nonNullState(propertyTemplateItem.getValue()); + if (propertyTemplateValue instanceof VariableExp) { + mapOtherSimpleVariableExpression(cTemplateVariable, traceProperty, (VariableExp)propertyTemplateValue); + } + else if (propertyTemplateValue instanceof CollectionTemplateExp) { + mapOtherCollectionTemplateExpression(cTemplateVariable, traceProperty, (CollectionTemplateExp)propertyTemplateValue); + } + else if (propertyTemplateValue instanceof ObjectTemplateExp) { + mapOtherObjectTemplateExpression(cTemplateVariable, traceProperty, (ObjectTemplateExp)propertyTemplateValue); + } + else { + mapOtherSimpleNonVariableExpression(cTemplateVariable, traceProperty, propertyTemplateValue); + } + } + } + else { + + } + OCLExpression rGuardPredicate = rTemplateExpression.getWhere(); + if (rGuardPredicate != null) { + cMiddleBottomPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate))); + } + } + + public void synthesize() throws CompilerChainException { + List<@NonNull TemplateExp> rOtherTemplateExpressions = getTemplateExpressions(rOtherDomain); + for (@NonNull TemplateExp rOtherTemplateExpression : rOtherTemplateExpressions) { + mapOtherTemplateExpression(rOtherTemplateExpression); + } + } } /** @@ -100,11 +322,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; */ @SuppressWarnings("serial") protected class ExpressionCopier extends EcoreUtil.Copier - { + { // FIXME enforce unique names on let-variables, iterators @Override public EObject get(Object oIn) { if (oIn instanceof Element) { - List<Element> oOuts = source2targets.get(oIn); + List<@NonNull Element> oOuts = source2targets.get(oIn); if (oOuts != null) { assert oOuts.size() == 1; return oOuts.get(0); @@ -118,15 +340,13 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; protected final @NonNull RelationDomain rEnforcedDomain; // rd: This source enforced domain protected final @NonNull TypedModel rEnforcedTypedModel; // rEnforcedDomain.getTypedModel() protected final @NonNull String rEnforcedDomainName; // rEnforcedDomain.getName() - protected final @NonNull List<@NonNull Variable> rEnforcedDomainVariables; // All variables defined or referenced in this domain -// @Deprecated -// protected final @NonNull /*Object*/TemplateExp rEnforcedTemplateExpression; // te: The template expression defining the enforced domain pattern + protected final @NonNull Set<@NonNull Variable> rEnforcedBoundVariables; // All variables defined in this domain + protected final @NonNull Set<@NonNull Variable> rEnforcedReferredVariables; // All variables defined or referenced in this domain protected final @NonNull List<@NonNull/*Object*/TemplateExp> rEnforcedTemplateExpressions; // te: The template expression defining the enforced domain pattern -// @Deprecated -// protected final @NonNull Variable rEnforcedRootVariable; // tev: The template expression variable (the root variable of the enforced domain pattern) protected final @NonNull List<@NonNull Variable> rEnforcedRootVariables; // tev: The template expression variable (the root variable of the enforced domain pattern) protected final @NonNull List<@NonNull AbstractOtherRelationDomain2CoreDomain> otherDomain2coreDomains; // All other domains sharing the parent of this domain - protected final @NonNull Set<@NonNull Variable> rOtherDomainVariables; // All variables defined or referenced in other domains + protected final @NonNull Set<@NonNull Variable> rAllOtherBoundVariables; // All variables defined in other domains + protected final @NonNull Set<@NonNull Variable> rAllOtherReferredVariables; // All variables defined or referenced in other domains // Core protected final @NonNull Mapping cMapping; // m: The resultant mapping protected final @NonNull GuardPattern cMiddleGuardPattern; // mg: The resultant mapping guard pattern @@ -135,41 +355,10 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; protected final @NonNull CoreDomain cEnforcedDomain; // md: The resultant enforced domain protected final @NonNull GuardPattern cEnforcedGuardPattern; // dg: The resultant enforced domain guard pattern protected final @NonNull BottomPattern cEnforcedBottomPattern; // db: The resultant enforced domain bottom pattern - protected final @NonNull RealizedVariable cMiddleRealizedVariable; // tcv: The trace class variable (the middle variable identifying the middle object) - - /** - * The lazily created named RealizedVariables in each CorePattern. - */ - private @NonNull Map<@NonNull CorePattern, @NonNull Map<@NonNull String, @NonNull RealizedVariable>> pattern2name2realizedVariable - = new HashMap<@NonNull CorePattern, @NonNull Map<@NonNull String, @NonNull RealizedVariable>>(); - - /** - * The lazily created named RealizedVariables in each CorePattern. - */ - private @NonNull Map<@NonNull CorePattern, @NonNull Map<@NonNull String, @NonNull Variable>> pattern2name2variable - = new HashMap<@NonNull CorePattern, @NonNull Map<@NonNull String, @NonNull Variable>>(); - - /** - * The lazily created RealizedVariables per Relation Variable in each CorePattern. - */ - private @NonNull Map<@NonNull CorePattern, @NonNull Map<@NonNull Variable, @NonNull RealizedVariable>> pattern2variable2realizedVariable - = new HashMap<@NonNull CorePattern, @NonNull Map<@NonNull Variable, @NonNull RealizedVariable>>(); - /** - * The lazily created Core Variable for each Relation Variable in each CorePattern. - */ - private @NonNull Map<@NonNull CorePattern, @NonNull Map<@NonNull Variable, @NonNull Variable>> pattern2variable2variable - = new HashMap<@NonNull CorePattern, @NonNull Map<@NonNull Variable, @NonNull Variable>>(); + protected final @NonNull VariablesAnalysis variablesAnalysis; - /** - * The core Variable for each relation Variable in a chosen mapping. - */ - private final @NonNull Map<@NonNull Variable, @NonNull Variable> rVariable2cVariable = new HashMap<@NonNull Variable, @NonNull Variable>(); - - /** - * The names allocated in each relation. - */ - private final @NonNull Map<@NonNull String, @NonNull Element> name2element = new HashMap<@NonNull String, @NonNull Element>(); + protected final @NonNull RealizedVariable cMiddleRealizedVariable; // tcv: The trace class variable (the middle variable identifying the middle object) private final @NonNull Map<@NonNull Element, @NonNull List<@NonNull Element>> source2targets = new HashMap<@NonNull Element, @NonNull List<@NonNull Element>>(); private final @NonNull Map<@NonNull Element, @NonNull Element> target2source = new HashMap<@NonNull Element, @NonNull Element>(); @@ -177,168 +366,64 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; public AbstractEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) { this.rEnforcedDomain = rEnforcedDomain; // -// @NonNull DomainPattern rEnforcedDomainPattern = qvtr2qvtc.getDomainPattern(rEnforcedDomain); - this.rEnforcedDomainVariables = getDomainVariables(rEnforcedDomain); + this.rEnforcedBoundVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherBoundVariables(rEnforcedBoundVariables, rEnforcedDomain); + this.rEnforcedReferredVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherReferredVariables(rEnforcedReferredVariables, rEnforcedDomain); this.rEnforcedTemplateExpressions = getTemplateExpressions(rEnforcedDomain); this.rEnforcedRootVariables = getRootVariables(rEnforcedDomain); -// this.rEnforcedTemplateExpression = /*(ObjectTemplateExp)*/ ClassUtil.nonNullState(rEnforcedDomainPattern.getTemplateExpression()); -// this.rEnforcedRootVariable = ClassUtil.nonNullState(rEnforcedTemplateExpression.getBindsTo()); this.rEnforcedTypedModel = ClassUtil.nonNullState(rEnforcedDomain.getTypedModel()); - @NonNull String rRelationName = ClassUtil.nonNullState(rRelation.getName()); this.rEnforcedDomainName = ClassUtil.nonNullState(rEnforcedDomain.getName()); @NonNull Type traceClass = qvtr2qvtc.getTraceClass(rRelation); // this.cEnforcedTypedModel = getCoreTypedModel(rEnforcedTypedModel); - this.cMapping = qvtr2qvtc.whenMapping(rRelation, cMappingName); + this.cMapping = qvtr2qvtc.createMapping(rRelation, cMappingName); this.cMiddleGuardPattern = ClassUtil.nonNullState(cMapping.getGuardPattern()); this.cMiddleBottomPattern = ClassUtil.nonNullState(cMapping.getBottomPattern()); - this.cEnforcedDomain = qvtr2qvtc.whenCoreDomain(cMapping, rEnforcedDomainName); + this.cEnforcedDomain = createCoreDomain(cEnforcedTypedModel, true); this.cEnforcedGuardPattern = ClassUtil.nonNullState(cEnforcedDomain.getGuardPattern()); this.cEnforcedBottomPattern = ClassUtil.nonNullState(cEnforcedDomain.getBottomPattern()); - this.cMiddleRealizedVariable = whenRealizedVariable(cMiddleBottomPattern, rRelationName+"_"+rEnforcedDomainName+"_v", traceClass); // 42 + // + this.variablesAnalysis = new VariablesAnalysis(qvtr2qvtc, cEnforcedDomain); + // + String middleRealizedVariableName = variablesAnalysis.getUniqueVariableName("trace", this); + this.cMiddleRealizedVariable = qvtr2qvtc.helper.createRealizedVariable(middleRealizedVariableName, traceClass); + cMiddleBottomPattern.getRealizedVariable().add(cMiddleRealizedVariable); +// putTrace(cMiddleRealizedVariable, cMiddleBottomPattern); // this.otherDomain2coreDomains = new ArrayList<@NonNull AbstractOtherRelationDomain2CoreDomain>(); - this.rOtherDomainVariables = new HashSet<@NonNull Variable>(); + this.rAllOtherBoundVariables = new HashSet<@NonNull Variable>(); for (@NonNull Domain rDomain : ClassUtil.nullFree(rEnforcedDomain.getRule().getDomain())) { if ((rDomain != rEnforcedDomain) && (rDomain instanceof RelationDomain)) { RelationDomain rRelationDomain = (RelationDomain)rDomain; otherDomain2coreDomains.add(createOtherDomain2CoreDomain(rRelationDomain)); - rOtherDomainVariables.addAll(getDomainVariables(rRelationDomain)); } } - } - - // 2 - /*public void doDomainVarsSharedWithWhenToDgVars(@NonNull Set<Variable> domainVarsSharedWithWhen, @NonNull GuardPattern dg) { - - List<Variable> dbVars = doRVarSetToMVarSet(new ArrayList<Variable>(domainVarsSharedWithWhen)); - dg.getBindsTo().addAll(dbVars); - }*/ - - // new - private void addCollectionTemplateExpressionToMiddleBottom(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull CollectionTemplateExp cte) throws CompilerChainException { - /** - * Each PropertyTemplateItem whose value is a CollectionTemplateExp - * converts to a VariableAssignment and Predicates. - * - * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; - */ - Variable vcte = ClassUtil.nonNullState(cte.getBindsTo()); - Variable mvcte = getCoreVariable(vcte); - NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), traceProperty); - VariableAssignment a = createVariableAssignment(mvcte, pce); - cMiddleBottomPattern.getAssignment().add(a); - /** - * Each CollectionTemplateExp member that is not a variable - * converts to a VariableAssignment of a new variable the member expression. - * - * ve1:T1{tp = ve2:Collection{a++b}} => a := a; - */ - Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<@NonNull OCLExpression, @NonNull Variable>(); - List<@NonNull OCLExpression> rMembers = ClassUtil.nullFree(cte.getMember()); - for (@NonNull OCLExpression rMember : rMembers) { - Variable mVariable; - if (rMember instanceof TemplateExp) { - TemplateExp rTemplateExp = (TemplateExp)rMember; - addTemplateExpressionToMiddleBottom(rTemplateExp); - Variable rVariable = ClassUtil.nonNullState(rTemplateExp.getBindsTo()); - mVariable = getCoreVariable(rVariable); - } - else if (rMember instanceof VariableExp) { - Variable rVariable = ClassUtil.nonNullState((Variable)((VariableExp)rMember).getReferredVariable()); - mVariable = getCoreVariable(rVariable); - } - else { - OCLExpression mMember = mapExpression(rMember); - mVariable = createVariable(getSafeName(mMember, "member"), mMember); - } - rMember2mVariable.put(rMember, mVariable); + Set<@NonNull Variable> rUnsharedEnforcedDomainVariables = new HashSet<@NonNull Variable>(rEnforcedReferredVariables); + rUnsharedEnforcedDomainVariables.removeAll(rSharedVariables); + this.rAllOtherReferredVariables = new HashSet<@NonNull Variable>(rAllDomainVariables); + rAllOtherReferredVariables.removeAll(rUnsharedEnforcedDomainVariables); + // + for (@NonNull Variable rVariable : rWhenVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsWhen(); } -// CollectionTemplateExp cte = (CollectionTemplateExp) ptv; -// Variable vcte = ClassUtil.nonNullState(cte.getBindsTo()); -// Variable mvcte = doRVarToMVar(vcte); -// PropertyCallExp pce = createPropertyCallExp(ve1, tp); -// VariableAssignment a = createVariableAssignment(mvcte, pce); -// mb.getAssignment().add(a); - - - CollectionType collectionType = ClassUtil.nonNullState(cte.getReferredCollectionType()); - int size = rMembers.size(); - Variable rRest = cte.getRest(); - if (rRest == null) { - /** - * The predicate for a CollectionTemplateExp without a rest variable is a total comparison. - * - * ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp; ve2 = Collection{a,b}; - */ - List<@NonNull CollectionLiteralPart> mParts = new ArrayList<@NonNull CollectionLiteralPart>(); - for (@NonNull OCLExpression rMember : rMembers) { - Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); - CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable)); - mParts.add(mItem); - } - CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts); - addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle); + for (@NonNull Variable rVariable : rWhereVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsWhere(); } - else { - Variable mRest = getCoreVariable(rRest); - if (collectionType.isOrdered()) { - /** - * The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment. - * - * ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->subCollection(3,ve2->size()); - */ - VariableExp vRest = createVariableExp(rRest); - String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence"; - IntegerLiteralExp eStart = createIntegerLiteralExp(size); - OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size"); - OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, vRest, eStart, eFinish); - VariableAssignment aRest = createVariableAssignment(mRest, eTail); - cMiddleBottomPattern.getAssignment().add(aRest); - /** - * The predicates for each ordered CollectionTemplateExp member variable is an element comparison. - * - * ve1:T1{tp = ve2:Collection{a,b++c}} => a = ve2->at(1); - */ - for (int i = 0; i < size; i++) { - IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1); - OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex); - OCLExpression rMember = rMembers.get(i); - Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); - addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement); - } - } - else { - /** - * The assignment for an unordered CollectionTemplateExp rest variable is a cumulative exclusion. - * - * ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->excluding(a)->excluding(b); - */ - OCLExpression exclusions = createVariableExp(mvcte); - for (@NonNull OCLExpression rMember : rMembers) { - Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); - exclusions = createOperationCallExp(exclusions, "excluding", createVariableExp(mVariable)); - } - VariableAssignment aRest = createVariableAssignment(mRest, exclusions); - cMiddleBottomPattern.getAssignment().add(aRest); - /** - * The predicates for each unordered CollectionTemplateExp member variable is an excluded inclusion test. - * - * ve1:T1{tp = ve2:Collection{a,b++c}} => ve2->excluding(a)->includes(b); - */ - for (int i = 0; i < size; i++) { - @NonNull OCLExpression eTerm = createVariableExp(mvcte); - for (int j = 0; j < i; j++) { - OCLExpression rMember = rMembers.get(j); - Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); - eTerm = createOperationCallExp(eTerm, "excluding", createVariableExp(mVariable)); - } - OCLExpression rMember = rMembers.get(i); - Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember)); - eTerm = createOperationCallExp(eTerm, "includes", createVariableExp(mVariable)); - addPredicate(cMiddleBottomPattern, eTerm); - } - } + for (@NonNull Variable rVariable : rEnforcedBoundVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedBound(); + } + for (@NonNull Variable rVariable : rEnforcedReferredVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedReferred(); + } + for (@NonNull Variable rVariable : rEnforcedRootVariables) { + variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot(); + } + // + for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) { + Variable rVariable = analysis.getRelationVariable(); + Variable cVariable = analysis.synthesize(); + putTrace(cVariable, rVariable); } } @@ -350,47 +435,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; addPredicate(cCorePattern, eTerm); } - // loop body of RDomainPatternToMDBottomPatternComposite - private void addObjectTemplateExpressionToMiddleBottom(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull ObjectTemplateExp pte) throws CompilerChainException { - /** - * Each PropertyTemplateItem whose value is an ObjectTemplateExp - * converts to a PropertyAssignment. - * - * ve1:T1{tp = ve2:T2{...}} => ve1.tp := ve2; - */ - Variable vpte = ClassUtil.nonNullState(pte.getBindsTo()); - Variable mvpte = getCoreVariable(vpte); - addTemplateExpressionToMiddleBottom(pte); - addPropertyAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, createVariableExp(mvpte)); - } - protected void addPredicate(@NonNull CorePattern cCorePattern, @NonNull OCLExpression cExpression) { QVTrToQVTc.SYNTHESIS.println("addPredicate " + cExpression); Predicate cPredicate = createPredicate(cExpression); cCorePattern.getPredicate().add(cPredicate); } - - /** - * Add the PropertyAssignment "cVariable.cProperty := cExpression" to the cBottomPattern. - */ - private void addPropertyAssignment(@NonNull BottomPattern cBottomPattern, @NonNull Variable cVariable, @NonNull Property cProperty, @NonNull OCLExpression cExpression) { - if (!cProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) { - VariableExp cSlotVariableExp = createVariableExp(cVariable); - NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cProperty, cExpression); - System.out.println("addPropertyAssignment " + cAssignment); - cBottomPattern.getAssignment().add(cAssignment); - return; - } - Property cOppositeProperty = cProperty.getOpposite(); - if ((cOppositeProperty != null) && (cExpression instanceof VariableExp) && (!cOppositeProperty.isIsMany() || (cVariable.getType() instanceof CollectionType))) { - VariableExp cSlotVariableExp = (VariableExp)cExpression; - NavigationAssignment cAssignment = createNavigationAssignment(cSlotVariableExp, cOppositeProperty, createVariableExp(cVariable)); - System.out.println("addPropertyAssignment " + cAssignment); - cBottomPattern.getAssignment().add(cAssignment); - return; - } - throw new IllegalStateException("Unsupported collection assign " + cVariable + "." + cProperty + ":=" + cExpression); - } // Quad call of RDomainPatternExprToMappingXXXX private void addPropertyAssignmentToMiddleBottomPattern(@NonNull Variable rTargetVariable, @NonNull Property rTargetProperty, @NonNull OCLExpression rExpression) throws CompilerChainException { @@ -400,128 +449,47 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; // body of RDomainPatternExprToMappingDomainTemplateVarAssignment Variable rBoundVariable = ClassUtil.nonNullState(((ObjectTemplateExp)rExpression).getBindsTo()); if (!rSharedVariables.contains(rBoundVariable)) { - Variable cBoundVariable = getCoreVariable(rBoundVariable); // FIXME whenVariable(cMiddleBottomPattern, rBoundVariable); - cTargetVariable = getCoreVariable(rTargetVariable); //getCoreRealizedVariable(rTargetVariable); + Variable cBoundVariable = variablesAnalysis.getCoreVariable(rBoundVariable); // FIXME whenVariable(cMiddleBottomPattern, rBoundVariable); + cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable); //getCoreRealizedVariable(rTargetVariable); cExpression = createVariableExp(cBoundVariable); } } else if (rExpression instanceof VariableExp) { + cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable); // getCoreVariable should do and be uniform Variable rReferredVariable = ClassUtil.nonNullState((Variable) ((VariableExp)rExpression).getReferredVariable()); - Variable cReferredVariable = getCoreVariable(rReferredVariable); + Variable cReferredVariable = variablesAnalysis.getCoreVariable(rReferredVariable); if (rSharedVariables.contains(rReferredVariable) ) { // body of RDomainPatternExprToMappingBottomVarAssignment - cTargetVariable = getCoreRealizedVariable(rTargetVariable); } else { // body of RDomainPatternExprToMappingDomainVarAssignment - cTargetVariable = getCoreRealizedVariable(rTargetVariable); - cEnforcedBottomPattern.getRealizedVariable().add((RealizedVariable)cTargetVariable); + if (!cEnforcedBottomPattern.getRealizedVariable().contains(cTargetVariable)) { + // FIXME variables should have been plotted earlier + cEnforcedBottomPattern.getRealizedVariable().add((RealizedVariable)cTargetVariable); + } } cExpression = createVariableExp(cReferredVariable); } else { // body of RDomainPatternExprToMappingDomainAssignment - cTargetVariable = getCoreVariable(rTargetVariable); + cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable); cExpression = mapExpression(rExpression); } if ((cTargetVariable != null) && (cExpression != null)) { - Property cTargetProperty = getProperty(cTargetVariable.getType(), rTargetProperty); - addPropertyAssignment(cEnforcedBottomPattern, cTargetVariable, cTargetProperty, cExpression); - } - } - - // body of RDomainPatternToMDBottomPatternSimpleSharedVarExpr and RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr - private void addSimpleVariableExpressionToMiddleBottom(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull VariableExp e) { - /** - * Each PropertyTemplateItem whose value is a simple VariableExp - * converts to a domain(unshared) / middle(shared) PropertyAssignment. - * - * ve1:T{tp = ve2} => ve1.tp := ve2; - */ - Variable rVariable/*vpte*/ = ClassUtil.nonNullState((Variable) e.getReferredVariable()); - Variable cVariable/*mvpte*/ = getCoreVariable(rVariable); - BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern; - addPropertyAssignment(cBottomPattern, cTemplateVariable, traceProperty, createVariableExp(cVariable)); - } - - // // RDomainPatternToMDBottomPattern - protected void addTemplateExpressionToMiddleBottom(@NonNull TemplateExp rTemplateExpression) throws CompilerChainException { - Variable rTemplateVariable = ClassUtil.nonNullState(rTemplateExpression.getBindsTo()); - if (rTemplateExpression instanceof ObjectTemplateExp) { - for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(((ObjectTemplateExp)rTemplateExpression).getPart())) { - Property rProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty()); - Variable cTemplateVariable = getCoreVariable(rTemplateVariable); - Property traceProperty = getProperty(cTemplateVariable.getType(), rProperty); - OCLExpression propertyTemplateValue = ClassUtil.nonNullState(propertyTemplateItem.getValue()); - if (propertyTemplateValue instanceof VariableExp) { - addSimpleVariableExpressionToMiddleBottom(cTemplateVariable, traceProperty, (VariableExp)propertyTemplateValue); - } - else if (propertyTemplateValue instanceof CollectionTemplateExp) { - addCollectionTemplateExpressionToMiddleBottom(cTemplateVariable, traceProperty, (CollectionTemplateExp)propertyTemplateValue); - } - else if (propertyTemplateValue instanceof ObjectTemplateExp) { - addObjectTemplateExpressionToMiddleBottom(cTemplateVariable, traceProperty, (ObjectTemplateExp)propertyTemplateValue); - } - else { - addSimpleNonVariableExpressionToMiddleBottom(cTemplateVariable, traceProperty, propertyTemplateValue); - } - } - } - else { - - } - OCLExpression rGuardPredicate = rTemplateExpression.getWhere(); - if (rGuardPredicate != null) { - cMiddleBottomPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate))); + Property cTargetProperty = qvtr2qvtc.getProperty(cTargetVariable.getType(), rTargetProperty); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTargetVariable, cTargetProperty, cExpression); } } - // loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr - private void addSimpleNonVariableExpressionToMiddleBottom(@NonNull Variable cTemplateVariable, @NonNull Property traceProperty, @NonNull OCLExpression ptv) { - /** - * Each PropertyTemplateItem whose value is not a TemplateExp and not a VariableExp - * converts to a PropertyAssignment. - * - * ve1:T{tp = me} => ve1.tp := me; - */ - addPropertyAssignment(cMiddleBottomPattern, cTemplateVariable, traceProperty, mapExpression(ptv)); + private @NonNull CoreDomain createCoreDomain(@NonNull TypedModel cTypedModel, boolean isEnforced) { + CoreDomain coreDomain = qvtr2qvtc.createCoreDomain(cTypedModel); + coreDomain.setIsEnforceable(isEnforced); + coreDomain.setRule(cMapping); + return coreDomain; } protected abstract @NonNull AbstractOtherRelationDomain2CoreDomain createOtherDomain2CoreDomain(@NonNull RelationDomain rRelationDomain); - // 50 - /* - private void doUnsharedWhenVarsToMgVars(@NonNull Set<Variable> unsharedWhenVars, - @NonNull GuardPattern mg) { - - List<Variable> mgVars = doRVarSetToMVarSet(new ArrayList<Variable>(unsharedWhenVars)); - mg.getBindsTo().addAll(mgVars); - } - */ - - - /* ============= T5 ============= */ - - // 35 - /*public @NonNull List<Variable> doRVarSetToMVarSet(@NonNull ArrayList<Variable> rvSeq) { - - List<Variable> mvSet = new ArrayList<Variable>(); - if (!rvSeq.isEmpty()) { - final Variable rv = rvSeq.remove(0); - assert rv != null; - Variable mv = doRVarToMVar(rv); - mvSet.add(mv); - mvSet.addAll(doRVarSetToMVarSet(rvSeq)); - } - return mvSet; - }*/ - - - private @NonNull RealizedVariable getCoreRealizedVariable(@NonNull Variable rv) { - @NonNull /*Realized*/Variable mv = /*(RealizedVariable)*/ getCoreVariable(rv); - return (@NonNull RealizedVariable) mv; - } - protected @NonNull TypedModel getCoreTypedModel(@NonNull TypedModel rTypedModel) { String name = ClassUtil.nonNullState(rTypedModel.getName()); List<org.eclipse.ocl.pivot.@NonNull Package> usedPackages = ClassUtil.nullFree(rTypedModel.getUsedPackage()); @@ -533,17 +501,18 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; } return ClassUtil.nonNullState(null); } - - protected @NonNull Variable getCoreVariable(@NonNull Variable rVariable) { // doRVarToMVar - return ClassUtil.nonNullState(rVariable2cVariable.get(rVariable)); - } - protected @NonNull List<@NonNull Variable> getDomainVariables(@NonNull RelationDomain rRelationDomain) { - List<@NonNull Variable> rDomainVariables = new ArrayList<@NonNull Variable>(); - for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(rRelationDomain.getPattern())) { - rDomainVariables.addAll(ClassUtil.nullFree(rDomainPattern.getBindsTo())); + protected abstract @NonNull Set<@NonNull Variable> getEnforcedBottomDomainVariables(); + +// protected abstract @NonNull Set<@NonNull Variable> getEnforcedDomainGuardVariables(@NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables); + + protected @NonNull Set<@NonNull RelationDomain> getOtherRelationDomains() { + Set<@NonNull RelationDomain> relationDomains = new HashSet<@NonNull RelationDomain>(); + for (@NonNull Domain relationDomain : ClassUtil.nullFree(rRelation.getDomain())) { + relationDomains.add((RelationDomain) relationDomain); } - return rDomainVariables; + relationDomains.remove(rEnforcedDomain); + return relationDomains; } protected @NonNull List<@NonNull Variable> getRootVariables(@NonNull RelationDomain rRelationDomain) { @@ -557,34 +526,6 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; return rRootVariables; } - protected @NonNull Set<@NonNull RelationDomain> getOtherRelationDomains() { - Set<@NonNull RelationDomain> relationDomains = new HashSet<@NonNull RelationDomain>(); - for (@NonNull Domain relationDomain : ClassUtil.nullFree(rRelation.getDomain())) { - relationDomains.add((RelationDomain) relationDomain); - } - relationDomains.remove(rEnforcedDomain); - return relationDomains; - } - - public @NonNull String getSafeName(@NonNull Element newElement, @NonNull String name) { - Element oldElement = name2element.get(name); - if (oldElement == newElement) { - return name; - } - if (oldElement == null) { - name2element.put(name, newElement); - return name; - } - for (int i = 1; true; i++) { - String newName = name + "_" + i; - oldElement = name2element.get(newName); - if (oldElement == null) { - name2element.put(newName, newElement); - return newName; - } - } - } - protected @NonNull List<@NonNull TemplateExp> getTemplateExpressions(@NonNull RelationDomain rRelationDomain) { List<@NonNull TemplateExp> rTemplateExpressions = new ArrayList<@NonNull TemplateExp>(); for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(rRelationDomain.getPattern())) { @@ -611,139 +552,91 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; return exists; } } - - // ROppositeDomainVarsToTraceClassProps - protected void mapDomainVariablesToMiddleVariableAssignments(@NonNull Set<@NonNull Variable> rDomainVariables) throws CompilerChainException { - for (@NonNull Variable rDomainVariable : rDomainVariables) { - TemplateExp rTemplateExpression = qvtr2qvtc.getTemplateExpression(rDomainVariable); -// if (dvte instanceof ObjectTemplateExp) { - // tp=dv:T{...} => tcv.tp := dv; - Property cProperty = basicGetProperty(cMiddleRealizedVariable.getType(), rDomainVariable); - if (cProperty != null) { // null for dead variables - Variable cVariable = getCoreVariable(rDomainVariable); - addPropertyAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cProperty, createVariableExp(cVariable)); - } -// } -/* else if (dvte instanceof CollectionTemplateExp) { - // tp=dv:T{...} => tcv.tp := dv; - Variable mdv = doRVarToMVar(dv); -// VariableExp ve1 = createVariableExp(tcv); - VariableExp ve2 = createVariableExp(mdv); - VariableAssignment a = createVariableAssignment(mdv, ve2); - mb.getAssignment().add(a); - } */ -/* else if (dvte instanceof CollectionTemplateExp) { - CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)dvte; - } */ - } + + protected void mapEnforcedCollectionTemplateExpression(@NonNull CollectionTemplateExp rEnforcedCollectionTemplateExp, @Nullable Key key) throws CompilerChainException { + // throw new CompilerChainException("Missing doInvokedRelationToMappingForEnforcement support for CollectionTemplateExp"); + System.err.println("Missing mapEnforcedCollectionTemplateExpression support"); } - // RDomainToMDBottomForEnforcement - protected void mapEnforcedDomain(@NonNull Set<@NonNull Predicate> predicatesWithoutVarBindings, @NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) throws CompilerChainException - { - Set<@NonNull Variable> nonRootEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedBottomDomainVariables); - nonRootEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables); - // - Set<@NonNull Predicate> predicatesWithVarBindings = selectPredicatesThatReferToVariables(predicatesWithoutVarBindings, nonRootEnforcedBottomDomainVariables); - Set<@NonNull Predicate> remainingPredicatesWithoutVarBindings = new HashSet<@NonNull Predicate>(predicatesWithoutVarBindings); - remainingPredicatesWithoutVarBindings.removeAll(predicatesWithVarBindings); + // RDomainToMDBottomForEnforcement (second half) + protected void mapEnforcedDomainPatterns() throws CompilerChainException { for (@NonNull TemplateExp rEnforcedTemplateExpression/*te*/ : rEnforcedTemplateExpressions) { - mapEnforcedDomain(rEnforcedTemplateExpression); + mapEnforcedTemplateExpression(rEnforcedTemplateExpression); } } - - // RDomainToMDBottomForEnforcement - private void mapEnforcedDomain(@NonNull TemplateExp rEnforcedTemplateExpression/*te*/) throws CompilerChainException - { -// for (@NonNull TemplateExp rEnforcedTemplateExpression/*te*/ : rEnforcedTemplateExpressions) { - Variable rTemplateVariable/*v*/ = ClassUtil.nonNullState(rEnforcedTemplateExpression.getBindsTo()); - Type rTemplateVariableType/*c*/ = ClassUtil.nonNullState(rTemplateVariable.getType()); - Key key = qvtr2qvtc.getKeyforType(rTemplateVariableType); -// if (key == null){ -// // Nothing to do -// } - /*else*/ if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) { - for (@NonNull PropertyTemplateItem pt : ClassUtil.nullFree(((ObjectTemplateExp)rEnforcedTemplateExpression).getPart())) { - Property rPartProperty = ClassUtil.nonNullState(pt.getReferredProperty()); - OCLExpression rPartValue/*pte*/ = ClassUtil.nonNullState(pt.getValue()); - if ((key != null) && key.getPart().contains(rPartProperty)) { - // body of RDomainToMDBottomForEnforcementOfIdentityProp - addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, rPartProperty, rPartValue); - } - else if (rPartValue instanceof TemplateExp) { - // body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject - TemplateExp pte = (TemplateExp)rPartValue; - Variable pv = pte.getBindsTo(); - Mapping composedMapping = cMapping; //qvtr2qvtc.createMapping(); //whenMapping(rRelation, cMapping.getName()+"_for_"+pv.name); -// GuardPattern composedMappingGuardPattern = ClassUtil.nonNullState(composedMapping.getGuardPattern()); - CoreDomain composedEnforcedDomain = cEnforcedDomain;//qvtr2qvtc.whenCoreDomain(composedMapping, rEnforcedDomainName); -// composedEnforcedDomain.setIsEnforceable(true); -// composedEnforcedDomain.setTypedModel(cEnforcedTypedModel); -// GuardPattern composedEnforcedGuardPattern = composedEnforcedDomain.getGuardPattern(); - BottomPattern composedEnforcedBottomPattern = cEnforcedBottomPattern;//ClassUtil.nonNullState(composedEnforcedDomain.getBottomPattern()); - - -// /*Realized*/Variable cTargetVariable/*mpv*/ = mapRealizedVariable(pv); - /*Realized*/Variable cTargetVariable/*mpv*/ = rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(composedEnforcedBottomPattern, pv); - Variable cTemplateVariable/*mv*/ = getCoreVariable(rTemplateVariable); - Property cTargetProperty = getProperty(cTemplateVariable.getType(), rPartProperty); - addPropertyAssignment(composedEnforcedBottomPattern, cTemplateVariable, cTargetProperty, createVariableExp(cTargetVariable)); -// FIXME mapEnforcedDomain(pte); -// cMapping.getLocal().add(composedMapping); - Property cTargetProperty2 = getProperty(cMiddleRealizedVariable.getType(), cTargetVariable); - addPropertyAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable)); - } - else { - // body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive - Mapping composedMapping = cMapping; //qvtr2qvtc.createMapping(); //whenMapping(rRelation, cMapping.getName()+"_forNonIdentityProp"); - BottomPattern composedBottomPattern = cMiddleBottomPattern; //BClassUtil.nonNullState(composedMapping.getBottomPattern()); -// composedMapping.getGuardPattern(); - GuardPattern composedMappingGuardPattern = ClassUtil.nonNullState(composedMapping.getGuardPattern()); - CoreDomain composedEnforcedDomain = cEnforcedDomain;//qvtr2qvtc.whenCoreDomain(composedMapping, rEnforcedDomainName); - GuardPattern composedEnforcedGuardPattern = cEnforcedGuardPattern;//composedEnforcedDomain.getGuardPattern(); - // where - @SuppressWarnings("unused")BottomPattern composedMappingBottomPattern = cMiddleBottomPattern;//ClassUtil.nonNullState(composedMapping.getBottomPattern()); - Variable cTemplateVariable = getCoreVariable(rTemplateVariable); - //RDomainToMComposedMappingGuardrEnforcedDomain - for (@NonNull TemplateExp rTemplateExpression : rEnforcedTemplateExpressions) { - if ((rPartValue instanceof VariableExp) && (rTemplateExpression instanceof ObjectTemplateExp)) { - // check - Variable rReferredVariable = (Variable) ClassUtil.nonNullState(((VariableExp) rPartValue).getReferredVariable()); - if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedTemplateExpression, rReferredVariable)) { - Variable cReferredVariable = getCoreVariable(rReferredVariable); - // assign - Property cTargetProperty = getProperty(cReferredVariable.getType(), cReferredVariable); - NavigationCallExp cPropertyCallExp = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), cTargetProperty); - addConditionPredicate(composedMappingGuardPattern, cPropertyCallExp, createVariableExp(cReferredVariable)); -// composedEnforcedDomain.setTypedModel(cEnforcedTypedModel); - composedEnforcedGuardPattern.getBindsTo().add(cReferredVariable); -// composedEnforcedDomain.setGuardPattern(composedEnforcedGuardPattern); - } - } - Property cTargetProperty = getProperty(cTemplateVariable.getType(), rPartProperty); - addPropertyAssignment(composedBottomPattern, cTemplateVariable, cTargetProperty, mapExpression(rPartValue)); -// cMapping.getLocal().add(composedMapping); + protected void mapEnforcedObjectTemplateExpression(@NonNull ObjectTemplateExp rEnforcedObjectTemplateExpression, Key key) throws CompilerChainException { + Variable rTemplateVariable/*v*/ = ClassUtil.nonNullState(rEnforcedObjectTemplateExpression.getBindsTo()); + for (@NonNull PropertyTemplateItem pt : ClassUtil.nullFree(rEnforcedObjectTemplateExpression.getPart())) { + Property rPartProperty = ClassUtil.nonNullState(pt.getReferredProperty()); + OCLExpression rPartValue/*pte*/ = ClassUtil.nonNullState(pt.getValue()); + if ((key != null) && key.getPart().contains(rPartProperty)) { + // body of RDomainToMDBottomForEnforcementOfIdentityProp + addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, rPartProperty, rPartValue); + } + else if (rPartValue instanceof TemplateExp) { + // body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject + TemplateExp pte = (TemplateExp)rPartValue; + Variable pv = ClassUtil.nonNullState(pte.getBindsTo()); + /*Realized*/Variable cTargetVariable/*mpv*/ = variablesAnalysis.getCoreVariable(pv); //rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(cEnforcedBottomPattern, pv); + Variable cTemplateVariable/*mv*/ = variablesAnalysis.getCoreVariable(rTemplateVariable); + Property cTargetProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rPartProperty); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, cTargetProperty, createVariableExp(cTargetVariable)); + mapEnforcedTemplateExpression(pte); +// Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable); +// qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable)); + } + else { + // body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive + Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable); + //RDomainToMComposedMappingGuardrEnforcedDomain + for (@NonNull TemplateExp rTemplateExpression : rEnforcedTemplateExpressions) { + if ((rPartValue instanceof VariableExp) && (rTemplateExpression instanceof ObjectTemplateExp)) { + // check + Variable rReferredVariable = (Variable) ClassUtil.nonNullState(((VariableExp) rPartValue).getReferredVariable()); + if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedObjectTemplateExpression, rReferredVariable)) { + Variable cReferredVariable = variablesAnalysis.getCoreVariable(rReferredVariable); + Property cTargetProperty = qvtr2qvtc.getProperty(cReferredVariable.getType(), cReferredVariable); + NavigationCallExp cPropertyCallExp = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), cTargetProperty); + addConditionPredicate(cMiddleGuardPattern, cPropertyCallExp, createVariableExp(cReferredVariable)); + cEnforcedGuardPattern.getBindsTo().add(cReferredVariable); } } + Property cTargetProperty = qvtr2qvtc.getProperty(cTemplateVariable.getType(), rPartProperty); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cTemplateVariable, cTargetProperty, mapExpression(rPartValue)); } } - else { - // throw new CompilerChainException("Missing doInvokedRelationToMappingForEnforcement support for CollectionTemplateExp"); - System.err.println("Missing doRDomainToMDBottomForEnforcement support for CollectionTemplateExp"); - } - // This call is wrong as the trace variable is realized, it can't be guarded. - // This should only be done in a nested mapping or later mapping - //doRDomainToMBottomPredicateForEnforcement(r, rd, te, predicatesWithoutVarBindings, unboundDomainVars, mb); - /* - * Creates the assignment of the middle model to the L/R models - */ - // RDomainVarToMDBottomAssignmnetForEnforcement - Variable cTemplateVariable = getCoreVariable(rTemplateVariable); - Property cTargetProperty = getProperty(cMiddleRealizedVariable.getType(), rTemplateVariable); - addPropertyAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty, createVariableExp(cTemplateVariable)); + } + } + + // RDomainToMDBottomForEnforcement + private void mapEnforcedTemplateExpression(@NonNull TemplateExp rEnforcedTemplateExpression/*te*/) throws CompilerChainException { + Variable rTemplateVariable/*v*/ = ClassUtil.nonNullState(rEnforcedTemplateExpression.getBindsTo()); + Type rTemplateVariableType/*c*/ = ClassUtil.nonNullState(rTemplateVariable.getType()); + Key key = qvtr2qvtc.getKeyForType(rTemplateVariableType); +// if (key == null){ +// // Nothing to do // } - } + /*else*/ if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) { + mapEnforcedObjectTemplateExpression((ObjectTemplateExp)rEnforcedTemplateExpression, key); + } + else if (rEnforcedTemplateExpression instanceof CollectionTemplateExp) { + mapEnforcedCollectionTemplateExpression((CollectionTemplateExp)rEnforcedTemplateExpression, key); + } + else { + throw new CompilerChainException("Missing mapEnforcedTemplateExpression support " + rEnforcedTemplateExpression.eClass().getName()); + } + // This call is wrong as the trace variable is realized, it can't be guarded. + // This should only be done in a nested mapping or later mapping + //doRDomainToMBottomPredicateForEnforcement(r, rd, te, predicatesWithoutVarBindings, unboundDomainVars, mb); + /* + * Creates the assignment of the middle model to the L/R models + */ + // RDomainVarToMDBottomAssignmnetForEnforcement + Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable); + Property cTargetProperty = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), rTemplateVariable); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cTargetProperty, createVariableExp(cTemplateVariable)); + } // 15 /* @@ -789,33 +682,47 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; assert eOut != null; return eOut; } - - protected void mapPredicatesToPredicates(@NonNull Iterable<@NonNull Predicate> rPredicates) { // RPredicateSetToMBPredicateSet - for (@NonNull Predicate rPredicate : rPredicates) { - OCLExpression rExpression = ClassUtil.nonNullState(rPredicate.getConditionExpression()); - addPredicate(cMiddleBottomPattern, mapExpression(rExpression)); - } -/* - // check - if(predSeq.isEmpty()) { - return; + + protected void mapInvocation() throws CompilerChainException {} + + // IROppositeDomainsToMappingForEnforcement + protected void mapOtherDomainPatterns() throws CompilerChainException + { + for (@NonNull AbstractOtherRelationDomain2CoreDomain otherDomain2coreDomain : otherDomain2coreDomains) { + otherDomain2coreDomain.synthesize(); + } + } + + // ROppositeDomainVarsToTraceClassProps + protected void mapOtherDomainVariables(@NonNull Set<@NonNull Variable> rDomainVariables) throws CompilerChainException { + for (@NonNull Variable rDomainVariable : rDomainVariables) { +// VariableAnalysis analysis = getVariableAnalysis(rDomainVariable); +// TemplateExp rTemplateExp = analysis.getTemplateExp(); +// if (dvte instanceof ObjectTemplateExp) { + // tp=dv:T{...} => tcv.tp := dv; + Property cProperty = qvtr2qvtc.basicGetProperty(cMiddleRealizedVariable.getType(), rDomainVariable); + if (cProperty != null) { // null for dead variables + Variable cVariable = variablesAnalysis.getCoreVariable(rDomainVariable); + qvtr2qvtc.addNavigationAssignment(cMiddleBottomPattern, cMiddleRealizedVariable, cProperty, createVariableExp(cVariable)); + } +// } +/* else if (dvte instanceof CollectionTemplateExp) { + // tp=dv:T{...} => tcv.tp := dv; + Variable mdv = doRVarToMVar(dv); +// VariableExp ve1 = createVariableExp(tcv); + VariableExp ve2 = createVariableExp(mdv); + VariableAssignment a = createVariableAssignment(mdv, ve2); + mb.getAssignment().add(a); + } */ +/* else if (dvte instanceof CollectionTemplateExp) { + CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)dvte; + } */ } - Predicate rp = predSeq.remove(0); - OCLExpression re = rp.getConditionExpression(); - assert re != null; - // init - @NonNull Predicate mp = createPredicate(); - // when - @NonNull OCLExpression me = doRExpToMExp(re); - doRPredicateSetToMBPredicateSet(predSeq, mb); - // assign - mp.setConditionExpression(me); - mb.getPredicate().add(mp); */ - } + } - protected @NonNull RealizedVariable mapRealizedVariable(@NonNull Variable rVariable) { - return whenRealizedVariable(cEnforcedBottomPattern, rVariable); - } +// protected @NonNull Variable mapRealizedVariable(@NonNull Variable rVariable) { +// return whenRealizedVariable(cEnforcedBottomPattern, rVariable); +// } /** * Transform a rule implemented by a black box into an enforcement operation @@ -825,77 +732,103 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; * @param cMiddleBottomPattern the mb */ // RRelImplToMBottomEnforcementOperation - protected void mapRelationImplementationToEnforcementOperation() { - - // TODO Code this when testing transformations with operational implementations. - + protected void mapRelationImplementation() { + // TODO Code this when testing transformations with operational implementations. } - protected void mapVariablesToVariables(@NonNull Iterable<@NonNull Variable> rVariables, @NonNull CorePattern cPattern) { // RVarSetToDGVarSet, RVarSetToMBVarSet - for (@NonNull Variable rVariable : rVariables) { - whenVariable(cPattern, rVariable); - } - } +// protected void mapVariables(@NonNull Iterable<@NonNull Variable> rVariables, @NonNull CorePattern cPattern) { // RVarSetToDGVarSet, RVarSetToMBVarSet +// for (@NonNull Variable rVariable : rVariables) { +// whenVariable(cPattern, rVariable); +// } +// } // RWhenPatternToMGuardPattern - protected void mapWhenPatternToGuardPatterns() throws CompilerChainException { + protected void mapWhenPattern() throws CompilerChainException { Pattern rWhenPattern = rRelation.getWhen(); if (rWhenPattern != null) { Set<@NonNull Variable> rMiddleGuardDomainVariables = new HashSet<@NonNull Variable>(rWhenVariables); - rMiddleGuardDomainVariables.removeAll(rAllBoundDomainVariables); + rMiddleGuardDomainVariables.removeAll(rAllDomainVariables); // for (Predicate rWhenPredicate : rWhenPattern.getPredicate()) { OCLExpression rConditionExpression = ClassUtil.nonNullState(rWhenPredicate.getConditionExpression()); if (rConditionExpression instanceof RelationCallExp) { // body of RWhenRelCallToMGuard - RelationCallExp rRelationCallExp = (RelationCallExp)rConditionExpression; - Relation rWhenRelation = ClassUtil.nonNullState(rRelationCallExp.getReferredRelation()); - Type tc = qvtr2qvtc.getTraceClass(rWhenRelation); - // where - StringBuilder s = new StringBuilder(); - List<@NonNull OCLExpression> rRelationCallArguments = ClassUtil.nullFree(rRelationCallExp.getArgument()); - for (OCLExpression rRelationCallArgument : rRelationCallArguments) { - VariableExp a = (VariableExp) rRelationCallArgument; + RelationCallExp rInvocation = (RelationCallExp)rConditionExpression; + Relation rInvokedRelation = ClassUtil.nonNullState(rInvocation.getReferredRelation()); + Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation); + // + List<@NonNull OCLExpression> rArguments = ClassUtil.nullFree(rInvocation.getArgument()); +/* StringBuilder s = new StringBuilder(); + for (OCLExpression rArgument : rArguments) { + VariableExp a = (VariableExp) rArgument; s.append("_"); s.append(a.getReferredVariable().getName()); } - String vdId = s.toString(); - List<Domain> dseq = new ArrayList<Domain>(rWhenRelation.getDomain()); - for (OCLExpression rRelationCallArgument : rRelationCallArguments) { - VariableExp ve = (VariableExp) rRelationCallArgument; - RelationDomain rRelationDomain = (RelationDomain) ClassUtil.nonNullState(dseq.get(rRelationCallArguments.indexOf(ve))); // FIXME multi-root + String vdId = s.toString(); */ + Variable cCalledVariable/*vd*/ = variablesAnalysis.createCoreOnlyVariable("when_" + invokedTraceClass.getName()/* + vdId*/, invokedTraceClass, rConditionExpression); // FIXME + cMiddleGuardPattern.getVariable().add(cCalledVariable); + List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rInvokedRelation); + int iSize = rArguments.size(); + assert iSize == rParameters.size(); + for (int i = 0; i < iSize; i++) { + VariableExp rArgument/*ve*/ = (VariableExp) rArguments.get(i); + Variable rParameter/*dv*/ = rParameters.get(i); //RWhenRelCallArgToMGuardPredicate - Variable dv = rRelationDomain.getRootVariable().get(0); - Variable v = (Variable) ClassUtil.nonNullState(ve.getReferredVariable()); - Variable vd = whenVariable(cMiddleGuardPattern, tc.getName()+vdId+"_v", tc); - Variable mv = getCoreVariable(v); - Property pep = getProperty(vd.getType(), dv); - NavigationCallExp pe = createNavigationCallExp(createVariableExp(vd), pep); - addConditionPredicate(cMiddleGuardPattern, pe, createVariableExp(mv)); + Variable rArgumentVariable/*v*/ = (Variable) ClassUtil.nonNullState(rArgument.getReferredVariable()); + Variable cArgumentVariable/*mv*/ = variablesAnalysis.getCoreVariable(rArgumentVariable); + Property cCalledProperty/*pep*/ = qvtr2qvtc.getProperty(cCalledVariable.getType(), rParameter); + NavigationCallExp cCalledValue/*pe*/ = createNavigationCallExp(createVariableExp(cCalledVariable), cCalledProperty); + addConditionPredicate(cMiddleGuardPattern, cCalledValue, createVariableExp(cArgumentVariable)); } } else { // body of RSimplePatternToMPattern - Predicate mpd = createPredicate(mapExpression(rConditionExpression)); // FIXME orphan + OCLExpression cConditionExpression = mapExpression(rConditionExpression); + addPredicate(cMiddleGuardPattern, cConditionExpression); +// Predicate mpd = createPredicate(mapExpression(rConditionExpression)); // FIXME orphan // addPredicate(composedMappingGuardPattern, cConditionExpression); - throw new UnsupportedOperationException("FIXME orphan"); } } //doUnsharedWhenVarsToMgVars(unsharedWhenVars, mg); - mapVariablesToVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern); +// mapVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern); } } - - protected void putCoreVariable(@NonNull Variable relationVariable, @NonNull Variable coreVariable) { -// Mapping mapping = QVTcoreUtil.getContainingMapping(coreVariable); -// assert mapping != null; - Variable oldVal = rVariable2cVariable.put(relationVariable, coreVariable); - // Variables should only be traced once - if (oldVal != null) { - System.out.println("putCoreVariable replacing value for " + relationVariable.getName()); + + // RPredicateSetToMBPredicateSet + protected void mapWhereBottomPredicates(@NonNull Iterable<@NonNull Predicate> rWherePredicates) { + for (@NonNull Predicate rWherePredicate : rWherePredicates) { + OCLExpression rExpression = ClassUtil.nonNullState(rWherePredicate.getConditionExpression()); + addPredicate(cMiddleBottomPattern, mapExpression(rExpression)); + } +/* + // check + if(predSeq.isEmpty()) { + return; } - putTrace(coreVariable, relationVariable); + Predicate rp = predSeq.remove(0); + OCLExpression re = rp.getConditionExpression(); + assert re != null; + // init + @NonNull Predicate mp = createPredicate(); + // when + @NonNull OCLExpression me = doRExpToMExp(re); + doRPredicateSetToMBPredicateSet(predSeq, mb); + // assign + mp.setConditionExpression(me); + mb.getPredicate().add(mp); */ } + + // RDomainToMDBottomForEnforcement (first half) + protected void mapWhereGuardPredicates(@NonNull Set<@NonNull Predicate> rWhereGuardPredicates, @NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) throws CompilerChainException + { + Set<@NonNull Variable> nonRootEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedBottomDomainVariables); + nonRootEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables); + // + Set<@NonNull Predicate> wherePredicatesWithVarBindings = selectPredicatesThatReferToVariables(rWhereGuardPredicates, nonRootEnforcedBottomDomainVariables); + Set<@NonNull Predicate> remainingWherePredicatesWithoutVarBindings = new HashSet<@NonNull Predicate>(rWhereGuardPredicates); + remainingWherePredicatesWithoutVarBindings.removeAll(wherePredicatesWithVarBindings); + // FIXME How does this do anything? + } private void putTrace(@NonNull Element coreElement, @NonNull Element relationElement) { Element oldRelationElement = target2source.put(coreElement, relationElement); @@ -910,10 +843,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; protected @NonNull Set<@NonNull Predicate> selectPredicatesThatReferToVariables(@NonNull Set<@NonNull Predicate> rPredicates, @NonNull Set<@NonNull Variable> rVariables) { Set<@NonNull Predicate> rPredicatesThatReferToVariables = new HashSet<@NonNull Predicate>(); - for (Predicate rPredicate : rPredicates) { - OCLExpression conditionExpression = rPredicate.getConditionExpression(); - assert conditionExpression != null; - Set<@NonNull Variable> rPredicateVariables = qvtr2qvtc.getVarsOfExp(conditionExpression); + for (@NonNull Predicate rPredicate : rPredicates) { +// OCLExpression conditionExpression = rPredicate.getConditionExpression(); +// assert conditionExpression != null; + Set<@NonNull Variable> rPredicateVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherReferredVariables(rPredicateVariables, rPredicate); rPredicateVariables.retainAll(rVariables); if (rPredicateVariables.isEmpty()) { // FIXME smelly polarity rPredicatesThatReferToVariables.add(rPredicate); @@ -921,134 +855,50 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; } return rPredicatesThatReferToVariables; } - - protected void setAttributes() { - cMiddleBottomPattern.getRealizedVariable().add(cMiddleRealizedVariable); - //mb.getVariable().addAll(mbvars); - cEnforcedDomain.setTypedModel(cEnforcedTypedModel); - cEnforcedDomain.setIsEnforceable(true); - } - - @Override - public @NonNull String toString() { - return rRelation.getName() + "::" + rEnforcedDomainName + " => " + cMapping.getName() + "::" + cEnforcedDomain.getName(); - } - - /** - * Lazily create the RealizedVariable for a corePattern corresponding to a relationVariable. - */ - private @NonNull RealizedVariable whenRealizedVariable(@NonNull BottomPattern corePattern, @NonNull Variable relationVariable) { - Map<@NonNull Variable, @NonNull RealizedVariable> variable2realizedVariable = pattern2variable2realizedVariable.get(corePattern); - if (variable2realizedVariable == null) { - variable2realizedVariable = new HashMap<@NonNull Variable, @NonNull RealizedVariable>(); - pattern2variable2realizedVariable.put(corePattern, variable2realizedVariable); - } - RealizedVariable realizedVariable = variable2realizedVariable.get(relationVariable); - if (realizedVariable == null) { - String name = relationVariable.getName(); - Type type = relationVariable.getType(); - assert (name != null) && (type != null); - realizedVariable = QVTcoreBaseFactory.eINSTANCE.createRealizedVariable(); - realizedVariable.setName(name); - realizedVariable.setType(type); - realizedVariable.setIsRequired(true); - variable2realizedVariable.put(relationVariable, realizedVariable); - corePattern.getRealizedVariable().add(realizedVariable); - putCoreVariable(relationVariable, realizedVariable); - } - return realizedVariable; - } - - /** - * Lazily create the name RealizedVariable for a corePattern with a type. - */ - private @NonNull RealizedVariable whenRealizedVariable(@NonNull BottomPattern corePattern, @NonNull String name, @NonNull Type type) { - Map<@NonNull String, @NonNull RealizedVariable> name2realizedVariable = pattern2name2realizedVariable.get(corePattern); - if (name2realizedVariable == null) { - name2realizedVariable = new HashMap<@NonNull String, @NonNull RealizedVariable>(); - pattern2name2realizedVariable.put(corePattern, name2realizedVariable); - } - RealizedVariable realizedVariable = name2realizedVariable.get(name); - if (realizedVariable == null) { - realizedVariable = QVTcoreBaseFactory.eINSTANCE.createRealizedVariable(); - realizedVariable.setName(name); - realizedVariable.setType(type); - realizedVariable.setIsRequired(true);; - name2realizedVariable.put(name, realizedVariable); - corePattern.getRealizedVariable().add(realizedVariable); -// putTrace(realizedVariable, corePattern); - } - else { - assert realizedVariable.getType() == type; - } - return realizedVariable; - } /** - * Lazily create the Variable for a corePattern corresponding to a relationVariable. + * Exploit the constructed/analyzed context to synthesize the Core constructs. + * @throws CompilerChainException */ - private @NonNull Variable whenVariable(@NonNull CorePattern corePattern, @NonNull Variable relationVariable) { - String name2 = relationVariable.getName(); - Map<@NonNull Variable, @NonNull Variable> variable2variable = pattern2variable2variable.get(corePattern); - if (variable2variable == null) { - variable2variable = new HashMap<@NonNull Variable, @NonNull Variable>(); - pattern2variable2variable.put(corePattern, variable2variable); - } - Variable coreVariable = variable2variable.get(relationVariable); - if (coreVariable == null) { - String name = relationVariable.getName(); - Type type = relationVariable.getType(); - assert (name != null) && (type != null); - coreVariable = PivotFactory.eINSTANCE.createVariable(); - coreVariable.setName(name); - coreVariable.setType(type); - coreVariable.setIsRequired(relationVariable.isIsRequired()); - variable2variable.put(relationVariable, coreVariable); - corePattern.getVariable().add(coreVariable); - putCoreVariable(relationVariable, coreVariable); - } - return coreVariable; + protected void synthesize() throws CompilerChainException { + Set<@NonNull Variable> rEnforcedBottomDomainVariables = getEnforcedBottomDomainVariables(); + // + Set<@NonNull Predicate> rWhereBottomPredicates = selectPredicatesThatReferToVariables(rWherePredicates, rEnforcedBottomDomainVariables); + Set<@NonNull Predicate> rWhereGuardPredicates = new HashSet<@NonNull Predicate>(rWherePredicates); + rWhereGuardPredicates.removeAll(rWhereBottomPredicates); + // +// Set<@NonNull Variable> rEnforcedDomainGuardVariables = getEnforcedDomainGuardVariables(rEnforcedBottomDomainVariables); + // Relation Calls + mapWhereBottomPredicates(rWhereBottomPredicates); +// mapVariables(rEnforcedDomainGuardVariables, cEnforcedGuardPattern); +// mapVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern); + mapOtherDomainPatterns(); + // Invoked here so the variables are instantiated + mapInvocation(); // Only for Invoked rather than Top relation + mapOtherDomainVariables(rAllOtherReferredVariables); + mapWhenPattern(); + mapWhereGuardPredicates(rWhereGuardPredicates, rEnforcedBottomDomainVariables); + mapEnforcedDomainPatterns(); + mapRelationImplementation(); } - - /** - * Lazily create the name Variable for a corePattern with a type. - */ - protected @NonNull Variable whenVariable(@NonNull CorePattern corePattern, @NonNull String name, @NonNull Type type) { - Map<@NonNull String, @NonNull Variable> name2variable = pattern2name2variable.get(corePattern); - if (name2variable == null) { - name2variable = new HashMap<@NonNull String, @NonNull Variable>(); - pattern2name2variable.put(corePattern, name2variable); - } - Variable coreVariable = name2variable.get(name); - if (coreVariable == null) { - coreVariable = PivotFactory.eINSTANCE.createVariable(); - coreVariable.setName(name); - coreVariable.setType(type); - coreVariable.setIsRequired(true); - name2variable.put(name, coreVariable); - corePattern.getVariable().add(coreVariable); - putTrace(coreVariable, corePattern); - } - else { - assert coreVariable.getType() == type; - } - return coreVariable; + + @Override + public @NonNull String toString() { + return rRelationName + "::" + rEnforcedDomainName + " => " + cMapping.getName() + "::" + cEnforcedDomain.getName(); } - - protected abstract void where() throws CompilerChainException; } protected @NonNull final QVTrToQVTc qvtr2qvtc; // Relations protected final @NonNull Relation rRelation; // r: Parent relation of this domain protected final @NonNull RelationalTransformation rTransformation; // Parent transformation of parent relation of enforced domain - protected final @NonNull Set<@NonNull Variable> rAllBoundDomainVariables; // ??All pattern variables declared in all domains (not CollectionTemplateExp member/rest, Let/Iterator variables) + protected final @NonNull String rRelationName; // rRelation.getName() + protected final @NonNull Set<@NonNull Variable> rAllDomainVariables; // ??All pattern variables declared in all domains (not CollectionTemplateExp member/rest, Let/Iterator variables) +// protected final @NonNull List<@NonNull Variable> rAllRootVariables; // The root variables of each domain in relation call order. protected final @NonNull Set<@NonNull Variable> rWhenVariables; // All pattern variables used in when calls protected final @NonNull Set<@NonNull Variable> rWhereVariables; // All pattern variables used in where calls - protected final @NonNull Set<@NonNull Predicate> rPredicates; // All non-RelationCallExp predicates + protected final @NonNull Set<@NonNull Predicate> rWherePredicates; // All non-RelationCallExp where predicates protected final @NonNull Set<@NonNull Variable> rSharedVariables; // All pattern variables shared by more than one domain -// protected final @NonNull Set<@NonNull Variable> rUniquePatternVariables; // All pattern variables that bind to exactly one object -// protected final @NonNull Set<@NonNull Variable> rNonUniquePatternVariables; // All pattern variables that bind to more than one object, typically as a Collection iterator protected final @NonNull Set<@NonNull Variable> rMiddleBottomDomainVariables; // Core protected final @NonNull Transformation cTransformation; // mt: The transformation containing the result mapping @@ -1058,108 +908,62 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; this.qvtr2qvtc = qvtr2qvtc; this.rRelation = rRelation; this.rTransformation = (RelationalTransformation) ClassUtil.nonNullState(rRelation.getTransformation()); - // -// this.rUniquePatternVariables = new HashSet<@NonNull Variable>(); -// this.rNonUniquePatternVariables = new HashSet<@NonNull Variable>(); -// for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { -// for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) { -// gatherPatternVariables(this.rUniquePatternVariables, this.rNonUniquePatternVariables, true, rDomainPattern.getTemplateExpression()); -// } -// } - this.rAllBoundDomainVariables = new HashSet<@NonNull Variable>(); - for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { - for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) { - this.rAllBoundDomainVariables.addAll(ClassUtil.nullFree(rDomainPattern.getBindsTo())); - } - } -// rAllBoundDomainVariables.addAll(rUniquePatternVariables); -// rAllBoundDomainVariables.addAll(rNonUniquePatternVariables); + this.rRelationName = ClassUtil.nonNullState(rRelation.getName()); // this.rWhenVariables = new HashSet<@NonNull Variable>(); Pattern rWhenPattern = rRelation.getWhen(); if (rWhenPattern != null) { - this.rWhenVariables.addAll(ClassUtil.nullFree(rWhenPattern.getBindsTo())); + VariablesAnalysis.gatherReferredVariables(rWhenVariables, rWhenPattern); +// FIXME assert rWhenPattern.getBindsTo().equals(rWhenVariables); +// rWhenPattern.getBindsTo().addAll(rWhenVariables); } // this.rWhereVariables = new HashSet<@NonNull Variable>(); - this.rPredicates = new HashSet<@NonNull Predicate>(); + this.rWherePredicates = new HashSet<@NonNull Predicate>(); Pattern rWherePattern = rRelation.getWhere(); if (rWherePattern != null) { - this.rWhereVariables.addAll(ClassUtil.nullFree(rWherePattern.getBindsTo())); - for (@NonNull Predicate rPredicate : ClassUtil.nullFree(rWherePattern.getPredicate())) { - if (!(rPredicate.getConditionExpression() instanceof RelationCallExp)) { - rPredicates.add(rPredicate); + VariablesAnalysis.gatherReferredVariables(rWhereVariables, rWherePattern); +// FIXME assert rWherePattern.getBindsTo().equals(rWhereVariables); +// rWherePattern.getBindsTo().addAll(rWhereVariables); + for (@NonNull Predicate rWherePredicate : ClassUtil.nullFree(rWherePattern.getPredicate())) { + if (!(rWherePredicate.getConditionExpression() instanceof RelationCallExp)) { + rWherePredicates.add(rWherePredicate); } } } // - this.rSharedVariables = qvtr2qvtc.getMiddleDomainVariables(rRelation); + this.rAllDomainVariables = new HashSet<@NonNull Variable>(); +/* for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { + for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) { + Set<@NonNull Variable> rDomainVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherReferredVariables(rDomainVariables, rDomainPattern); +// FIXME assert rDomainPattern.getBindsTo().equals(rDomainVariables); +// rDomainPattern.getBindsTo().addAll(rDomainVariables); + rAllDomainVariables.addAll(rDomainVariables); + } + } */ + VariablesAnalysis.gatherReferredVariables(rAllDomainVariables, ClassUtil.nullFree(rRelation.getDomain())); + // + this.rSharedVariables = VariablesAnalysis.getMiddleDomainVariables(rRelation); // this.rMiddleBottomDomainVariables = new HashSet<@NonNull Variable>(rWhereVariables); rMiddleBottomDomainVariables.removeAll(rWhenVariables); - rMiddleBottomDomainVariables.removeAll(rAllBoundDomainVariables); + rMiddleBottomDomainVariables.removeAll(rAllDomainVariables); rMiddleBottomDomainVariables.addAll(rSharedVariables); // FIXME this stinks // this.cTransformation = qvtr2qvtc.getCoreTransformation(rTransformation); } - - protected @Nullable Property basicGetProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { - /*@NonNull*/ String name = rNamedElement.getName(); - assert (aClass != null) && (name != null); - CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass); - return completeClass.getProperty(name); - } /** - * Add each of the domain variables within templateExpression to either uniquePatternVariables or nonUniquePatternVariables - * according to whether the variable has a single or multiple bindings in the overall context. The isUnique parameter is - * propagated during the recursion as true until a collection is traversed. - * - private void gatherPatternVariables(@NonNull Set<@NonNull Variable> uniquePatternVariables, @NonNull Set<@NonNull Variable> nonUniquePatternVariables, - boolean isUnique, @NonNull TemplateExp templateExpression) { - Variable templateVariable = ClassUtil.nonNullState(templateExpression.getBindsTo()); - (isUnique ? uniquePatternVariables : nonUniquePatternVariables).add(templateVariable); - if (templateExpression instanceof ObjectTemplateExp) { - for (@NonNull PropertyTemplateItem propertyTemplateItem : ClassUtil.nullFree(((ObjectTemplateExp)templateExpression).getPart())) { - Property property = propertyTemplateItem.getReferredProperty(); - OCLExpression value = propertyTemplateItem.getValue(); - if (value instanceof TemplateExp) { - gatherPatternVariables(uniquePatternVariables, nonUniquePatternVariables, isUnique && !property.isIsMany(), (@NonNull TemplateExp) value); - } - } - } - else if (templateExpression instanceof CollectionTemplateExp) { - for (@NonNull OCLExpression memberExpression : ClassUtil.nullFree(((CollectionTemplateExp)templateExpression).getMember())) { - if (memberExpression instanceof TemplateExp) { - gatherPatternVariables(uniquePatternVariables, nonUniquePatternVariables, false, (@NonNull TemplateExp) memberExpression); - } - } - } - } */ - - protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { - /*@NonNull*/ String name = rNamedElement.getName(); - assert (aClass != null) && (name != null); - CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass); - Property p = completeClass.getProperty(name); - if (p != null) - return p; - throw new CompilerChainException("No property '" + name + "' in '" + aClass + "::" + "'"); - } + * Return an AbstractEnforceableRelationDomain2CoreMapping for each Core Mapping that is to be synthesized. + */ + protected abstract @NonNull List<@NonNull ? extends AbstractEnforceableRelationDomain2CoreMapping> analyze() throws CompilerChainException; -// protected @NonNull Set<@NonNull Variable> getUnsharedWhenVars(@NonNull Set<@NonNull Variable> whenVars, @NonNull Set<@NonNull Variable> allDomainVars) { -// Set<@NonNull Variable> unsharedWhereVars = new HashSet<@NonNull Variable>(whenVars); -// unsharedWhereVars.removeAll(allDomainVars); -// return unsharedWhereVars; -// } - - protected void where(@NonNull Relation rRelation, @NonNull List<@NonNull ? extends AbstractEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings) throws CompilerChainException { - for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : enforceableRelationDomain2coreMappings) { - enforceableRelationDomain2coreMapping.where(); - } - // setAttributes() { + public void transform() throws CompilerChainException { + List<@NonNull ? extends AbstractEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = analyze(); for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : enforceableRelationDomain2coreMappings) { - enforceableRelationDomain2coreMapping.setAttributes(); + enforceableRelationDomain2coreMapping.synthesize(); + enforceableRelationDomain2coreMapping.variablesAnalysis.check(); } } } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/InvokedRelationToMappingForEnforcement.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/InvokedRelationToMappingForEnforcement.java index a229f4086..a02772a6a 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/InvokedRelationToMappingForEnforcement.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/InvokedRelationToMappingForEnforcement.java @@ -25,15 +25,13 @@ import org.eclipse.ocl.pivot.VariableExp; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.CompilerChainException; import org.eclipse.qvtd.pivot.qvtbase.Domain; -import org.eclipse.qvtd.pivot.qvtbase.Predicate; import org.eclipse.qvtd.pivot.qvtrelation.Relation; import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp; import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; -import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; /*public*/ class InvokedRelationToMappingForEnforcement extends AbstractQVTr2QVTcRelations { - private class InvokedEnforceableRelationDomain2CoreMapping extends AbstractEnforceableRelationDomain2CoreMapping + protected class InvokedEnforceableRelationDomain2CoreMapping extends AbstractEnforceableRelationDomain2CoreMapping { protected class InvokedOtherRelationDomain2CoreDomain extends AbstractOtherRelationDomain2CoreDomain { @@ -41,34 +39,34 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; super(rOtherDomain); } - // body of IROppositeDomainsToMappingForEnforcement +/* // body of IROppositeDomainsToMappingForEnforcement @Override - public void mapOtherDomainToDomainVariablesAndPatterns() throws CompilerChainException { - List<@NonNull Variable> rOtherDomainVariables = getDomainVariables(rOtherDomain); //ClassUtil.nullFree(rOtherDomainPattern.getBindsTo()); - List<@NonNull TemplateExp> rOtherTemplateExpressions = getTemplateExpressions(rOtherDomain); - List<@NonNull Variable> rOtherRootVariables = getRootVariables(rOtherDomain); + public void synthesize() throws CompilerChainException { // FIXME unify with TopLevel +// Set<@NonNull Variable> rOtherDomainVariables = new HashSet<@NonNull Variable>(); +// gatherReferredVariables(rOtherDomainVariables, rOtherDomain); //ClassUtil.nullFree(rOtherDomainPattern.getBindsTo()); +// assert rOtherDomainVariables.equals(Sets.newHashSet(getDomainVariables(rOtherDomain))); +// List<@NonNull Variable> rOtherRootVariables = getRootVariables(rOtherDomain); // - Set<@NonNull Variable> rOtherGuardVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rOtherGuardVariables.retainAll(rWhenVariables); - rOtherGuardVariables.addAll(rOtherRootVariables); +// Set<@NonNull Variable> rOtherGuardVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rOtherGuardVariables.retainAll(rWhenVariables); +// rOtherGuardVariables.addAll(rOtherRootVariables); // - Set<@NonNull Variable> rOtherBottomVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rOtherBottomVariables.removeAll(rWhenVariables); - rOtherBottomVariables.removeAll(rSharedVariables); - rOtherBottomVariables.removeAll(rOtherRootVariables); +// Set<@NonNull Variable> rOtherBottomVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rOtherBottomVariables.removeAll(rWhenVariables); +// rOtherBottomVariables.removeAll(rSharedVariables); +// rOtherBottomVariables.removeAll(rOtherRootVariables); // - Set<@NonNull Variable> rMiddleBottomVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rMiddleBottomVariables.removeAll(rWhenVariables); - rMiddleBottomVariables.retainAll(rSharedVariables); - rMiddleBottomVariables.removeAll(rOtherRootVariables); +// Set<@NonNull Variable> rMiddleBottomVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rMiddleBottomVariables.removeAll(rWhenVariables); +// rMiddleBottomVariables.retainAll(rSharedVariables); +// rMiddleBottomVariables.removeAll(rOtherRootVariables); // - mapVariablesToVariables(rOtherGuardVariables, cOtherGuardPattern); - mapVariablesToVariables(rOtherBottomVariables, cOtherBottomPattern); - mapVariablesToVariables(rMiddleBottomVariables, cMiddleBottomPattern); - for (@NonNull TemplateExp rOtherTemplateExpression : rOtherTemplateExpressions) { - addTemplateExpressionToMiddleBottom(rOtherTemplateExpression); - } - } +// mapVariables(rOtherGuardVariables, cOtherGuardPattern); +// mapVariables(rOtherBottomVariables, cOtherBottomPattern); +// mapVariables(rMiddleBottomVariables, cMiddleBottomPattern); + // + super.synthesize(); + } */ } private @NonNull Relation rInvokingRelation; @@ -77,7 +75,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; public InvokedEnforceableRelationDomain2CoreMapping(@NonNull RelationCallExp rInvocation, @NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) { super(rEnforcedDomain, cMappingName); this.rInvocation = rInvocation; - this.rInvokingRelation = qvtr2qvtc.getInvokingRelationForRelationCallExp(rInvocation); + this.rInvokingRelation = qvtr2qvtc.getInvokingRelation(rInvocation); } @Override @@ -85,59 +83,47 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; return new InvokedOtherRelationDomain2CoreDomain(rRelationDomain); } + @Override + protected @NonNull Set<@NonNull Variable> getEnforcedBottomDomainVariables() { // FIXME unify with TopLevel + Set<@NonNull Variable> rEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedReferredVariables); + rEnforcedBottomDomainVariables.removeAll(rWhenVariables); + rEnforcedBottomDomainVariables.removeAll(rSharedVariables); + rEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables); + return rEnforcedBottomDomainVariables; + } + +// @Override +// protected @NonNull Set<@NonNull Variable> getEnforcedDomainGuardVariables(@NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) { // FIXME unify with TopLevel +// Set<@NonNull Variable> rEnforcedDomainGuardVariables = new HashSet<@NonNull Variable>(rEnforcedReferredVariables); +// rEnforcedDomainGuardVariables.retainAll(rWhenVariables); +// rEnforcedDomainGuardVariables.addAll(rEnforcedRootVariables); +// return rEnforcedDomainGuardVariables; +// } + // RInvokerToMGuard - private void mapInvokerToGuardPredicates() throws CompilerChainException { - // where - List<@NonNull Domain> dseq = new ArrayList<@NonNull Domain>(ClassUtil.nullFree(rRelation.getDomain())); + @Override + protected void mapInvocation() throws CompilerChainException { + Type invokingTraceClass = qvtr2qvtc.getTraceClass(rInvokingRelation); + Variable cInvocationVariable/*vd*/ = variablesAnalysis.createCoreOnlyVariable("from_" + invokingTraceClass.getName(), invokingTraceClass, rInvokingRelation); + cMiddleGuardPattern.getVariable().add(cInvocationVariable); + Type cInvocationType = cInvocationVariable.getType(); + assert cInvocationType == invokingTraceClass; // FIXME List<@NonNull OCLExpression> rArguments = ClassUtil.nullFree(rInvocation.getArgument()); - for (@NonNull OCLExpression rArgument : rArguments) { + List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rRelation); + int iSize = rArguments.size(); + assert iSize == rParameters.size(); + for (int i = 0; i < iSize; i++) { + Variable rParameter = rParameters.get(i); + OCLExpression rArgument = rArguments.get(i); VariableExp rArgumentVariableExp = (VariableExp)rArgument; - @NonNull RelationDomain rArgumentDomain = (RelationDomain) dseq.get(rArguments.indexOf(rArgumentVariableExp)); // FIXME multi-roots // RInvokerToMGuardPredicate - Type traceClass = qvtr2qvtc.getTraceClass(rInvokingRelation); Variable rArgumentVariable = (Variable) ClassUtil.nonNullState(rArgumentVariableExp.getReferredVariable()); - Variable rRootVariable = ClassUtil.nonNullState(rArgumentDomain.getRootVariable().get(0)); - Variable vd = whenVariable(cMiddleGuardPattern, traceClass.getName()+"_v", traceClass); - Variable cRootVariable = getCoreVariable(rRootVariable); - Property cProperty = getProperty(vd.getType(), rArgumentVariable); - NavigationCallExp cTraceValue = createNavigationCallExp(createVariableExp(vd), cProperty); - addConditionPredicate(cMiddleGuardPattern, cTraceValue, createVariableExp(cRootVariable)); + Variable cParameter = variablesAnalysis.getCoreVariable(rParameter); + Property cProperty = qvtr2qvtc.getProperty(cInvocationType, rArgumentVariable); + NavigationCallExp cInvocationValue = createNavigationCallExp(createVariableExp(cInvocationVariable), cProperty); + addConditionPredicate(cMiddleGuardPattern, cInvocationValue, createVariableExp(cParameter)); } } - - @Override - protected void where() throws CompilerChainException { - Set<@NonNull Variable> rEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedDomainVariables); - rEnforcedBottomDomainVariables.removeAll(rWhenVariables); - rEnforcedBottomDomainVariables.removeAll(rSharedVariables); - rEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables); - // - Set<@NonNull Predicate> rPredicatesWithVariableBindings = selectPredicatesThatReferToVariables(rPredicates, rEnforcedBottomDomainVariables); - // - Set<@NonNull Predicate> rPredicatesWithoutVariableBindings = new HashSet<@NonNull Predicate>(rPredicates); - rPredicatesWithoutVariableBindings.removeAll(rPredicatesWithVariableBindings); - // - Set<@NonNull Variable> rEnforcedDomainGuardVariables = new HashSet<@NonNull Variable>(rEnforcedDomainVariables); - rEnforcedDomainGuardVariables.retainAll(rWhenVariables); - rEnforcedDomainGuardVariables.addAll(rEnforcedRootVariables); - // Relation Calls - // T5 - mapPredicatesToPredicates(rPredicatesWithVariableBindings); - mapVariablesToVariables(rEnforcedDomainGuardVariables, cEnforcedGuardPattern); - //T4 - mapVariablesToVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern); - //T3 - - // IROppositeDomainsToMappingForEnforcement - for (@NonNull AbstractOtherRelationDomain2CoreDomain otherDomain2coreDomain : otherDomain2coreDomains) { - otherDomain2coreDomain.mapOtherDomainToDomainVariablesAndPatterns(); - } - mapInvokerToGuardPredicates(); - mapDomainVariablesToMiddleVariableAssignments(rOtherDomainVariables); - mapWhenPatternToGuardPatterns(); - mapEnforcedDomain(rPredicatesWithoutVariableBindings, rEnforcedBottomDomainVariables); - mapRelationImplementationToEnforcementOperation(); - } } public InvokedRelationToMappingForEnforcement(@NonNull QVTrToQVTc qvtr2qvtc, @NonNull Relation rRelation) { @@ -145,35 +131,24 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; assert !rRelation.isIsTopLevel(); } - public void doInvokedRelationToMappingForEnforcement() throws CompilerChainException { - // check() { - @NonNull List<@NonNull InvokedEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = new ArrayList<@NonNull InvokedEnforceableRelationDomain2CoreMapping>(); + /** + * Each invocation of each enforced domain is synthesized as a separate mapping. + */ + @Override + protected @NonNull List<@NonNull InvokedEnforceableRelationDomain2CoreMapping> analyze() throws CompilerChainException { + List<@NonNull InvokedEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = new ArrayList<@NonNull InvokedEnforceableRelationDomain2CoreMapping>(); for (@NonNull RelationCallExp rInvocation : qvtr2qvtc.getRelationCallExpsForRelation(rRelation)) { QVTrToQVTc.SYNTHESIS.println("invocation of " + rRelation + " from " + rInvocation); + @NonNull Relation rInvokingRelation = qvtr2qvtc.getInvokingRelation(rInvocation); + @NonNull String rInvokingRelationName = ClassUtil.nonNullState(rInvokingRelation.getName()); for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { if (rDomain.isIsEnforceable()) { RelationDomain rEnforcedDomain = (RelationDomain)rDomain; -// @NonNull DomainPattern rEnforcedDomainPattern = qvtr2qvtc.getDomainPattern(rEnforcedDomain); -// TemplateExp rEnforcedTemplateExpression = rEnforcedDomainPattern.getTemplateExpression(); - String coreMappingName = getCoreMappingName(rInvocation, rEnforcedDomain); -// if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) { - enforceableRelationDomain2coreMappings.add(new InvokedEnforceableRelationDomain2CoreMapping(rInvocation, rEnforcedDomain, coreMappingName)); -// } -// else { -// throw new CompilerChainException("Missing doInvokedRelationToMappingForEnforcement support for CollectionTemplateExp"); -// enforceableRelationDomain2coreMappings.add(new InvokedEnforceableRelationDomain2CoreMapping(rInvocation, rEnforcedDomain, coreMappingName)); -// } + String coreMappingName = rRelationName + '_' + rInvokingRelationName + '_' + rEnforcedDomain.getName(); + enforceableRelationDomain2coreMappings.add(new InvokedEnforceableRelationDomain2CoreMapping(rInvocation, rEnforcedDomain, coreMappingName)); } } } - // where() - where(rRelation, enforceableRelationDomain2coreMappings); - } - - private @NonNull String getCoreMappingName(@NonNull RelationCallExp rInvocation, @NonNull RelationDomain rEnforcedDomain) { - @NonNull Relation rInvokingRelation = qvtr2qvtc.getInvokingRelationForRelationCallExp(rInvocation); - @NonNull String rRelationName = ClassUtil.nonNullState(rRelation.getName()); - @NonNull String rRelationNameName = ClassUtil.nonNullState(rInvokingRelation.getName()); - return rRelationName + '_' + rRelationNameName + '_' + rEnforcedDomain.getName(); + return enforceableRelationDomain2coreMappings; } } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java index ee9a51a49..c7ac2500b 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrToQVTc.java @@ -47,10 +47,12 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.examples.codegen.oclinecore.OCLinEcoreGeneratorAdapterFactory; import org.eclipse.ocl.pivot.CollectionType; +import org.eclipse.ocl.pivot.CompleteClass; import org.eclipse.ocl.pivot.DataType; import org.eclipse.ocl.pivot.Element; import org.eclipse.ocl.pivot.Import; import org.eclipse.ocl.pivot.Model; +import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.Namespace; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.Package; @@ -58,6 +60,7 @@ import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.StandardLibrary; import org.eclipse.ocl.pivot.Type; +import org.eclipse.ocl.pivot.TypedElement; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.VariableDeclaration; import org.eclipse.ocl.pivot.VariableExp; @@ -77,15 +80,20 @@ import org.eclipse.qvtd.pivot.qvtbase.Pattern; import org.eclipse.qvtd.pivot.qvtbase.Predicate; import org.eclipse.qvtd.pivot.qvtbase.Rule; import org.eclipse.qvtd.pivot.qvtbase.Transformation; +import org.eclipse.qvtd.pivot.qvtbase.TypedModel; import org.eclipse.qvtd.pivot.qvtbase.utilities.TreeIterable; import org.eclipse.qvtd.pivot.qvtcore.CoreModel; import org.eclipse.qvtd.pivot.qvtcore.Mapping; import org.eclipse.qvtd.pivot.qvtcore.QVTcoreFactory; import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper; +import org.eclipse.qvtd.pivot.qvtcorebase.Assignment; import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern; import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain; import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern; +import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment; import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory; +import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable; +import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseUtil; import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern; import org.eclipse.qvtd.pivot.qvtrelation.Key; import org.eclipse.qvtd.pivot.qvtrelation.Relation; @@ -93,9 +101,6 @@ import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp; import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; import org.eclipse.qvtd.pivot.qvtrelation.RelationModel; import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation; -import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp; -import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp; -import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem; import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; public class QVTrToQVTc @@ -140,16 +145,30 @@ public class QVTrToQVTc private final @NonNull List<org.eclipse.ocl.pivot.@NonNull Package> tracePackages = new ArrayList<org.eclipse.ocl.pivot.@NonNull Package>(); // private final @NonNull List<@NonNull Transformation> coreTransformations = new ArrayList<@NonNull Transformation>(); - private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relationToTraceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>(); + + /** + * Mapping from each relation to its corresponding trace class. + */ + private final @NonNull Map<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class> relation2traceClass = new HashMap<@NonNull Relation, org.eclipse.ocl.pivot.@NonNull Class>(); + // Un-navigable opposites // // The Key that identifies each Class. - // FIXME can there be two keys for the sane Class? + // FIXME can there be two keys for the same Class? // private final @NonNull Map<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key> class2key = new HashMap<org.eclipse.ocl.pivot.@NonNull Class, @NonNull Key>(); - private final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> variable2templateExp = new HashMap<@NonNull Variable, @NonNull TemplateExp>(); - private final @NonNull Map<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>> relationCallExpsForRelation = new HashMap<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>>(); - private final @NonNull Map<@NonNull RelationCallExp, @NonNull Relation> rInvocation2invokingRelation = new HashMap<@NonNull RelationCallExp, @NonNull Relation>(); + + /** + * Map from each relation to all the expressions that call the relation. + */ + private final @NonNull Map<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>> relation2invocations = new HashMap<@NonNull Relation, @NonNull List<@NonNull RelationCallExp>>(); + + /** + * Map from each relation invocation the relation whose where predicate contains the invocation. + * @deprecated computable - no cache required + */ + @Deprecated + private final @NonNull Map<@NonNull RelationCallExp, @NonNull Relation> invocation2invokingRelation = new HashMap<@NonNull RelationCallExp, @NonNull Relation>(); private @NonNull CoreModel coreModel; @@ -164,12 +183,12 @@ public class QVTrToQVTc */ private @NonNull Map<@NonNull RelationalTransformation, org.eclipse.ocl.pivot.@NonNull Package> relationalTransformation2tracePackage = new HashMap<@NonNull RelationalTransformation, org.eclipse.ocl.pivot.@NonNull Package>(); - + /** - * The lazily created named CoreDomain in each Rule. + * The core TypedModel for each Relational TypedModel. */ - private @NonNull Map<@NonNull Rule, @NonNull Map<@NonNull String, @NonNull CoreDomain>> rule2name2coreDomain - = new HashMap<@NonNull Rule, @NonNull Map<@NonNull String, @NonNull CoreDomain>>(); + private @NonNull Map<@NonNull TypedModel, @NonNull TypedModel> relationalTypedModel2coreTypedModel + = new HashMap<@NonNull TypedModel, @NonNull TypedModel>(); /** * The lazily created named Trace Properties in each Trace Class. @@ -182,6 +201,11 @@ public class QVTrToQVTc */ private @NonNull Map<@NonNull Transformation, @NonNull Map<@NonNull String, @NonNull Mapping>> transformation2name2mapping = new HashMap<@NonNull Transformation, @NonNull Map<@NonNull String, @NonNull Mapping>>(); + + /** + * The root variables (in relation call order) of each relation. + */ + private @NonNull Map<@NonNull Relation, @NonNull List<@NonNull Variable>> relation2rootVariables = new HashMap<@NonNull Relation, @NonNull List<@NonNull Variable>>(); public QVTrToQVTc(@NonNull EnvironmentFactory environmentFactory, @NonNull Resource qvtrResource, @NonNull Resource qvtcResource) { this.environmentFactory = environmentFactory; @@ -193,72 +217,165 @@ public class QVTrToQVTc // Create a cache of opposite relations and copy imports TreeIterator<EObject> it = qvtrResource.getAllContents(); - while(it.hasNext()) { + while (it.hasNext()) { EObject eo = it.next(); if (eo instanceof Key) { - Key key = (Key)eo; - org.eclipse.ocl.pivot.Class identifies = key.getIdentifies(); - assert identifies != null; - class2key.put(identifies, key); + analyzeKey((Key)eo); } - // Populate bindsTo of DomainPattern - if (eo instanceof Pattern) { - Pattern p = (Pattern) eo; - for (Predicate pred : p.getPredicate()) { - OCLExpression conditionExpression = pred.getConditionExpression(); - assert conditionExpression != null; - p.getBindsTo().addAll(getVarsOfExp(conditionExpression)); - } - if (eo instanceof DomainPattern) { - DomainPattern dp = (DomainPattern) eo; - TemplateExp te = dp.getTemplateExpression(); - dp.getBindsTo().add(te.getBindsTo()); - if (te instanceof ObjectTemplateExp) { - dp.getBindsTo().addAll(getNestedBindToVariable((ObjectTemplateExp) te)); + if (eo instanceof Relation) { + Relation relation = (Relation)eo; + analyzeInvocations(relation); + analyzeRootVariables(relation); + } + if (eo instanceof Import) { + this.coreModel.getOwnedImports().add((Import) EcoreUtil.copy(eo)); + } + } + } + + /** + * Add the NavigationAssignment "cVariable.cProperty := cExpression" to the cBottomPattern inverting the usage + * of a Collection element assignment to "cExpression.cOppositeProperty := cVariable". + */ + public void addNavigationAssignment(@NonNull BottomPattern cBottomPattern, @NonNull Variable cVariable, @NonNull Property cProperty, @NonNull OCLExpression cExpression) { + if (!cProperty.isIsMany() || (cExpression.getType() instanceof CollectionType)) { + VariableExp cSlotVariableExp = helper.createVariableExp(cVariable); + NavigationAssignment cAssignment = helper.createNavigationAssignment(cSlotVariableExp, cProperty, cExpression); + System.out.println("addPropertyAssignment " + cAssignment); + assertNewAssignment(cBottomPattern.getAssignment(), cAssignment); + cBottomPattern.getAssignment().add(cAssignment); + return; + } + Property cOppositeProperty = cProperty.getOpposite(); + if ((cOppositeProperty != null) && (cExpression instanceof VariableExp) && (!cOppositeProperty.isIsMany() || (cVariable.getType() instanceof CollectionType))) { + VariableExp cSlotVariableExp = (VariableExp)cExpression; + NavigationAssignment cAssignment = helper.createNavigationAssignment(cSlotVariableExp, cOppositeProperty, helper.createVariableExp(cVariable)); + System.out.println("addOppositePropertyAssignment " + cAssignment); + assertNewAssignment(cBottomPattern.getAssignment(), cAssignment); + cBottomPattern.getAssignment().add(cAssignment); + return; + } + throw new IllegalStateException("Unsupported collection assign " + cVariable + "." + cProperty + ":=" + cExpression); + } + + protected void analyzeInvocations(@NonNull Relation callingRelation) { + Pattern wherePattern = callingRelation.getWhere(); + if (wherePattern != null) { + for (Predicate predicate : wherePattern.getPredicate()) { + OCLExpression predicateExpression = predicate.getConditionExpression(); + if (predicateExpression instanceof RelationCallExp) { + RelationCallExp relationInvocation = (RelationCallExp) predicateExpression; + Relation calledRelation = ClassUtil.nonNullState(relationInvocation.getReferredRelation()); + List<@NonNull RelationCallExp> relationInvocations = relation2invocations.get(calledRelation); + if (relationInvocations == null) { + relationInvocations = new ArrayList<@NonNull RelationCallExp>(); + relation2invocations.put(calledRelation, relationInvocations); } + relationInvocations.add(relationInvocation); + invocation2invokingRelation.put(relationInvocation, callingRelation); } } - if (eo instanceof TemplateExp) { - TemplateExp te = (TemplateExp) eo; - Variable bindsTo = te.getBindsTo(); - assert bindsTo != null; - variable2templateExp.put(bindsTo, te); + } + } + + protected void analyzeKey(@NonNull Key key) { + org.eclipse.ocl.pivot.Class identifies = key.getIdentifies(); + assert identifies != null; + class2key.put(identifies, key); + } + + protected void analyzeRootVariables(@NonNull Relation relation) { + List<@NonNull Variable> rootVariables = new ArrayList<@NonNull Variable>(); + for (@NonNull Domain rDomain : ClassUtil.nullFree(relation.getDomain())) { + for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) { + TemplateExp rRootTemplateExpression = rDomainPattern.getTemplateExpression(); + if (rRootTemplateExpression != null) { + Variable rRootVariable = rRootTemplateExpression.getBindsTo(); + if (rRootVariable != null) { + rootVariables.add(rRootVariable); + } + } } - if (eo instanceof RelationCallExp) { - RelationCallExp ri = (RelationCallExp) eo; - Relation r = ri.getReferredRelation(); - assert r != null; - Predicate p = (Predicate) ri.eContainer(); - Pattern pattern = p.getPattern(); - if (pattern.eContainer() instanceof Relation) { - Relation ir = (Relation) pattern.eContainer(); - if (ir.getWhere() == pattern) { - List<RelationCallExp> relationCallExps = relationCallExpsForRelation.get(r); - if (relationCallExps != null) { - relationCallExps.add(ri); - } else { - List<RelationCallExp> callExps = new ArrayList<RelationCallExp>(); - callExps.add(ri); - relationCallExpsForRelation.put(r, callExps); + } + relation2rootVariables.put(relation, rootVariables); + } + + private void assertNewAssignment(@NonNull List<Assignment> oldAssignments, @NonNull NavigationAssignment newAssignment) { +// if ("tr.action := sm".equals(newAssignment.toString())) { +// newAssignment.toString(); +// } + OCLExpression newSlotExpression = newAssignment.getSlotExpression(); + if (newSlotExpression instanceof VariableExp) { + VariableDeclaration newVariable = ((VariableExp)newSlotExpression).getReferredVariable(); + Property targetProperty = QVTcoreBaseUtil.getTargetProperty(newAssignment); + for (Assignment oldAssignment : oldAssignments) { + if (oldAssignment instanceof NavigationAssignment) { + if (QVTcoreBaseUtil.getTargetProperty((NavigationAssignment)oldAssignment) == targetProperty) { + OCLExpression oldSlotExpression = ((NavigationAssignment)oldAssignment).getSlotExpression(); + if (oldSlotExpression instanceof VariableExp) { + VariableDeclaration oldVariable = ((VariableExp)oldSlotExpression).getReferredVariable(); + assert oldVariable != newVariable : "Repeated assignment: \"" + oldAssignment + "\", \"" + newAssignment + "\""; } - rInvocation2invokingRelation.put(ri, ir); } } } - if (eo instanceof Import) { - this.coreModel.getOwnedImports().add((Import) EcoreUtil.copy(eo)); - } } } - - public @NonNull Mapping createMapping() { - Mapping coreMapping = QVTcoreFactory.eINSTANCE.createMapping(); + + public @Nullable Property basicGetProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { + /*@NonNull*/ String name = rNamedElement.getName(); + assert (aClass != null) && (name != null); + CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass); + return completeClass.getProperty(name); + } + + public @NonNull CoreDomain createCoreDomain(@NonNull TypedModel typedModel) { + CoreDomain coreDomain = QVTcoreBaseFactory.eINSTANCE.createCoreDomain(); + coreDomain.setTypedModel(typedModel); + coreDomain.setName(ClassUtil.nonNullState(typedModel.getName())); +// putTrace(coreDomain, coreRule); GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern(); - coreMapping.setGuardPattern(guardPattern); + coreDomain.setGuardPattern(guardPattern); +// putTrace(guardPattern, coreRule); BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern(); - coreMapping.setBottomPattern(bottomPattern); + coreDomain.setBottomPattern(bottomPattern); + return coreDomain; + } + + /** + * Create the name Mapping for a coreTransformation. + */ + /*public*/ @NonNull Mapping createMapping(@NonNull Relation relation, @NonNull String name) { + RelationalTransformation rt = (RelationalTransformation) relation.getTransformation(); + assert rt != null; + @NonNull Transformation coreTransformation = getCoreTransformation(rt); + Map<@NonNull String, @NonNull Mapping> name2mapping = transformation2name2mapping.get(coreTransformation); + if (name2mapping == null) { + name2mapping = new HashMap<@NonNull String, @NonNull Mapping>(); + transformation2name2mapping.put(coreTransformation, name2mapping); + } + Mapping coreMapping = name2mapping.get(name); + assert (coreMapping == null);// { + coreMapping = helper.createMapping(name); + putGlobalTrace(coreMapping, relation); + coreMapping.setTransformation(coreTransformation); + name2mapping.put(name, coreMapping); +// } return coreMapping; } + + + public @NonNull RealizedVariable createRealizedVariable(@NonNull TypedElement typedElement) { + return createRealizedVariable(ClassUtil.nonNullState(typedElement.getName()), ClassUtil.nonNullState(typedElement.getType())); + } + + public @NonNull RealizedVariable createRealizedVariable(@NonNull String name, @NonNull Type type) { + RealizedVariable realizedVariable = QVTcoreBaseFactory.eINSTANCE.createRealizedVariable(); + realizedVariable.setName(name); + realizedVariable.setType(type); + realizedVariable.setIsRequired(true); + return realizedVariable; + } // Save the qvtc resource public void dispose() { @@ -271,10 +388,72 @@ public class QVTrToQVTc transformToCoreTransformations(); } + public void generateModels(@NonNull GenModel genModel) { + Registry generatorAdapterDescriptorRegistry = GeneratorAdapterFactory.Descriptor.Registry.INSTANCE; + if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(GenModelGeneratorAdapterFactory.DESCRIPTOR)) { + generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, GenModelGeneratorAdapterFactory.DESCRIPTOR); + } + if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR)) { + generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR); + } +//** ResourceUtils.checkResourceSet(resourceSet); + // genModel.setCanGenerate(true); + // validate(); + + + + genModel.setValidateModel(true); // The more checks the better +// genModel.setCodeFormatting(true); // Normalize layout + genModel.setForceOverwrite(false); // Don't overwrite read-only + // files + genModel.setCanGenerate(true); + // genModel.setFacadeHelperClass(null); // Non-null gives JDT + // default NPEs +// genModel.setFacadeHelperClass(ASTFacadeHelper.class.getName()); // Bug 308069 + // genModel.setValidateModel(true); +// genModel.setBundleManifest(false); // New manifests should be +// // generated manually +// genModel.setUpdateClasspath(false); // New class-paths should be +// // generated manually +// if (genModel.getComplianceLevel().compareTo(GenJDKLevel.JDK50_LITERAL) < 0) { +// genModel.setComplianceLevel(GenJDKLevel.JDK50_LITERAL); +// } + // genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"); + Diagnostic diagnostic = genModel.diagnose(); + reportDiagnostics(new Issues(), diagnostic); + + /* + * JavaModelManager.getJavaModelManager().initializePreferences(); + * new + * JavaCorePreferenceInitializer().initializeDefaultPreferences(); + * + * GenJDKLevel genSDKcomplianceLevel = + * genModel.getComplianceLevel(); String complianceLevel = + * JavaCore.VERSION_1_5; switch (genSDKcomplianceLevel) { case + * JDK60_LITERAL: complianceLevel = JavaCore.VERSION_1_6; case + * JDK14_LITERAL: complianceLevel = JavaCore.VERSION_1_4; default: + * complianceLevel = JavaCore.VERSION_1_5; } // Hashtable<?,?> + * defaultOptions = JavaCore.getDefaultOptions(); // + * JavaCore.setComplianceOptions(complianceLevel, defaultOptions); + * // JavaCore.setOptions(defaultOptions); + */ + +// Generator generator = new Generator(); +// generator.setInput(genModel); + Generator generator = GenModelUtil.createGenerator(genModel); + Monitor monitor = /*showProgress ? new LoggerMonitor(log) :*/ new BasicMonitor(); + diagnostic = generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, monitor); + reportDiagnostics(new Issues(), diagnostic); + } + /*public*/ @NonNull Transformation getCoreTransformation(@NonNull RelationalTransformation relationalTransformation) { return ClassUtil.nonNullState(relationalTransformation2coreTransformation.get(relationalTransformation)); } + /*public*/ @NonNull TypedModel getCoreTypedModel(@NonNull TypedModel relationTypedModel) { + return ClassUtil.nonNullState(relationalTypedModel2coreTypedModel.get(relationTypedModel)); + } + /* public @NonNull DomainPattern getDomainPattern(@NonNull Domain d) { List<@NonNull DomainPattern> pattern = ClassUtil.nullFree(((RelationDomain) d).getPattern()); assert pattern.size() == 1; @@ -286,49 +465,20 @@ public class QVTrToQVTc public @NonNull EnvironmentFactory getEnvironmentFactory() { return environmentFactory; } - - /*public*/ @NonNull Relation getInvokingRelationForRelationCallExp(@NonNull RelationCallExp rInvocation) { - return ClassUtil.nonNullState(rInvocation2invokingRelation.get(rInvocation)); - } - public @Nullable Key getKeyforType(@NonNull Type type) { - return class2key.get(type); + public @NonNull QVTcoreHelper getHelper() { + return helper; } - // TODO bug 453863 // ?? this is suspect for more than 2 domains. // FIXME What is 'shared'? a) any two domains b) output/any-input c) all domains - /** - * Return the variables that are used by more than one domain of the relation and so must be middle variables. - */ - public @NonNull Set<@NonNull Variable> getMiddleDomainVariables(@NonNull Relation rRelation) { - Set<@NonNull Variable> rDomainVariables = new HashSet<@NonNull Variable>(); - Set<@NonNull Variable> rMiddleDomainVariables = new HashSet<@NonNull Variable>(); - for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { - for (@NonNull DomainPattern rDomainPattern : ClassUtil.nullFree(((RelationDomain)rDomain).getPattern())) { - for (@NonNull Variable rVariable : ClassUtil.nullFree(rDomainPattern.getBindsTo())) { - if (!rDomainVariables.add(rVariable)) { - rMiddleDomainVariables.add(rVariable); // Accumulate second (and higher) usages - } - } - } - } - return rMiddleDomainVariables; + /*public*/ @NonNull Relation getInvokingRelation(@NonNull RelationCallExp rInvocation) { + Relation rRelation1 = ClassUtil.nonNullState(invocation2invokingRelation.get(rInvocation)); + Relation rRelation2 = (Relation) ((Predicate)rInvocation.eContainer()).getPattern().eContainer(); + assert rRelation1 == rRelation2; + return rRelation1; } - - private @NonNull Set<@NonNull Variable> getNestedBindToVariable(@NonNull ObjectTemplateExp ote) { - Set<@NonNull Variable> vars = new HashSet<@NonNull Variable>(); - for (PropertyTemplateItem p : ote.getPart()) { - OCLExpression e = p.getValue(); - assert e != null; - if (e instanceof ObjectTemplateExp) { - Variable bindsTo = ((ObjectTemplateExp)e).getBindsTo(); - assert bindsTo != null; - vars.add(bindsTo); - vars.addAll(getNestedBindToVariable((ObjectTemplateExp) e)); - } else { - vars.addAll(getVarsOfExp(e)); - } - } - return vars; + + public @Nullable Key getKeyForType(@NonNull Type type) { + return class2key.get(type); } public Predicate getPredicateForRelationCallExp(RelationCallExp ri) { @@ -345,6 +495,22 @@ public class QVTrToQVTc return trimFileExtension.segment(0); } } + + /** + * Return the property of aClass whose name corresponds to rNamedElement. + * @throws CompilerChainException if no such property + */ + protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { + return getProperty(aClass, rNamedElement.getName()); + } + protected @NonNull Property getProperty(/*@NonNull*/ Type aClass, /*@NonNull*/ String name) throws CompilerChainException { + assert (aClass != null) && (name != null); + CompleteClass completeClass = environmentFactory.getCompleteModel().getCompleteClass(aClass); + Property p = completeClass.getProperty(name); + if (p != null) + return p; + throw new CompilerChainException("No property '" + name + "' in '" + aClass + "::" + "'"); + } /** * @return the qvtcSource @@ -353,58 +519,33 @@ public class QVTrToQVTc return qvtcResource; } - public @NonNull List<@NonNull RelationCallExp> getRelationCallExpsForRelation(@NonNull Relation r) { - return ClassUtil.nonNullState(relationCallExpsForRelation.get(r)); + public @NonNull List<@NonNull RelationCallExp> getRelationCallExpsForRelation(@NonNull Relation relation) { + return ClassUtil.nonNullState(relation2invocations.get(relation)); } - - /* ============= Queries ============= */ - public @NonNull StandardLibrary getStandardLibrary() { - return environmentFactory.getStandardLibrary(); + public @NonNull List<@NonNull Variable> getRootVariables(@NonNull Relation relation) { + return ClassUtil.nonNullState(relation2rootVariables.get(relation)); } - /*public*/ @Nullable TemplateExp getTemplateExpression(@NonNull Variable dv) { - return variable2templateExp.get(dv); + public @NonNull StandardLibrary getStandardLibrary() { + return environmentFactory.getStandardLibrary(); } /*public*/ org.eclipse.ocl.pivot.@NonNull Class getTraceClass(@NonNull Relation relation) { - return ClassUtil.nonNullState(relationToTraceClass.get(relation)); + return ClassUtil.nonNullState(relation2traceClass.get(relation)); } /*public*/ org.eclipse.ocl.pivot.@NonNull Package getTracePackage(@NonNull RelationalTransformation relationalTransformation) { return ClassUtil.nonNullState(relationalTransformation2tracePackage.get(relationalTransformation)); } - - /* - * Get variables occurring in an OCL expression - */ - public @NonNull Set<@NonNull Variable> getVarsOfExp(@NonNull OCLExpression e) { - Set<@NonNull Variable> variables = new HashSet<@NonNull Variable>(); - for (EObject eObject : new TreeIterable(e, true)) { - if (eObject instanceof VariableExp) { - VariableDeclaration referredVariable = ((VariableExp)eObject).getReferredVariable(); - if (referredVariable instanceof Variable) { - variables.add((Variable)referredVariable); - } - } - else if (eObject instanceof Variable) { - variables.add((Variable)eObject); - } - else if (eObject instanceof TemplateExp) { - Variable bindsTo = ((TemplateExp)eObject).getBindsTo(); - if (bindsTo != null) { - variables.add(bindsTo); - } - if (eObject instanceof CollectionTemplateExp) { - Variable rest = ((CollectionTemplateExp)eObject).getRest(); - if (rest != null) { - variables.add(rest); - } - } - } + +/* public @NonNull Set<org.eclipse.ocl.pivot.@NonNull Class> getUsedClasses(@NonNull TypedModel rTypedModel) { + Set<org.eclipse.ocl.pivot.@NonNull Class> usedClasses = new HashSet<org.eclipse.ocl.pivot.@NonNull Class>(); + for (org.eclipse.ocl.pivot.@NonNull Package rPackage : ClassUtil.nullFree(rTypedModel.getUsedPackage())) { + usedClasses.addAll(ClassUtil.nullFree(rPackage.getOwnedClasses())); } - return variables; - } + return usedClasses; + } */ // Create the top rules, and search the input model for the appropriate types, when possible? public void prepare() { @@ -444,15 +585,22 @@ public class QVTrToQVTc // } } - /*public*/ void putRelationTrace(@NonNull Relation r, org.eclipse.ocl.pivot.@NonNull Class traceClass) { - relationToTraceClass.put(r, traceClass); + /*public*/ void putRelationTrace(@NonNull Relation rRelation, org.eclipse.ocl.pivot.@NonNull Class traceClass) { + org.eclipse.ocl.pivot.Class oldTraceClass = relation2traceClass.put(rRelation, traceClass); + assert oldTraceClass == null; // putTrace(traceClass, r); } /*public*/ void putTracePackage(@NonNull RelationalTransformation rt, org.eclipse.ocl.pivot.@NonNull Package tracePackage) { - relationalTransformation2tracePackage.put(rt, tracePackage); + org.eclipse.ocl.pivot.Package oldTracePackage = relationalTransformation2tracePackage.put(rt, tracePackage); + assert oldTracePackage == null; // putTrace(tracePackage, rt); } + + public void putTypedModel(@NonNull TypedModel relationTypedModel, @NonNull TypedModel coreTypedModel) { + TypedModel oldTypedModel = relationalTypedModel2coreTypedModel.put(relationTypedModel, coreTypedModel); + assert oldTypedModel == null; + } protected void reportDiagnostics(Issues issues, Diagnostic diagnostic) { int severity = diagnostic.getSeverity(); @@ -610,65 +758,6 @@ public class QVTrToQVTc return genModel; } - public void generateModels(@NonNull GenModel genModel) { - Registry generatorAdapterDescriptorRegistry = GeneratorAdapterFactory.Descriptor.Registry.INSTANCE; - if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(GenModelGeneratorAdapterFactory.DESCRIPTOR)) { - generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, GenModelGeneratorAdapterFactory.DESCRIPTOR); - } - if (!generatorAdapterDescriptorRegistry.getDescriptors(GenModelPackage.eNS_URI).contains(OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR)) { - generatorAdapterDescriptorRegistry.addDescriptor(GenModelPackage.eNS_URI, OCLinEcoreGeneratorAdapterFactory.DESCRIPTOR); - } -//** ResourceUtils.checkResourceSet(resourceSet); - // genModel.setCanGenerate(true); - // validate(); - - - - genModel.setValidateModel(true); // The more checks the better -// genModel.setCodeFormatting(true); // Normalize layout - genModel.setForceOverwrite(false); // Don't overwrite read-only - // files - genModel.setCanGenerate(true); - // genModel.setFacadeHelperClass(null); // Non-null gives JDT - // default NPEs -// genModel.setFacadeHelperClass(ASTFacadeHelper.class.getName()); // Bug 308069 - // genModel.setValidateModel(true); -// genModel.setBundleManifest(false); // New manifests should be -// // generated manually -// genModel.setUpdateClasspath(false); // New class-paths should be -// // generated manually -// if (genModel.getComplianceLevel().compareTo(GenJDKLevel.JDK50_LITERAL) < 0) { -// genModel.setComplianceLevel(GenJDKLevel.JDK50_LITERAL); -// } - // genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"); - Diagnostic diagnostic = genModel.diagnose(); - reportDiagnostics(new Issues(), diagnostic); - - /* - * JavaModelManager.getJavaModelManager().initializePreferences(); - * new - * JavaCorePreferenceInitializer().initializeDefaultPreferences(); - * - * GenJDKLevel genSDKcomplianceLevel = - * genModel.getComplianceLevel(); String complianceLevel = - * JavaCore.VERSION_1_5; switch (genSDKcomplianceLevel) { case - * JDK60_LITERAL: complianceLevel = JavaCore.VERSION_1_6; case - * JDK14_LITERAL: complianceLevel = JavaCore.VERSION_1_4; default: - * complianceLevel = JavaCore.VERSION_1_5; } // Hashtable<?,?> - * defaultOptions = JavaCore.getDefaultOptions(); // - * JavaCore.setComplianceOptions(complianceLevel, defaultOptions); - * // JavaCore.setOptions(defaultOptions); - */ - -// Generator generator = new Generator(); -// generator.setInput(genModel); - Generator generator = GenModelUtil.createGenerator(genModel); - Monitor monitor = /*showProgress ? new LoggerMonitor(log) :*/ new BasicMonitor(); - diagnostic = generator.generate(genModel, GenBaseGeneratorAdapter.MODEL_PROJECT_TYPE, monitor); - reportDiagnostics(new Issues(), diagnostic); - } - - public @NonNull Resource saveTrace(@NonNull Resource asResource, @NonNull URI traceURI, @NonNull URI genModelURI, @Nullable Map<@NonNull String, @Nullable String> traceOptions, @NonNull Map<?, ?> saveOptions) throws IOException { Model root = PivotFactory.eINSTANCE.createModel(); root.setExternalURI(traceURI.toString()); @@ -699,8 +788,7 @@ public class QVTrToQVTc externalURI = externalURI.replace(".qvtr", ".qvtcas"); } coreModel.setExternalURI(externalURI); - transformToCoreTransformations(ClassUtil.nullFree(coreModel.getOwnedPackages()), ClassUtil.nullFree(relationModel.getOwnedPackages())); -// CompilerUtil.normalizeNameables(coreTransformations); + transformToCoreTransformationHierarchy(ClassUtil.nullFree(coreModel.getOwnedPackages()), ClassUtil.nullFree(relationModel.getOwnedPackages())); } } List<@NonNull RelationalTransformation> relationalTransformations = new ArrayList<@NonNull RelationalTransformation>(relationalTransformation2coreTransformation.keySet()); @@ -708,13 +796,27 @@ public class QVTrToQVTc for (@NonNull RelationalTransformation relationalTransformation : relationalTransformations) { List<@NonNull Rule> rules = new ArrayList<@NonNull Rule>(ClassUtil.nullFree(relationalTransformation.getRule())); Collections.sort(rules, NameUtil.NAMEABLE_COMPARATOR); + Transformation coreTransformation = getCoreTransformation(relationalTransformation); + List<@NonNull TypedModel> rEnforceableTypdModels = new ArrayList<@NonNull TypedModel>(); + for (@NonNull Rule rule : rules) { + if (rule instanceof Relation) { + for (@NonNull Domain rDomain : ClassUtil.nullFree(rule.getDomain())) { + if (rDomain.isIsEnforceable()) { + TypedModel rTypedModel = ClassUtil.nonNullState(rDomain.getTypedModel()); + if (!rEnforceableTypdModels.contains(rTypedModel)) { + rEnforceableTypdModels.add(rTypedModel); + } + } + } + } + } for (@NonNull Rule rule : rules) { if (rule instanceof Relation) { Relation rRelation = (Relation)rule; if (rRelation.isIsTopLevel()) { QVTrToQVTc.SYNTHESIS.println("topLevel " + rRelation); TopLevelRelationToMappingForEnforcement topLevelRelationToMappingForEnforcement = new TopLevelRelationToMappingForEnforcement(this, rRelation); - topLevelRelationToMappingForEnforcement.doTopLevelRelationToMappingForEnforcement(); + topLevelRelationToMappingForEnforcement.transform(); } } } @@ -727,10 +829,11 @@ public class QVTrToQVTc Relation rRelation = (Relation)rule; if (!rRelation.isIsTopLevel()) { InvokedRelationToMappingForEnforcement invokedRelationToMappingForEnforcement = new InvokedRelationToMappingForEnforcement(this, rRelation); - invokedRelationToMappingForEnforcement.doInvokedRelationToMappingForEnforcement(); + invokedRelationToMappingForEnforcement.transform(); } } } + CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getRule())); } /* for (@NonNull Transformation coreTransformation : relationalTransformation2coreTransformation.values()) { List<DebugTraceBack> debugTraceBacks = coreTransformation.getOwnedDebugTraceBacks(); @@ -746,8 +849,7 @@ public class QVTrToQVTc } */ } - - private void transformToCoreTransformations(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> corePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) { + private void transformToCoreTransformationHierarchy(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> corePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) { for (org.eclipse.ocl.pivot.@NonNull Package relationPackage : relationPackages) { String name = relationPackage.getName(); assert name != null; @@ -758,23 +860,25 @@ public class QVTrToQVTc RelationalTransformationToMappingTransformation relationalTransformationToMappingTransformation = new RelationalTransformationToMappingTransformation(this); Transformation coreTransformation = relationalTransformationToMappingTransformation.doRelationalTransformationToMappingTransformation((RelationalTransformation)relationClass); corePackage.getOwnedClasses().add(coreTransformation); + CompilerUtil.normalizeNameables(ClassUtil.nullFree(coreTransformation.getRule())); } } - transformToCoreTransformations(ClassUtil.nullFree(corePackage.getOwnedPackages()), ClassUtil.nullFree(relationPackage.getOwnedPackages())); + CompilerUtil.normalizeNameables(ClassUtil.nullFree(corePackage.getOwnedClasses())); + transformToCoreTransformationHierarchy(ClassUtil.nullFree(corePackage.getOwnedPackages()), ClassUtil.nullFree(relationPackage.getOwnedPackages())); } } public @NonNull List<@NonNull Package> transformToTracePackages() { for (@NonNull EObject eObject : qvtrResource.getContents()) { if (eObject instanceof RelationModel) { - transformToTracePackages(tracePackages, ClassUtil.nullFree(((RelationModel)eObject).getOwnedPackages())); + transformToTracePackageHierarchy(tracePackages, ClassUtil.nullFree(((RelationModel)eObject).getOwnedPackages())); CompilerUtil.normalizeNameables(tracePackages); } } return tracePackages; } - private void transformToTracePackages(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> tracePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) { + private void transformToTracePackageHierarchy(@NonNull List<org.eclipse.ocl.pivot.@NonNull Package> tracePackages, @NonNull Iterable<org.eclipse.ocl.pivot.@NonNull Package> relationPackages) { for (org.eclipse.ocl.pivot.@NonNull Package relationPackage : relationPackages) { for (org.eclipse.ocl.pivot.@NonNull Class relationClass : ClassUtil.nullFree(relationPackage.getOwnedClasses())) { if (relationClass instanceof RelationalTransformation) { @@ -783,59 +887,9 @@ public class QVTrToQVTc tracePackages.add(tracePackage); } } - transformToTracePackages(tracePackages, ClassUtil.nullFree(relationPackage.getOwnedPackages())); + transformToTracePackageHierarchy(tracePackages, ClassUtil.nullFree(relationPackage.getOwnedPackages())); } } - - /** - * Lazily create the name CoreDomain for a coreRule. - */ - /*public*/ @NonNull CoreDomain whenCoreDomain(@NonNull Rule coreRule, @NonNull String name) { - Map<@NonNull String, @NonNull CoreDomain> name2coreDomain = rule2name2coreDomain.get(coreRule); - if (name2coreDomain == null) { - name2coreDomain = new HashMap<@NonNull String, @NonNull CoreDomain>(); - rule2name2coreDomain.put(coreRule, name2coreDomain); - } - CoreDomain coreDomain = name2coreDomain.get(name); - if (coreDomain == null) { - coreDomain = QVTcoreBaseFactory.eINSTANCE.createCoreDomain(); - coreDomain.setName(name); - coreDomain.setRule(coreRule); - name2coreDomain.put(name, coreDomain); -// putTrace(coreDomain, coreRule); - GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern(); - coreDomain.setGuardPattern(guardPattern); -// putTrace(guardPattern, coreRule); - BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern(); - coreDomain.setBottomPattern(bottomPattern); -// putTrace(bottomPattern, coreRule); - } - return coreDomain; - } - - /** - * Lazily create the name Mapping for a coreTransformation. - */ - /*public*/ @NonNull Mapping whenMapping(@NonNull Relation relation, @NonNull String name) { - RelationalTransformation rt = (RelationalTransformation) relation.getTransformation(); - assert rt != null; - @NonNull Transformation coreTransformation = getCoreTransformation(rt); - Map<@NonNull String, @NonNull Mapping> name2mapping = transformation2name2mapping.get(coreTransformation); - if (name2mapping == null) { - name2mapping = new HashMap<@NonNull String, @NonNull Mapping>(); - transformation2name2mapping.put(coreTransformation, name2mapping); - } - Mapping coreMapping = name2mapping.get(name); - if (coreMapping == null) { - coreMapping = createMapping(); - putGlobalTrace(coreMapping, relation); - coreMapping.setName(name); - coreMapping.setTransformation(coreTransformation); - name2mapping.put(name, coreMapping); - } - return coreMapping; - } - /** * Lazily create the name Property for a traceClass with a type. */ diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToMappingTransformation.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToMappingTransformation.java index 1466f52b6..94e89720e 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToMappingTransformation.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToMappingTransformation.java @@ -28,6 +28,14 @@ import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation; public RelationalTransformationToMappingTransformation(@NonNull QVTrToQVTc qvtr2qvtc) { this.qvtr2qvtc = qvtr2qvtc; } + + private @NonNull TypedModel createTypedModel(@NonNull Transformation coreTransformation, @Nullable String name, @NonNull List<org.eclipse.ocl.pivot.@NonNull Package> usedPackages) { + TypedModel coreTypedModel = QVTbaseFactory.eINSTANCE.createTypedModel(); + coreTypedModel.setName(name); + coreTypedModel.getUsedPackage().addAll(usedPackages); + coreTransformation.getModelParameter().add(coreTypedModel); + return coreTypedModel; + } public @NonNull Transformation doRelationalTransformationToMappingTransformation(@NonNull RelationalTransformation relationalTransformation) { // @@ -45,16 +53,9 @@ import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation; // Create a non-middle TypedModel per model parameter // for (@NonNull TypedModel relationTypedModel : ClassUtil.nullFree(relationalTransformation.getModelParameter())) { - createTypedModel(coreTransformation, relationTypedModel.getName(), ClassUtil.nullFree(relationTypedModel.getUsedPackage())); + TypedModel coreTypedModel = createTypedModel(coreTransformation, relationTypedModel.getName(), ClassUtil.nullFree(relationTypedModel.getUsedPackage())); + qvtr2qvtc.putTypedModel(relationTypedModel, coreTypedModel); } return coreTransformation; } - - private @NonNull TypedModel createTypedModel(@NonNull Transformation coreTransformation, @Nullable String name, @NonNull List<org.eclipse.ocl.pivot.@NonNull Package> usedPackages) { - TypedModel coreTypedModel = QVTbaseFactory.eINSTANCE.createTypedModel(); - coreTypedModel.setName(name); - coreTypedModel.getUsedPackage().addAll(usedPackages); - coreTransformation.getModelParameter().add(coreTypedModel); - return coreTypedModel; - } } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToTracePackage.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToTracePackage.java index 24977a84e..cb9c4076c 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToTracePackage.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/RelationalTransformationToTracePackage.java @@ -17,6 +17,7 @@ import org.eclipse.ocl.pivot.CollectionType; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Type; +import org.eclipse.ocl.pivot.TypedElement; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.internal.utilities.CompilerUtil; @@ -39,16 +40,16 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; this.qvtr2qvtc = qvtr2qvtc; } - public org.eclipse.ocl.pivot.@NonNull Package doRelationalTransformationToTracePackage(@NonNull RelationalTransformation rt) { + public org.eclipse.ocl.pivot.@NonNull Package doRelationalTransformationToTracePackage(@NonNull RelationalTransformation rTransformation) { org.eclipse.ocl.pivot.Package p = PivotFactory.eINSTANCE.createPackage(); - p.setName("P" + rt.getName()); - p.setNsPrefix("P" + rt.getName()); + p.setName("P" + rTransformation.getName()); + p.setNsPrefix("P" + rTransformation.getName()); // p.setURI(p.getName()); - qvtr2qvtc.putTracePackage(rt, p); + qvtr2qvtc.putTracePackage(rTransformation, p); List<org.eclipse.ocl.pivot.@NonNull Class> ownedClasses = ClassUtil.nullFree(p.getOwnedClasses()); - for (@NonNull Rule r : ClassUtil.nullFree(rt.getRule())) { - if (r instanceof Relation) { - ownedClasses.add(doRelationToTraceClass((Relation)r)); + for (@NonNull Rule rRule : ClassUtil.nullFree(rTransformation.getRule())) { + if (rRule instanceof Relation) { + ownedClasses.add(doRelationToTraceClass((Relation)rRule)); } } CompilerUtil.normalizeNameables(ownedClasses); @@ -59,7 +60,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; @SuppressWarnings("null")org.eclipse.ocl.pivot.@NonNull Class traceClass = PivotFactory.eINSTANCE.createClass(); qvtr2qvtc.putRelationTrace(rRelation, traceClass); traceClass.setName("T" + rRelation.getName()); - for (@NonNull Variable rVariable : qvtr2qvtc.getMiddleDomainVariables(rRelation)) { + for (@NonNull Variable rVariable : VariablesAnalysis.getMiddleDomainVariables(rRelation)) { createTraceProperty(traceClass, rVariable); } for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { @@ -107,7 +108,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; } } - private void createTraceProperty(org.eclipse.ocl.pivot.@NonNull Class rc, @NonNull Variable tv) { + private void createTraceProperty(org.eclipse.ocl.pivot.@NonNull Class rc, @NonNull TypedElement tv) { String vn = ClassUtil.nonNullState(tv.getName()); Type c = ClassUtil.nonNullState(tv.getType()); qvtr2qvtc.whenTraceProperty(rc, vn, c, tv.isIsRequired()); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/TopLevelRelationToMappingForEnforcement.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/TopLevelRelationToMappingForEnforcement.java index 22787eef3..1855d82ee 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/TopLevelRelationToMappingForEnforcement.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/TopLevelRelationToMappingForEnforcement.java @@ -20,17 +20,13 @@ import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.CompilerChainException; import org.eclipse.qvtd.pivot.qvtbase.Domain; -import org.eclipse.qvtd.pivot.qvtbase.Predicate; import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable; -import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern; import org.eclipse.qvtd.pivot.qvtrelation.Relation; import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; -import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp; -import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; /*public*/ class TopLevelRelationToMappingForEnforcement extends AbstractQVTr2QVTcRelations { - private class TopEnforceableRelationDomain2CoreMapping extends AbstractEnforceableRelationDomain2CoreMapping + protected class TopEnforceableRelationDomain2CoreMapping extends AbstractEnforceableRelationDomain2CoreMapping { protected class TopOtherRelationDomain2CoreDomain extends AbstractOtherRelationDomain2CoreDomain { @@ -38,57 +34,51 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; super(rOtherDomain); } - // body of TROppositeDomainsToMappingForEnforcement +/* // body of TROppositeDomainsToMappingForEnforcement @Override - public void mapOtherDomainToDomainVariablesAndPatterns() throws CompilerChainException { -// cOtherDomain.setGuardPattern(cOtherGuardPattern); // FIXME redundant - for (@NonNull DomainPattern rOtherDomainPattern : ClassUtil.nullFree(rOtherDomain.getPattern())) { - List<@NonNull Variable> rOtherDomainVariables = ClassUtil.nullFree(rOtherDomainPattern.getBindsTo()); - TemplateExp rOtherTemplateExpression = rOtherDomainPattern.getTemplateExpression(); - Variable rOtherRootVariable = ClassUtil.nonNullState(rOtherTemplateExpression.getBindsTo()); -// if (rOtherTemplateExpression instanceof ObjectTemplateExp) { -// ObjectTemplateExp rOtherObjectTemplateExpression = (ObjectTemplateExp)rOtherTemplateExpression; - Set<@NonNull Variable> rOtherGuardDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rOtherGuardDomainVariables.retainAll(rWhenVariables); - rOtherGuardDomainVariables.add(rOtherRootVariable); - rOtherGuardDomainVariables.removeAll(rSharedVariables); -// rOtherGuardDomainVariables.removeAll(rNonUniquePatternVariables); - // - Set<@NonNull Variable> rOtherBottomDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rOtherBottomDomainVariables.removeAll(rWhenVariables); - rOtherBottomDomainVariables.removeAll(rSharedVariables); -// rOtherBottomDomainVariables.removeAll(rNonUniquePatternVariables); - rOtherBottomDomainVariables.remove(rOtherRootVariable); - // - Set<@NonNull Variable> rMiddleBottomDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); - rMiddleBottomDomainVariables.removeAll(rWhenVariables); - rMiddleBottomDomainVariables.retainAll(rSharedVariables); -// rMiddleBottomDomainVariables.removeAll(rNonUniquePatternVariables); - rMiddleBottomDomainVariables.remove(rOtherRootVariable); - // - mapVariablesToVariables(rOtherGuardDomainVariables, cOtherGuardPattern); - mapVariablesToVariables(rOtherBottomDomainVariables, cOtherBottomPattern); - mapVariablesToVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern); - addTemplateExpressionToMiddleBottom(rOtherTemplateExpression); -// } -// else { -// throw new CompilerChainException("Missing doTROppositeDomainsToMappingForEnforcement support for CollectionTemplateExp"); -// } - } - } + public void synthesize() throws CompilerChainException { // FIXME unify with Invoked +// for (@NonNull DomainPattern rOtherDomainPattern : ClassUtil.nullFree(rOtherDomain.getPattern())) { +// List<@NonNull Variable> rOtherDomainVariables = ClassUtil.nullFree(rOtherDomainPattern.getBindsTo()); +// TemplateExp rOtherTemplateExpression = rOtherDomainPattern.getTemplateExpression(); +// Variable rOtherRootVariable = ClassUtil.nonNullState(rOtherTemplateExpression.getBindsTo()); +// Set<@NonNull Variable> rOtherGuardDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rOtherGuardDomainVariables.retainAll(rWhenVariables); +// rOtherGuardDomainVariables.add(rOtherRootVariable); +// rOtherGuardDomainVariables.removeAll(rSharedVariables); + // +// Set<@NonNull Variable> rOtherBottomDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rOtherBottomDomainVariables.removeAll(rWhenVariables); +// rOtherBottomDomainVariables.removeAll(rSharedVariables); +// rOtherBottomDomainVariables.remove(rOtherRootVariable); + // +// Set<@NonNull Variable> rMiddleBottomDomainVariables = new HashSet<@NonNull Variable>(rOtherDomainVariables); +// rMiddleBottomDomainVariables.removeAll(rWhenVariables); +// rMiddleBottomDomainVariables.retainAll(rSharedVariables); +// rMiddleBottomDomainVariables.remove(rOtherRootVariable); + // +// mapVariables(rOtherGuardDomainVariables, cOtherGuardPattern); +// mapVariables(rOtherBottomDomainVariables, cOtherBottomPattern); +// mapVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern); +// } + // + super.synthesize(); + } */ } private @NonNull List<@NonNull RealizedVariable> cEnforcedRootVariables; // The mapping template expression variables (the realized variable enforced by the domain pattern) // except when arguments - public TopEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) { + public TopEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) throws CompilerChainException { super(rEnforcedDomain, cMappingName); this.cEnforcedRootVariables = new ArrayList<@NonNull RealizedVariable>(rEnforcedRootVariables.size()); - for (@NonNull Variable rEnforcedRootVariable : rEnforcedRootVariables) { +/* for (@NonNull Variable rEnforcedRootVariable : rEnforcedRootVariables) { if (!rWhenVariables.contains(rEnforcedRootVariable)) { - this.cEnforcedRootVariables.add(mapRealizedVariable(rEnforcedRootVariable)); + Variable realizedVariable = mapRealizedVariable(rEnforcedRootVariable); + if (realizedVariable instanceof RealizedVariable) { // FIXME not a RealizedVariable if keyed + this.cEnforcedRootVariables.add((RealizedVariable)realizedVariable); + } } - } + } */ } @Override @@ -97,42 +87,29 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; } @Override - protected void setAttributes() { - super.setAttributes(); - cEnforcedBottomPattern.getRealizedVariable().addAll(cEnforcedRootVariables); - } - - @Override - protected void where() throws CompilerChainException { - Set<@NonNull Variable> rEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedDomainVariables); + protected @NonNull Set<@NonNull Variable> getEnforcedBottomDomainVariables() { // FIXME unify with Invoked + Set<@NonNull Variable> rEnforcedBottomDomainVariables = new HashSet<@NonNull Variable>(rEnforcedReferredVariables); rEnforcedBottomDomainVariables.removeAll(rWhenVariables); rEnforcedBottomDomainVariables.removeAll(rSharedVariables); -// rEnforcedBottomDomainVariables.removeAll(rNonUniquePatternVariables); - // - Set<@NonNull Predicate> rPredicatesWithVariableBindings = selectPredicatesThatReferToVariables(rPredicates, rEnforcedBottomDomainVariables); - Set<@NonNull Predicate> rPredicatesWithoutVariableBindings = new HashSet<@NonNull Predicate>(rPredicates); - rPredicatesWithoutVariableBindings.removeAll(rPredicatesWithVariableBindings); - // - Set<@NonNull Variable> rEnforcedDomainGuardVariables = new HashSet<@NonNull Variable>(rEnforcedDomainVariables); + return rEnforcedBottomDomainVariables; + } + +/* @Override + protected @NonNull Set<@NonNull Variable> getEnforcedDomainGuardVariables(@NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) { // FIXME unify with Invoked + Set<@NonNull Variable> rEnforcedDomainGuardVariables = new HashSet<@NonNull Variable>(rEnforcedReferredVariables); rEnforcedDomainGuardVariables.retainAll(rWhenVariables); rEnforcedBottomDomainVariables.removeAll(rSharedVariables); -// rEnforcedBottomDomainVariables.removeAll(rNonUniquePatternVariables); // List<@NonNull Variable> nonWhenRootVariables2 = rEnforcedRootVariables; nonWhenRootVariables2.removeAll(rWhenVariables); rEnforcedDomainGuardVariables.remove(nonWhenRootVariables2); // This fixes Bug 486636 - // Relation Calls - mapPredicatesToPredicates(rPredicatesWithVariableBindings); - mapVariablesToVariables(rEnforcedDomainGuardVariables, cEnforcedGuardPattern); - mapVariablesToVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern); - for (@NonNull AbstractOtherRelationDomain2CoreDomain otherDomain2coreDomain : otherDomain2coreDomains) { - otherDomain2coreDomain.mapOtherDomainToDomainVariablesAndPatterns(); - } - // Invoked here so the variables are instantiated - mapDomainVariablesToMiddleVariableAssignments(rOtherDomainVariables); - mapWhenPatternToGuardPatterns(); - mapEnforcedDomain(rPredicatesWithoutVariableBindings, rEnforcedBottomDomainVariables); - mapRelationImplementationToEnforcementOperation(); + return rEnforcedDomainGuardVariables; + } */ + + @Override + protected void synthesize() throws CompilerChainException { + super.synthesize(); + cEnforcedBottomPattern.getRealizedVariable().addAll(cEnforcedRootVariables); // FIXME redundant ?? } } @@ -141,32 +118,20 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; assert rRelation.isIsTopLevel(); } - public void doTopLevelRelationToMappingForEnforcement() throws CompilerChainException { - // check - @NonNull List<@NonNull TopEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = new ArrayList<@NonNull TopEnforceableRelationDomain2CoreMapping>(); + /** + * Each enforced domain is synthesized as a separate mapping. + */ + @Override + protected @NonNull List<@NonNull TopEnforceableRelationDomain2CoreMapping> analyze() throws CompilerChainException { + List<@NonNull TopEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = new ArrayList<@NonNull TopEnforceableRelationDomain2CoreMapping>(); for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { if (rDomain.isIsEnforceable()) { RelationDomain rEnforcedDomain = (RelationDomain)rDomain; - for (@NonNull DomainPattern rEnforcedPattern : ClassUtil.nullFree(rEnforcedDomain.getPattern())) { - TemplateExp rEnforcedTemplateExpression = rEnforcedPattern.getTemplateExpression(); - if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) { - enforceableRelationDomain2coreMappings.add(new TopEnforceableRelationDomain2CoreMapping(rEnforcedDomain, getCoreMappingName(rEnforcedDomain))); - break; - } - else { - throw new CompilerChainException("Missing doTopLevelRelationToMappingForEnforcement support for CollectionTemplateExp"); - } - } + String rEnforcedDomainName = ClassUtil.nonNullState(rEnforcedDomain.getName()); + String coreMappingName = rRelationName + '_' + rEnforcedDomainName; + enforceableRelationDomain2coreMappings.add(new TopEnforceableRelationDomain2CoreMapping(rEnforcedDomain, coreMappingName)); } } - // where() { - where(rRelation, enforceableRelationDomain2coreMappings); - } - - private @NonNull String getCoreMappingName(@NonNull RelationDomain rEnforcedDomain) { - @NonNull String rRelationName = ClassUtil.nonNullState(rRelation.getName()); - @NonNull String rEnforcedDomainName = ClassUtil.nonNullState(rEnforcedDomain.getName()); - return rRelationName + '_' + rEnforcedDomainName; + return enforceableRelationDomain2coreMappings; } - } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java new file mode 100644 index 000000000..ccd8b6e6e --- /dev/null +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/VariablesAnalysis.java @@ -0,0 +1,379 @@ +/******************************************************************************* + * Copyright (c) 2014, 2015 The University of York and Willink Transformations. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Horacio Hoyos - initial API and implementation + ******************************************************************************/ +package org.eclipse.qvtd.compiler.internal.qvtr2qvtc; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.ocl.pivot.Element; +import org.eclipse.ocl.pivot.Type; +import org.eclipse.ocl.pivot.Variable; +import org.eclipse.ocl.pivot.VariableDeclaration; +import org.eclipse.ocl.pivot.VariableExp; +import org.eclipse.ocl.pivot.utilities.ClassUtil; +import org.eclipse.qvtd.pivot.qvtbase.Domain; +import org.eclipse.qvtd.pivot.qvtbase.utilities.TreeIterable; +import org.eclipse.qvtd.pivot.qvtcore.Mapping; +import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper; +import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil; +import org.eclipse.qvtd.pivot.qvtcorebase.Area; +import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern; +import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain; +import org.eclipse.qvtd.pivot.qvtcorebase.CorePattern; +import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable; +import org.eclipse.qvtd.pivot.qvtrelation.Relation; +import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp; +import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; + +/** + * VariablesAnalysis manages all the variables in use by a Relation and its corresponding Mapping. + */ +/*public*/ class VariablesAnalysis extends QVTcoreHelper +{ + /** + * Return all variables bound to a single variable within the composition tree of each of asRoots. + */ + public static void gatherBoundVariables(@NonNull Set<@NonNull Variable> boundVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) { + for (Element asRoot : asRoots) { + gatherBoundVariables(boundVariables, asRoot); + } + } + public static void gatherBoundVariables(@NonNull Set<@NonNull Variable> boundVariables, @NonNull Element asRoot) { + for (EObject eObject : new TreeIterable(asRoot, true)) { + if (eObject instanceof TemplateExp) { + Variable bindsTo = ((TemplateExp)eObject).getBindsTo(); // ?? CollectionTemplateExp collection is not bound + if (bindsTo != null) { + boundVariables.add(bindsTo); + } + if (eObject instanceof CollectionTemplateExp) { // ?? VariableExp members are bound + Variable rest = ((CollectionTemplateExp)eObject).getRest(); // ?? not bound + if (rest != null) { + boundVariables.add(rest); + } + } + } + } + } + + /** + * Return all variables referenced within the composition tree of each of asRoots. + */ + public static void gatherReferredVariables(@NonNull Set<@NonNull Variable> referredVariables, @NonNull Iterable<@NonNull ? extends Element> asRoots) { + for (Element asRoot : asRoots) { + gatherReferredVariables(referredVariables, asRoot); + } + } + public static void gatherReferredVariables(@NonNull Set<@NonNull Variable> referredVariables, @NonNull Element asRoot) { + for (EObject eObject : new TreeIterable(asRoot, true)) { + if (eObject instanceof VariableExp) { + VariableDeclaration referredVariable = ((VariableExp)eObject).getReferredVariable(); + if (referredVariable instanceof Variable) { + referredVariables.add((Variable)referredVariable); + } + } + else if (eObject instanceof Variable) { + referredVariables.add((Variable)eObject); + } + else if (eObject instanceof TemplateExp) { + Variable bindsTo = ((TemplateExp)eObject).getBindsTo(); + if (bindsTo != null) { + referredVariables.add(bindsTo); + } + if (eObject instanceof CollectionTemplateExp) { + Variable rest = ((CollectionTemplateExp)eObject).getRest(); + if (rest != null) { + referredVariables.add(rest); + } + } + } + } + } + // TODO bug 453863 // ?? this is suspect for more than 2 domains. // FIXME What is 'shared'? a) any two domains b) output/any-input c) all domains + /** + * Return the variables that are used by more than one domain of the relation and so must be middle variables. + */ + public static @NonNull Set<@NonNull Variable> getMiddleDomainVariables(@NonNull Relation rRelation) { + Set<@NonNull Variable> rSomeDomainVariables = new HashSet<@NonNull Variable>(); + Set<@NonNull Variable> rMiddleDomainVariables = new HashSet<@NonNull Variable>(); + for (@NonNull Domain rDomain : ClassUtil.nullFree(rRelation.getDomain())) { + Set<@NonNull Variable> rThisDomainVariables = new HashSet<@NonNull Variable>(); + VariablesAnalysis.gatherReferredVariables(rThisDomainVariables, rDomain); + for (@NonNull Variable rVariable : rThisDomainVariables) { + if (!rSomeDomainVariables.add(rVariable)) { + rMiddleDomainVariables.add(rVariable); // Accumulate second (and higher) usages + } + } + } + return rMiddleDomainVariables; + } + + /** + * A VariableAnalysis accumulates the usage of a relation varaible and eventually synthesizes an appropriate core variable. + */ + protected class VariableAnalysis + { + protected final @NonNull Variable rVariable; + protected final @NonNull String name; + + private boolean isEnforcedBound = false; + private boolean isEnforcedReferred = false; + private @Nullable CoreDomain otherBound = null; + private boolean isOtherReferred = false; + private boolean isRoot = false; + private boolean isWhen = false; + private boolean isWhere = false; + private @Nullable Variable cVariable; + + private VariableAnalysis(@NonNull Variable rVariable) { + this.rVariable = rVariable; + this.name = getUniqueVariableName(ClassUtil.nonNullState(rVariable.getName()), this); + } + + public @Nullable RealizedVariable basicGetCoreRealizedVariable() { + return (RealizedVariable)cVariable; + } + + public @Nullable Variable basicGetCoreVariable() { + return cVariable; + } + + public void check() { + if (cVariable == null) { + System.err.println("No cVariable for " + this); + return; + } + CorePattern cPattern = getCorePattern(); + boolean isRealized = isRealized(); + assert (cVariable != null) && (cVariable.eContainer() == cPattern); + assert (cVariable instanceof RealizedVariable) == isRealized; + } + +// public @NonNull TemplateExp getTemplateExp() { +// return ClassUtil.nonNullState(rTemplateExp); +// } + + private @NonNull CorePattern getCorePattern() { + Area cArea = null; + boolean isGuard = false; + if (isWhen) { + isGuard = true; + assert isEnforcedBound || (otherBound != null); + cArea = isEnforcedBound ? cEnforcedDomain : otherBound; + } +// else if (isWhere) { +// } + else if (isEnforcedBound) { + isGuard = false; + cArea = cEnforcedDomain; + } + else if (otherBound != null) { + isGuard = isRoot; + cArea = otherBound; + } + else if (isEnforcedReferred && isOtherReferred) { + isGuard = false; + cArea = cMapping; + } + assert cArea != null; + return ClassUtil.nonNullState(isGuard ? cArea.getGuardPattern() : cArea.getBottomPattern()); + } + + public @NonNull Variable getCoreVariable() { + return ClassUtil.nonNullState(cVariable); + } + + public @NonNull Variable getRelationVariable() { + return rVariable; + } + + private boolean isRealized() { + boolean isRealized = false; + if (isWhen) { + } +// else if (isWhere) { +// } + else if (isEnforcedBound) { + isRealized = true; + } + return isRealized; + } + + public void setIsEnforcedBound() { + assert !isEnforcedBound; + assert this.otherBound == null; + this.isEnforcedBound = true; + } + + public void setIsEnforcedReferred() { + this.isEnforcedReferred = true; + } + + public void setIsRoot() { + this.isRoot = true; + } + + public void setIsWhen() { + this.isWhen = true; + } + + public void setIsWhere() { + this.isWhere = true; + } + + public void setOtherBound(@NonNull CoreDomain otherDomain) { + assert !isEnforcedBound; + assert this.otherBound == null; + this.otherBound = otherDomain; + } + + public void setOtherReferred(@NonNull CoreDomain otherDomain) { + this.isOtherReferred = true; + } + + public @NonNull Variable synthesize() { + CorePattern cPattern = getCorePattern(); + boolean isRealized = isRealized(); + // + Variable cVariable2 = cVariable; + assert cVariable2 == null; + Type type = ClassUtil.nonNullState(rVariable.getType()); + if (isRealized) { + RealizedVariable cRealizedVariable = createRealizedVariable(name, type); + ((BottomPattern)cPattern).getRealizedVariable().add(cRealizedVariable); + cVariable = cVariable2 = cRealizedVariable; + } + else { + cVariable = cVariable2 = createVariable(name, type, rVariable.isIsRequired(), null); + cPattern.getVariable().add(cVariable2); + } + return cVariable2; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append(rVariable.toString()); + if (isWhen) { + s.append(" WHEN"); + } + if (isWhere) { + s.append(" WHERE"); + } + if (isRoot) { + s.append(" ROOT"); + } + if (isEnforcedBound) { + s.append(" ENFORCED"); + } + else if (isEnforcedReferred) { + s.append(" enforced"); + } + if (otherBound != null) { + s.append(" OTHER"); + } + else if (isOtherReferred) { + s.append(" other"); + } + return s.toString(); + } + } + + protected final @NonNull CoreDomain cEnforcedDomain; // md: The resultant enforced domain + protected final @NonNull Mapping cMapping; // m: The resultant mapping + + /** + * Map from the each core variable name in use to an originating object, typically the VariableAnalysis of a relation variable, + * but the RElationCallExp of a where, the invoking relation of a call-from invocation, or this for the middle variable. + */ + private @NonNull Map<@NonNull String, @NonNull Object> name2originator = new HashMap<@NonNull String, @NonNull Object>(); + + /** + * The analysis of each relation variable. + */ + private final @NonNull Map<@NonNull Variable, @NonNull VariableAnalysis> rVariable2analysis = new HashMap<@NonNull Variable, @NonNull VariableAnalysis>(); + + public VariablesAnalysis(@NonNull QVTrToQVTc qvtr2qvtc, @NonNull CoreDomain cEnforcedDomain) { + super(qvtr2qvtc.getEnvironmentFactory()); + this.cEnforcedDomain = cEnforcedDomain; + this.cMapping = ClassUtil.nonNullState(QVTcoreUtil.getContainingMapping(cEnforcedDomain)); + } + + public void check() { + for (@NonNull VariableAnalysis analysis : rVariable2analysis.values()) { + analysis.check(); + } + } + + /** + * Create a core Variable with a name and type in the middle guard pattern. The variable has no corresponding relation variable. + * @param originator + */ + public @NonNull Variable createCoreOnlyVariable(@NonNull String name, @NonNull Type type, @NonNull Element originator) { + String uniqueName = getUniqueVariableName(name, originator); + return createVariable(uniqueName, type, true, null); + } + + public @NonNull Iterable<@NonNull VariableAnalysis> getAnalyses() { + return rVariable2analysis.values(); + } + + public @NonNull Variable getCoreVariable(@NonNull Variable rVariable) { // doRVarToMVar + return getVariableAnalysis(rVariable).getCoreVariable(); + } + + public @NonNull String getUniqueVariableName(@NonNull String name, @NonNull Object originator) { + Object oldOriginator = name2originator.get(name); + if (oldOriginator != null) { + assert oldOriginator != originator; // Lazy re-creation should not occur. + for (int i = 0; true; i++) { + String newName = name + "_" + i; + if (!name2originator.containsKey(newName)) { + name = newName; + break; + } + } + } + name2originator.put(name, originator); + return name; + } + + protected @NonNull VariableAnalysis getVariableAnalysis(@NonNull Variable relationVariable) { + VariableAnalysis analysis = rVariable2analysis.get(relationVariable); + if (analysis == null) { + analysis = new VariableAnalysis(relationVariable); + rVariable2analysis.put(relationVariable, analysis); + } + return analysis; + } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + List<@NonNull String> names = new ArrayList<@NonNull String>(name2originator.keySet()); + Collections.sort(names); + for (@NonNull String name : names) { + if (s.length() > 0) { + s.append("\n"); + } + s.append(name + " => " ); + s.append(name2originator.get(name)); + } + return s.toString(); + } +} diff --git a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java index 27381f6e7..324f8d499 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtbase/src/org/eclipse/qvtd/pivot/qvtbase/utilities/QVTbaseHelper.java @@ -400,6 +400,16 @@ public class QVTbaseHelper // FIXME extends PivotHelper return asVariable; } + public @NonNull Variable createVariable(@NonNull String name, @NonNull Type asType, boolean isRequired, @Nullable OCLExpression asInitExpression) { + Variable asVariable = PivotUtil.createVariable(name, asType, isRequired, asInitExpression); + return asVariable; + } + + public @NonNull Variable createVariable(@NonNull TypedElement typedElement) { + Variable asVariable = PivotUtil.createVariable(typedElement.getName(), typedElement.getType(), typedElement.isIsRequired(), null); + return asVariable; + } + public @NonNull VariableExp createVariableExp(@NonNull Variable asVariable) { VariableExp asVariableExp = PivotUtil.createVariableExp(asVariable); return asVariableExp; diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java index 7c25d809f..7b15bab68 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtcore/src/org/eclipse/qvtd/pivot/qvtcore/utilities/QVTcoreHelper.java @@ -11,7 +11,13 @@ package org.eclipse.qvtd.pivot.qvtcore.utilities; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.utilities.EnvironmentFactory; +import org.eclipse.qvtd.pivot.qvtcore.Mapping; +import org.eclipse.qvtd.pivot.qvtcore.QVTcoreFactory; +import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern; +import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern; +import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory; import org.eclipse.qvtd.pivot.qvtcorebase.utilities.QVTcoreBaseHelper; /** @@ -22,4 +28,14 @@ public class QVTcoreHelper extends QVTcoreBaseHelper public QVTcoreHelper(@NonNull EnvironmentFactory environmentFactory) { super(environmentFactory); } + + public @NonNull Mapping createMapping(@Nullable String name) { + Mapping coreMapping = QVTcoreFactory.eINSTANCE.createMapping(); + coreMapping.setName(name); + GuardPattern guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern(); + coreMapping.setGuardPattern(guardPattern); + BottomPattern bottomPattern = QVTcoreBaseFactory.eINSTANCE.createBottomPattern(); + coreMapping.setBottomPattern(bottomPattern); + return coreMapping; + } }
\ No newline at end of file diff --git a/plugins/org.eclipse.qvtd.pivot.qvtcorebase/src/org/eclipse/qvtd/pivot/qvtcorebase/utilities/QVTcoreBaseHelper.java b/plugins/org.eclipse.qvtd.pivot.qvtcorebase/src/org/eclipse/qvtd/pivot/qvtcorebase/utilities/QVTcoreBaseHelper.java index 420169fc5..c84c2fbc1 100644 --- a/plugins/org.eclipse.qvtd.pivot.qvtcorebase/src/org/eclipse/qvtd/pivot/qvtcorebase/utilities/QVTcoreBaseHelper.java +++ b/plugins/org.eclipse.qvtd.pivot.qvtcorebase/src/org/eclipse/qvtd/pivot/qvtcorebase/utilities/QVTcoreBaseHelper.java @@ -13,6 +13,7 @@ package org.eclipse.qvtd.pivot.qvtcorebase.utilities; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.Property; +import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.Variable; import org.eclipse.ocl.pivot.utilities.EnvironmentFactory; import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseHelper; @@ -20,6 +21,7 @@ import org.eclipse.qvtd.pivot.qvtcorebase.NavigationAssignment; import org.eclipse.qvtd.pivot.qvtcorebase.OppositePropertyAssignment; import org.eclipse.qvtd.pivot.qvtcorebase.PropertyAssignment; import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory; +import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable; import org.eclipse.qvtd.pivot.qvtcorebase.VariableAssignment; /** @@ -48,6 +50,14 @@ public class QVTcoreBaseHelper extends QVTbaseHelper return asNavigationAssignment; } + public @NonNull RealizedVariable createRealizedVariable(@NonNull String name, @NonNull Type type) { + RealizedVariable realizedVariable = QVTcoreBaseFactory.eINSTANCE.createRealizedVariable(); + realizedVariable.setName(name); + realizedVariable.setType(type); + realizedVariable.setIsRequired(true);; + return realizedVariable; + } + public @NonNull VariableAssignment createVariableAssignment(@NonNull Variable asVariable, @NonNull OCLExpression asValueExpression) { VariableAssignment asVariableAssignment = QVTcoreBaseFactory.eINSTANCE.createVariableAssignment(); asVariableAssignment.setTargetVariable(asVariable); |