diff options
author | Ed Willink | 2017-04-20 08:08:33 +0000 |
---|---|---|
committer | Ed Willink | 2017-05-14 05:22:52 +0000 |
commit | 43180d911b35ea9b930342327dffb8540bc57127 (patch) | |
tree | a2b63ec17e3a24caa1f8cfef74f83024e6434783 /plugins | |
parent | 4108dedd83f3c44ed1796526715f0382c9ee851c (diff) | |
download | org.eclipse.qvtd-43180d911b35ea9b930342327dffb8540bc57127.tar.gz org.eclipse.qvtd-43180d911b35ea9b930342327dffb8540bc57127.tar.xz org.eclipse.qvtd-43180d911b35ea9b930342327dffb8540bc57127.zip |
[514590] Improve when/where invocation
Diffstat (limited to 'plugins')
12 files changed, 401 insertions, 185 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 3f5ecdaa9..c897ad804 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 @@ -695,6 +695,10 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; throw new IllegalStateException(); } + public @NonNull Mapping getCoreMapping() { + return cMapping; + } + protected @NonNull TypedModel getCoreTypedModel(@NonNull TypedModel rTypedModel) { String name = PivotUtil.getName(rTypedModel); Iterable<org.eclipse.ocl.pivot.@NonNull Package> usedPackages = QVTrelationUtil.getUsedPackages(rTypedModel); @@ -1065,6 +1069,8 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; // return whenRealizedVariable(cEnforcedBottomPattern, rVariable); // } + protected abstract @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings); + /** * Transform a rule implemented by a black box into an enforcement operation * @@ -1096,30 +1102,41 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; // body of RWhenRelCallToMGuard RelationCallExp rInvocation = (RelationCallExp)rConditionExpression; Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation); - Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation); - // List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation); - /* StringBuilder s = new StringBuilder(); - for (OCLExpression rArgument : rArguments) { - VariableExp a = (VariableExp) rArgument; - s.append("_"); - s.append(a.getReferredVariable().getName()); - } - String vdId = s.toString(); */ - String invokedName = "when_" + invokedTraceClass.getName()/* + vdId*/; - Variable cCalledVariable/*vd*/ = variablesAnalysis.addCoreGuardVariable(invokedName, invokedTraceClass); // FIXME 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 rArgumentVariable/*v*/ = QVTbaseUtil.getReferredVariable(rArgument); - Variable cArgumentVariable/*mv*/ = variablesAnalysis.getCoreVariable(rArgumentVariable); - Property cCalledProperty/*pep*/ = qvtr2qvtc.getTraceProperty(QVTrelationUtil.getType(cCalledVariable), rParameter); - NavigationCallExp cCalledValue/*pe*/ = createNavigationCallExp(createVariableExp(cCalledVariable), cCalledProperty); - variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cCalledValue, createVariableExp(cArgumentVariable)); + if (rInvokedRelation.isIsTopLevel()) { + Type invokedTraceClass/*tc*/ = qvtr2qvtc.getTraceClass(rInvokedRelation); + // + String invokedName = "when_" + invokedTraceClass.getName()/* + vdId*/; + Variable cCalledVariable/*vd*/ = variablesAnalysis.addCoreGuardVariable(invokedName, invokedTraceClass); // FIXME + for (int i = 0; i < iSize; i++) { + VariableExp rArgument/*ve*/ = (VariableExp) rArguments.get(i); + Variable rParameter/*dv*/ = rParameters.get(i); + //RWhenRelCallArgToMGuardPredicate + Variable rArgumentVariable/*v*/ = QVTbaseUtil.getReferredVariable(rArgument); + Variable cArgumentVariable/*mv*/ = variablesAnalysis.getCoreVariable(rArgumentVariable); + Property cCalledProperty/*pep*/ = qvtr2qvtc.getTraceProperty(QVTrelationUtil.getType(cCalledVariable), rParameter); + NavigationCallExp cCalledValue/*pe*/ = createNavigationCallExp(createVariableExp(cCalledVariable), cCalledProperty); + variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cCalledValue, createVariableExp(cArgumentVariable)); + } + } + else { + Type invokedSignatureClass = qvtr2qvtc.getSignatureClass(rInvokedRelation); + String invokedName = "when_" + invokedSignatureClass.getName()/* + vdId*/; + Variable cInvocationVariable = variablesAnalysis.addCoreRealizedVariable(invokedName, invokedSignatureClass); // FIXME + Property cInvocationProperty = qvtr2qvtc.getTraceProperty(rInvocation); + variablesAnalysis.addTraceNavigationAssignment(cInvocationProperty, cInvocationVariable); + VariableAnalysis signatureVariableAnalysis = variablesAnalysis.getCoreVariableAnalysis(cInvocationVariable); + for (int i = 0; i < iSize; i++) { + VariableExp rArgument = (VariableExp) rArguments.get(i); + Variable rParameter = rParameters.get(i); + Variable cArgumentVariable = variablesAnalysis.getCoreVariable(QVTbaseUtil.getReferredVariable(rArgument)); + Property cCalledProperty = qvtr2qvtc.getSignatureProperty(QVTrelationUtil.getClass(cInvocationVariable), rParameter); + signatureVariableAnalysis.addNavigationAssignment(cCalledProperty, createVariableExp(cArgumentVariable), false); + } + } } else { @@ -1183,15 +1200,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; RelationCallExp rInvocation = (RelationCallExp)rConditionExpression; Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation); Type invokedSignatureClass/*tc*/ = qvtr2qvtc.getSignatureClass(rInvokedRelation); - // List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation); - /* StringBuilder s = new StringBuilder(); - for (OCLExpression rArgument : rArguments) { - VariableExp a = (VariableExp) rArgument; - s.append("_"); - s.append(a.getReferredVariable().getName()); - } - String vdId = s.toString(); */ String invokedName = "where_" + invokedSignatureClass.getName()/* + vdId*/; Variable cInvocationVariable/*vd*/ = variablesAnalysis.addCoreRealizedVariable(invokedName, invokedSignatureClass); // FIXME Property cInvocationProperty/*pep*/ = qvtr2qvtc.getTraceProperty(rInvocation); @@ -1201,20 +1210,11 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; 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 rArgumentVariable/*v*/ = QVTbaseUtil.getReferredVariable(rArgument); - Variable cArgumentVariable/*mv*/ = variablesAnalysis.getCoreVariable(rArgumentVariable); - Property cCalledProperty/*pep*/ = qvtr2qvtc.getSignatureProperty(QVTrelationUtil.getType(cInvocationVariable), rParameter); - NavigationCallExp cCalledValue/*pe*/ = createNavigationCallExp(createVariableExp(cInvocationVariable), cCalledProperty); - // if (cArgumentVariable instanceof RealizedVariable) { + VariableExp rArgument = (VariableExp) rArguments.get(i); + Variable rParameter = rParameters.get(i); + Variable cArgumentVariable = variablesAnalysis.getCoreVariable(QVTbaseUtil.getReferredVariable(rArgument)); + Property cCalledProperty = qvtr2qvtc.getSignatureProperty(QVTrelationUtil.getClass(cInvocationVariable), rParameter); signatureVariableAnalysis.addNavigationAssignment(cCalledProperty, createVariableExp(cArgumentVariable), false); - - // } - // else { - // variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cCalledValue, createVariableExp(cArgumentVariable)); - // } } } else { @@ -1261,6 +1261,12 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; * @throws CompilerChainException */ protected void synthesize() throws CompilerChainException { + Relation rOverride = QVTrelationUtil.basicGetOverrides(rRelation); + if (rOverride != null) { + AbstractQVTr2QVTcRelations overriddenRelation2Mappings = qvtr2qvtc.getRelation2Mappings(rOverride); + AbstractEnforceableRelationDomain2CoreMapping overridenDomain2Mapping = mapOverrides(overriddenRelation2Mappings); + cMapping.getSpecification().add(overridenDomain2Mapping.getCoreMapping()); + } Set<@NonNull Variable> rEnforcedBottomDomainVariables = getEnforcedBottomDomainVariables(); // Set<@NonNull Predicate> rWhereBottomPredicates = selectPredicatesThatReferToVariables(rWherePredicates, rEnforcedBottomDomainVariables); @@ -1298,44 +1304,59 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; * The overall QVTr2QVTc transformation */ protected @NonNull final QVTr2QVTc qvtr2qvtc; + // Relations /** * r: The relation being transformed */ protected final @NonNull Relation rRelation; + /** * The transformation containing the rRelation. i.e. rRelation.getOwningTransformation() */ protected final @NonNull RelationalTransformation rTransformation; + /** * The name of the rRelation. i.e. rRelation.getName() */ protected final @NonNull String rRelationName; + /** * All variables that are defined or referenced in any way within the relation's containment tree. * Includes CollectionTemplateExp member/rest, Let/Iterator variables. */ protected final @NonNull Set<@NonNull Variable> rAllVariables; + /** * Mapping from each variable used as a when RelationCallExp argument to the typedModel of its corresponding argument. */ protected final @NonNull Map<@NonNull Variable, @Nullable TypedModel> rWhenVariable2rTypedModel; + /** * Mapping from each variable used as a where RelationCallExp argument to the typedModel of its corresponding argument. */ protected final @NonNull Map<@NonNull Variable, @Nullable TypedModel> rWhereVariable2rTypedModel; + /** * All when predicates that are not RelationCallExp */ protected final @NonNull Set<@NonNull Predicate> rWhenPredicates; + /** * All where predicates that are not RelationCallExp */ protected final @NonNull Set<@NonNull Predicate> rWherePredicates; + /** * All variables defined/referenced by more than one domain. i.e. primitives */ protected final @NonNull Set<@NonNull Variable> rSharedVariables; + + /** + * All relations, including this one, that this relation overrides. + */ + protected final @NonNull Set<@NonNull Relation> rAllOverrides = new HashSet<>(); + // Core /** * mt: The transformation containing the result mapping @@ -1388,32 +1409,56 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; // this.rSharedVariables = VariablesAnalysis.getMiddleDomainVariables(rRelation); // + gatherOverrides(rRelation); + // this.cTransformation = qvtr2qvtc.getCoreTransformation(rTransformation); } + private void gatherOverrides(@NonNull Relation rOverriding) { + if (rAllOverrides.add(rOverriding)) { + Relation rOverridden = QVTrelationUtil.basicGetOverrides(rOverriding); + if (rOverridden != null) { + gatherOverrides(rOverridden); + } + } + else { + System.err.println("Override cycle for " + this + " at " + rOverriding); + }; + } + /** - * Return an AbstractEnforceableRelationDomain2CoreMapping for each Core Mapping that is to be synthesized. + * Create an AbstractEnforceableRelationDomain2CoreMapping for each Core Mapping that is to be synthesized. */ - protected abstract @NonNull List<@NonNull ? extends AbstractEnforceableRelationDomain2CoreMapping> analyze() throws CompilerChainException; + public abstract void analyze() throws CompilerChainException; + + public @NonNull Relation getRelation() { + return rRelation; + } + + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getTopRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + throw new IllegalStateException(); + } protected @Nullable Iterable<@NonNull RelationCallExp> getWhenInvocations() { return null; } + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhenRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + throw new IllegalStateException(); + } + protected @Nullable Iterable<@NonNull RelationCallExp> getWhereInvocations() { return null; } + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhereRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + throw new IllegalStateException(); + } + + public abstract void synthesize() throws CompilerChainException; + @Override public @NonNull String toString() { return PivotUtil.getName(rTransformation) + "::" + rRelationName; } - - public void transform() throws CompilerChainException { - List<@NonNull ? extends AbstractEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = analyze(); - for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : enforceableRelationDomain2coreMappings) { - 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 52cb10e88..bc7f404fe 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 @@ -10,9 +10,10 @@ *******************************************************************************/ package org.eclipse.qvtd.compiler.internal.qvtr2qvtc; -import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.jdt.annotation.NonNull; @@ -20,7 +21,10 @@ import org.eclipse.ocl.pivot.NavigationCallExp; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.Variable; +import org.eclipse.ocl.pivot.VariableDeclaration; +import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.CompilerChainException; +import org.eclipse.qvtd.pivot.qvtbase.TypedModel; import org.eclipse.qvtd.pivot.qvtrelation.Relation; import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp; import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; @@ -95,6 +99,21 @@ import com.google.common.collect.Iterables; return rEnforcedBottomDomainVariables; } + private @NonNull VariableDeclaration getOverriddenParameter(@NonNull Relation rOverride, @NonNull Variable rParameter) { + if (rOverride == rRelation) { + return rParameter; + } + RelationDomain rootVariableDomain = QVTrelationUtil.getRootVariableDomain(rParameter); + List<@NonNull Variable> rootVariables = QVTrelationUtil.getRootVariables(rootVariableDomain); + int index = rootVariables.indexOf(rParameter); + assert index >= 0; + TypedModel rTypedModel = QVTrelationUtil.getTypedModel(rootVariableDomain); + RelationDomain overriddenRootVariableDomain = QVTrelationUtil.getRelationDomain(rOverride, rTypedModel); + List<@NonNull Variable> overriddenRootVariables = QVTrelationUtil.getRootVariables(overriddenRootVariableDomain); + assert index <= overriddenRootVariables.size(); + return overriddenRootVariables.get(index); + } + // @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); @@ -106,10 +125,22 @@ import com.google.common.collect.Iterables; // RInvokerToMGuard @Override protected void mapIncomingInvocation() throws CompilerChainException { - Type invokingTraceClass = qvtr2qvtc.getSignatureClass(rRelation); // ?? invocation - Variable cInvocationVariable/*vd*/ = variablesAnalysis.addCoreGuardVariable("from_" + invokingTraceClass.getName(), invokingTraceClass); - Type cInvocationType = QVTrelationUtil.getType(cInvocationVariable); - assert cInvocationType == invokingTraceClass; // FIXME + Type invokingSignatureClass = null; // ?? invocation + Relation rOverride = rRelation; + for (; rOverride != null; rOverride = QVTrelationUtil.basicGetOverrides(rOverride)) { + invokingSignatureClass = qvtr2qvtc.basicGetSignatureClass(rOverride); + if (invokingSignatureClass != null) { + // qvtr2qvtc.get + break; + } + } + assert rOverride != null; + if (invokingSignatureClass == null) { + invokingSignatureClass = qvtr2qvtc.getSignatureClass(rRelation); // ?? invocation + } + Variable cInvocationVariable/*vd*/ = variablesAnalysis.addCoreGuardVariable("from_" + invokingSignatureClass.getName(), invokingSignatureClass); + org.eclipse.ocl.pivot.Class cInvocationType = QVTrelationUtil.getClass(cInvocationVariable); + assert cInvocationType == invokingSignatureClass; // FIXME // List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation); List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rRelation); // int iSize = rArguments.size(); @@ -122,53 +153,99 @@ import com.google.common.collect.Iterables; // RInvokerToMGuardPredicate // Variable rArgumentVariable = QVTrelationUtil.getReferredVariable(rArgumentVariableExp); Variable cParameter = variablesAnalysis.getCoreVariable(rParameter); - Property cProperty = qvtr2qvtc.getSignatureProperty(cInvocationType, rParameter); + Property cProperty = qvtr2qvtc.getSignatureProperty(cInvocationType, getOverriddenParameter(rOverride, rParameter)); NavigationCallExp cInvocationValue = createNavigationCallExp(createVariableExp(cInvocationVariable), cProperty); variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cInvocationValue, createVariableExp(cParameter)); } } } + /** + * The per-typed model when invocation conversions. + */ + private @NonNull Map<@NonNull TypedModel, @NonNull AbstractEnforceableRelationDomain2CoreMapping> whenTypedModel2relationDomain2coreMapping = new HashMap<>(); + + /** + * The per-typed model where invocation conversions. + */ + private @NonNull Map<@NonNull TypedModel, @NonNull AbstractEnforceableRelationDomain2CoreMapping> whereTypedModel2relationDomain2coreMapping = new HashMap<>(); + public InvokedRelationToMappingForEnforcement(@NonNull QVTr2QVTc qvtr2qvtc, @NonNull Relation rRelation) { super(qvtr2qvtc, rRelation); assert !rRelation.isIsTopLevel(); } + private void addWhenRelationDomain2coreMapping(@NonNull AbstractEnforceableRelationDomain2CoreMapping relationDomain2coreMapping) { + RelationDomain rDomain = relationDomain2coreMapping.rEnforcedDomain; + TypedModel rTypedModel = QVTrelationUtil.getTypedModel(rDomain); + AbstractEnforceableRelationDomain2CoreMapping old = whenTypedModel2relationDomain2coreMapping.put(rTypedModel, relationDomain2coreMapping); + assert old == null; + } + + private void addWhereRelationDomain2coreMapping(@NonNull AbstractEnforceableRelationDomain2CoreMapping relationDomain2coreMapping) { + RelationDomain rDomain = relationDomain2coreMapping.rEnforcedDomain; + TypedModel rTypedModel = QVTrelationUtil.getTypedModel(rDomain); + AbstractEnforceableRelationDomain2CoreMapping old = whereTypedModel2relationDomain2coreMapping.put(rTypedModel, relationDomain2coreMapping); + assert old == null; + } + /** * 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<>(); - Iterable<@NonNull RelationCallExp> incomingWhenInvocations = qvtr2qvtc.getIncomingWhenInvocationsOf(rRelation); - if ((incomingWhenInvocations != null) && !Iterables.isEmpty(incomingWhenInvocations)) { - // for (@NonNull RelationCallExp rInvocation : incomingWhenInvocations) { + public void analyze() throws CompilerChainException { + boolean hasWhenInvocation = false; + boolean hasWhereInvocation = false; + for (@NonNull Relation rOverride : rAllOverrides) { + Iterable<@NonNull RelationCallExp> incomingWhenInvocations = qvtr2qvtc.getIncomingWhenInvocationsOf(rOverride); + if ((incomingWhenInvocations != null) && !Iterables.isEmpty(incomingWhenInvocations)) { + hasWhenInvocation = true; + } + Iterable<@NonNull RelationCallExp> incomingWhereInvocations = qvtr2qvtc.getIncomingWhereInvocationsOf(rOverride); + if ((incomingWhereInvocations != null) && !Iterables.isEmpty(incomingWhereInvocations)) { + hasWhereInvocation = true; + } + } + if (hasWhenInvocation) { QVTr2QVTc.SYNTHESIS.println("invocation of when " + rRelation); for (@NonNull RelationDomain rDomain : QVTrelationUtil.getOwnedDomains(rRelation)) { if (rDomain.isIsEnforceable()) { - // Relation rInvokingRelation = qvtr2qvtc.getInvokingRelation(rInvocation); String coreMappingName = qvtr2qvtc.getNameGenerator().createWhenMappingClassName(rDomain); - WhenedEnforceableRelationDomain2CoreMapping enforceableRelationDomain2CoreMapping = new WhenedEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName); - enforceableRelationDomain2coreMappings.add(enforceableRelationDomain2CoreMapping); + addWhenRelationDomain2coreMapping(new WhenedEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName)); } } - // } } - Iterable<@NonNull RelationCallExp> incomingWhereInvocations = qvtr2qvtc.getIncomingWhereInvocationsOf(rRelation); - if ((incomingWhereInvocations != null) && !Iterables.isEmpty(incomingWhereInvocations)) { - // for (@NonNull RelationCallExp rInvocation : incomingWhereInvocations) { + if (hasWhereInvocation) { QVTr2QVTc.SYNTHESIS.println("invocation of where " + rRelation); for (@NonNull RelationDomain rDomain : QVTrelationUtil.getOwnedDomains(rRelation)) { if (rDomain.isIsEnforceable()) { - // Relation rInvokingRelation = qvtr2qvtc.getInvokingRelation(rInvocation); String coreMappingName = qvtr2qvtc.getNameGenerator().createWhereMappingClassName(rDomain); - WheredEnforceableRelationDomain2CoreMapping enforceableRelationDomain2CoreMapping = new WheredEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName); - enforceableRelationDomain2coreMappings.add(enforceableRelationDomain2CoreMapping); + addWhereRelationDomain2coreMapping(new WheredEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName)); } } - // } } - return enforceableRelationDomain2coreMappings; + } + + @Override + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhenRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + return ClassUtil.nonNullState(whenTypedModel2relationDomain2coreMapping.get(rEnforcedTypedModel)); + } + + @Override + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getWhereRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + return ClassUtil.nonNullState(whereTypedModel2relationDomain2coreMapping.get(rEnforcedTypedModel)); + } + + @Override + public void synthesize() throws CompilerChainException { + for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : whenTypedModel2relationDomain2coreMapping.values()) { + enforceableRelationDomain2coreMapping.synthesize(); + enforceableRelationDomain2coreMapping.variablesAnalysis.check(); + } + for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : whereTypedModel2relationDomain2coreMapping.values()) { + enforceableRelationDomain2coreMapping.synthesize(); + enforceableRelationDomain2coreMapping.variablesAnalysis.check(); + } } protected final class WhenedEnforceableRelationDomain2CoreMapping extends InvokedEnforceableRelationDomain2CoreMapping @@ -181,6 +258,11 @@ import com.google.common.collect.Iterables; protected @NonNull VariablesAnalysis createVariablesAnalysis(@NonNull RelationDomain rEnforcedDomain, @NonNull Type traceClass) throws CompilerChainException { return new VariablesAnalysis.WhenedVariablesAnalysis(qvtr2qvtc, rEnforcedDomain, cEnforcedDomain, traceClass); } + + @Override + protected @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings) { + return relation2Mappings.getWhenRelationDomain2CoreMapping(rEnforcedTypedModel); + } } protected final class WheredEnforceableRelationDomain2CoreMapping extends InvokedEnforceableRelationDomain2CoreMapping @@ -193,5 +275,10 @@ import com.google.common.collect.Iterables; protected @NonNull VariablesAnalysis createVariablesAnalysis(@NonNull RelationDomain rEnforcedDomain, @NonNull Type traceClass) throws CompilerChainException { return new VariablesAnalysis.WheredVariablesAnalysis(qvtr2qvtc, rEnforcedDomain, cEnforcedDomain, traceClass); } + + @Override + protected @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings) { + return relation2Mappings.getWhereRelationDomain2CoreMapping(rEnforcedTypedModel); + } } } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTr2QVTc.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTr2QVTc.java index ae2b0a9c4..016116a1a 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTr2QVTc.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTr2QVTc.java @@ -48,7 +48,6 @@ import org.eclipse.ocl.pivot.CompleteClass; 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.Operation; @@ -58,6 +57,7 @@ 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.internal.ecore.as2es.AS2Ecore; import org.eclipse.ocl.pivot.internal.manager.PivotMetamodelManager; import org.eclipse.ocl.pivot.internal.utilities.EnvironmentFactoryInternal; @@ -175,6 +175,56 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc } } + public static final class RelationComparator implements Comparator<@NonNull Relation> + { + private @NonNull Map<@NonNull Relation, @NonNull Set<@NonNull Relation>> relation2overrides = new HashMap<>(); + + @Override + public int compare(@NonNull Relation r1, @NonNull Relation r2) { + // + // Top level first + // + boolean t1 = r1.isIsTopLevel(); + boolean t2 = r2.isIsTopLevel(); + if (t1 != t2) { + return t1 ? -1 : 1; + } + // + // Overriding last + // + Set<@NonNull Relation> o1 = getOverrides(r1); + Set<@NonNull Relation> o2 = getOverrides(r2); + if (o1.contains(r2)) { + assert !o2.contains(r1); + return 1; + } + else if (o2.contains(r1)) { + return -1; + } + // + // Alphabetical + // + String n1 = NameUtil.getSafeName(r1); + String n2 = NameUtil.getSafeName(r2); + return ClassUtil.safeCompareTo(n1, n2); + } + + private @NonNull Set<@NonNull Relation> getOverrides(@NonNull Relation relation) { + Set<@NonNull Relation> overrides = relation2overrides.get(relation); + if (overrides == null) { + overrides = new HashSet<>(); + for (Relation override = relation; override != null; override = QVTrelationUtil.basicGetOverrides(override)) { + if (!overrides.add(override)) { + System.err.println("Cyclic override for " + relation + " at " + override); + break; + } + } + relation2overrides.put(relation, overrides); + } + return overrides; + } + } + protected static class UpdateVisitor extends AbstractUpdateVisitor<@NonNull QVTr2QVTc> { public UpdateVisitor(@NonNull QVTr2QVTc context) { @@ -278,6 +328,11 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc */ private @NonNull Map<@NonNull Relation, @Nullable Set<@NonNull Relation>> relation2overridingRelations = new HashMap<>(); + /** + * The per-relation conversions. + */ + private @NonNull Map<@NonNull Relation, @NonNull AbstractQVTr2QVTcRelations> relation2relation2mappings = new HashMap<>(); + private @Nullable Property oclContainerProperty = null; public QVTr2QVTc(@NonNull EnvironmentFactory environmentFactory, @NonNull Resource qvtrResource, @NonNull Resource qvtcResource) { @@ -378,13 +433,16 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc relation2rootVariables.put(relation, rootVariables); } - public @Nullable Property basicGetProperty(/*@NonNull*/ Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { - Property traceProperty = getRelationalTransformation2TracePackage().basicGetTraceProperty(aClass, rNamedElement); + public org.eclipse.ocl.pivot.@Nullable Class basicGetSignatureClass(@NonNull Relation rRelation) { + return getRelationalTransformation2TracePackage().basicGetSignatureClass(rRelation); + } + + public @Nullable Property basicGetTraceProperty(@NonNull Type aClass, @NonNull VariableDeclaration rVariable) throws CompilerChainException { + Property traceProperty = getRelationalTransformation2TracePackage().basicGetTraceProperty(aClass, rVariable); if (traceProperty != null) { return traceProperty; } - /*@NonNull*/ String name = rNamedElement.getName(); - assert (aClass != null) && (name != null); + String name = QVTrelationUtil.getName(rVariable); CompleteClass completeClass = getCompleteClass(aClass); return completeClass.getProperty(name); } @@ -708,16 +766,8 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc * Return the trace property of aClass whose name corresponds to rNamedElement. * @throws CompilerChainException if no such property */ - protected @NonNull Property getSignatureProperty(@NonNull Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { - Property property = getRelationalTransformation2TracePackage().basicGetSignatureProperty(aClass, rNamedElement); - if (property != null) { - return property; - } - property = getProperty(aClass, rNamedElement.getName()); // FIXME above should be non-null to ensure uniquely named property is in use - if (rNamedElement instanceof Property) { - assert rNamedElement == property; - } - return property; + protected @NonNull Property getSignatureProperty(org.eclipse.ocl.pivot.@NonNull Class aClass, @NonNull VariableDeclaration rVariable) throws CompilerChainException { + return getRelationalTransformation2TracePackage().getSignatureProperty(aClass, rVariable); } public @NonNull StandardLibrary getStandardLibrary() { @@ -736,14 +786,14 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc * Return the trace property of aClass whose name corresponds to rNamedElement. * @throws CompilerChainException if no such property */ - protected @NonNull Property getTraceProperty(@NonNull Type aClass, @NonNull NamedElement rNamedElement) throws CompilerChainException { - Property property = getRelationalTransformation2TracePackage().basicGetTraceProperty(aClass, rNamedElement); + protected @NonNull Property getTraceProperty(@NonNull Type aClass, @NonNull VariableDeclaration rVariable) throws CompilerChainException { + Property property = getRelationalTransformation2TracePackage().basicGetTraceProperty(aClass, rVariable); if (property != null) { return property; } - property = getProperty(aClass, rNamedElement.getName()); // FIXME above should be non-null to ensure uniquely named property is in use - if (rNamedElement instanceof Property) { - assert rNamedElement == property; + property = getProperty(aClass, rVariable.getName()); // FIXME above should be non-null to ensure uniquely named property is in use + if (rVariable instanceof Property) { + assert rVariable == property; } return property; } @@ -794,7 +844,7 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc */ protected void mapTransformation(@NonNull RelationalTransformation rTransformation, @NonNull Transformation cTransformation) throws CompilerChainException { List<@NonNull Relation> rRelations = Lists.newArrayList(QVTrelationUtil.getOwnedRelations(rTransformation)); - Collections.sort(rRelations, NameUtil.NAMEABLE_COMPARATOR); + Collections.sort(rRelations, new RelationComparator()); Variable cThis = QVTbaseUtil.getContextVariable(standardLibrary, cTransformation); Variable rThis = QVTbaseUtil.getContextVariable(standardLibrary, rTransformation); // putGlobalTrace(cThis, rThis); @@ -809,26 +859,35 @@ public class QVTr2QVTc extends AbstractQVTc2QVTc } mapQueries(rTransformation, cTransformation); for (@NonNull Relation rRelation : rRelations) { + AbstractQVTr2QVTcRelations relation2mappings; if (rRelation.isIsTopLevel()) { QVTr2QVTc.SYNTHESIS.println("topLevel " + rRelation); - TopLevelRelationToMappingForEnforcement topLevelRelationToMappingForEnforcement = new TopLevelRelationToMappingForEnforcement(this, rRelation); - topLevelRelationToMappingForEnforcement.transform(); + relation2mappings = new TopLevelRelationToMappingForEnforcement(this, rRelation); } + else { + relation2mappings = new InvokedRelationToMappingForEnforcement(this, rRelation); + } + relation2mappings.analyze(); + relation2relation2mappings.put(rRelation, relation2mappings); } for (@NonNull Relation rRelation : rRelations) { - if (!rRelation.isIsTopLevel()) { - InvokedRelationToMappingForEnforcement invokedRelationToMappingForEnforcement = new InvokedRelationToMappingForEnforcement(this, rRelation); - invokedRelationToMappingForEnforcement.transform(); - // for (@NonNull Relation rOverridingRelation : getOverridingRelations(rRelation)) { - // invokedRelationToMappingForEnforcement = new InvokedRelationToMappingForEnforcement(this, rOverridingRelation); - // invokedRelationToMappingForEnforcement.transform(); - // } - } + AbstractQVTr2QVTcRelations relation2mappings = relation2relation2mappings.get(rRelation); + assert relation2mappings != null; + relation2mappings.synthesize(); } CompilerUtil.normalizeNameables(QVTbaseUtil.Internal.getOwnedOperationsList(cTransformation)); CompilerUtil.normalizeNameables(QVTbaseUtil.getRule(cTransformation)); } + public void addRelation2Mappings(@NonNull AbstractQVTr2QVTcRelations relation2mappings) { + Relation rRelation = relation2mappings.getRelation(); + relation2relation2mappings.put(rRelation, relation2mappings); + } + + public @NonNull AbstractQVTr2QVTcRelations getRelation2Mappings(@NonNull Relation rRelation) { + return ClassUtil.nonNullState(relation2relation2mappings.get(rRelation)); + } + // Create the top rules, and search the input model for the appropriate types, when possible? public void prepare() { try { diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java index 49c5b9607..14d85f9b8 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/QVTrNameGenerator.java @@ -63,7 +63,7 @@ public class QVTrNameGenerator } public @NonNull String createTracePropertyName(@NonNull VariableDeclaration variable) { - return "t_" + QVTrelationUtil.getName(variable); + return /*"t_" +*/ QVTrelationUtil.getName(variable); } public @NonNull String createWhenInvocationPropertyName(@NonNull Relation relation) { 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 4c07e191e..98f7aabbb 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 @@ -10,16 +10,18 @@ *******************************************************************************/ package org.eclipse.qvtd.compiler.internal.qvtr2qvtc; -import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; -import java.util.List; +import java.util.Map; import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.ocl.pivot.Type; import org.eclipse.ocl.pivot.Variable; +import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.ocl.pivot.utilities.PivotUtil; import org.eclipse.qvtd.compiler.CompilerChainException; +import org.eclipse.qvtd.pivot.qvtbase.TypedModel; import org.eclipse.qvtd.pivot.qvtrelation.Relation; import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain; import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil; @@ -123,6 +125,15 @@ import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil; return rEnforcedDomainGuardVariables; } */ + public @NonNull AbstractEnforceableRelationDomain2CoreMapping getTopRelationDomain2CoreMapping(@NonNull TypedModel rEnforcedTypedModel) { + return ClassUtil.nonNullState(topTypedModel2relationDomain2coreMapping.get(rEnforcedTypedModel)); + } + + @Override + protected @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings) { + return relation2Mappings.getTopRelationDomain2CoreMapping(rEnforcedTypedModel); + } + @Override protected void synthesize() throws CompilerChainException { super.synthesize(); @@ -130,24 +141,42 @@ import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil; } } + /** + * The per-typed model top relation conversions. + */ + protected @NonNull Map<@NonNull TypedModel, @NonNull AbstractEnforceableRelationDomain2CoreMapping> topTypedModel2relationDomain2coreMapping = new HashMap<>(); + public TopLevelRelationToMappingForEnforcement(@NonNull QVTr2QVTc qvtr2qvtc, @NonNull Relation rRelation) { super(qvtr2qvtc, rRelation); assert rRelation.isIsTopLevel(); } + private void addTopRelationDomain2coreMapping(@NonNull AbstractEnforceableRelationDomain2CoreMapping relationDomain2coreMapping) { + RelationDomain rDomain = relationDomain2coreMapping.rEnforcedDomain; + TypedModel rTypedModel = QVTrelationUtil.getTypedModel(rDomain); + AbstractEnforceableRelationDomain2CoreMapping old = topTypedModel2relationDomain2coreMapping.put(rTypedModel, relationDomain2coreMapping); + assert old == null; + } + /** * Return the list of conversions, one for each possible enforced domain. */ @Override - protected @NonNull List<@NonNull TopEnforceableRelationDomain2CoreMapping> analyze() throws CompilerChainException { - List<@NonNull TopEnforceableRelationDomain2CoreMapping> enforceableRelationDomain2coreMappings = new ArrayList<>(); + public void analyze() throws CompilerChainException { for (@NonNull RelationDomain rDomain : QVTrelationUtil.getOwnedDomains(rRelation)) { if (rDomain.isIsEnforceable()) { String rEnforcedDomainName = PivotUtil.getName(rDomain); String coreMappingName = rRelationName + '_' + rEnforcedDomainName; - enforceableRelationDomain2coreMappings.add(new TopEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName)); + addTopRelationDomain2coreMapping(new TopEnforceableRelationDomain2CoreMapping(rDomain, coreMappingName)); } } - return enforceableRelationDomain2coreMappings; + } + + @Override + public void synthesize() throws CompilerChainException { + for (@NonNull AbstractEnforceableRelationDomain2CoreMapping enforceableRelationDomain2coreMapping : topTypedModel2relationDomain2coreMapping.values()) { + enforceableRelationDomain2coreMapping.synthesize(); + enforceableRelationDomain2coreMapping.variablesAnalysis.check(); + } } } 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 index 0d34e07cd..c1098c544 100644 --- 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 @@ -414,7 +414,7 @@ import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp; */ public @NonNull Variable addTraceNavigationAssignment(@NonNull Variable rVariable, boolean isOptional) throws CompilerChainException { Variable cVariable = getCoreVariable(rVariable); //getCoreRealizedVariable(rTargetVariable); - Property cTargetProperty = qvtr2qvtc.basicGetProperty(cMiddleRealizedVariable.getType(), rVariable); + Property cTargetProperty = qvtr2qvtc.basicGetTraceProperty(QVTrelationUtil.getType(cMiddleRealizedVariable), rVariable); assert isOptional || (cTargetProperty != null); if (cTargetProperty != null) { assert (!cTargetProperty.isIsMany() || (cVariable.getType() instanceof CollectionType)); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/AbstractRelation2TraceClass.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/AbstractRelation2TraceClass.java index da645fa6f..3a9c447e4 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/AbstractRelation2TraceClass.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/AbstractRelation2TraceClass.java @@ -26,7 +26,6 @@ import org.eclipse.ocl.pivot.Class; import org.eclipse.ocl.pivot.DataType; import org.eclipse.ocl.pivot.Detail; import org.eclipse.ocl.pivot.IteratorVariable; -import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.OCLExpression; import org.eclipse.ocl.pivot.Operation; import org.eclipse.ocl.pivot.OperationCallExp; @@ -129,7 +128,8 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass */ private org.eclipse.ocl.pivot.@Nullable Class bagOfTraceClass = null; - private @NonNull Map<@NonNull NamedElement, @NonNull Element2TraceProperty> element2element2traceProperty = new HashMap<>(); + private @NonNull Map<@NonNull VariableDeclaration, @NonNull VariableDeclaration2TraceProperty> variable2variableDeclaration2traceProperty = new HashMap<>(); + private @NonNull Map<@NonNull RelationCallExp, @NonNull Invocation2TraceProperty> invocation2invocation2traceProperty = new HashMap<>(); protected AbstractRelation2TraceClass(@NonNull RelationalTransformation2TracePackage relationalTransformation2tracePackage, @NonNull Relation relation) { this.relationalTransformation2tracePackage = relationalTransformation2tracePackage; @@ -268,7 +268,7 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass */ private void analyzeTemplateVariables(@NonNull TemplateExp templateExp, @NonNull TypedModel rTypedModel, boolean isOneToOne) { Variable templateVariable = QVTrelationUtil.getBindsTo(templateExp); - if (element2element2traceProperty.containsKey(templateVariable)) { + if (variable2variableDeclaration2traceProperty.containsKey(templateVariable)) { if (templateExp instanceof ObjectTemplateExp) { for (@NonNull PropertyTemplateItem rPropertyTemplateItem : QVTrelationUtil.getOwnedParts((ObjectTemplateExp)templateExp)) { boolean isNestedOneToOne = false; @@ -322,21 +322,12 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass } @Override - public @Nullable Property basicGetSignatureProperty(@NonNull NamedElement rNamedElement) { - Element2TraceProperty variableDeclaration2TraceProperty = element2element2traceProperty.get(rNamedElement); - if (variableDeclaration2TraceProperty == null) { + public @Nullable Property basicGetTraceProperty(@NonNull VariableDeclaration rVariable) { + VariableDeclaration2TraceProperty variableDeclaration2traceProperty = variable2variableDeclaration2traceProperty.get(rVariable); + if (variableDeclaration2traceProperty == null) { return null; } - return variableDeclaration2TraceProperty.getSignatureProperty(); - } - - @Override - public @Nullable Property basicGetTraceProperty(@NonNull NamedElement rNamedElement) { - Element2TraceProperty element2TraceProperty = element2element2traceProperty.get(rNamedElement); - if (element2TraceProperty == null) { - return null; - } - return element2TraceProperty.getTraceProperty(); + return variableDeclaration2traceProperty.getTraceProperty(); } @Override @@ -344,7 +335,7 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass return ClassUtil.safeCompareTo(this.traceClass.getName(), that.getTraceClass().getName()); } - public @NonNull Property createTraceProperty(@Nullable TypedModel rTypedModel, org.eclipse.ocl.pivot.@NonNull Class owningClass, + public @NonNull Property createProperty(@Nullable TypedModel rTypedModel, org.eclipse.ocl.pivot.@NonNull Class owningClass, @NonNull String name, org.eclipse.ocl.pivot.@NonNull Class type, boolean isRequired, boolean unitOpposite) { String domainName = rTypedModel != null ? rTypedModel.getName() : null; Property traceProperty = PivotFactory.eINSTANCE.createProperty(); @@ -403,7 +394,7 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass private Invocation2TraceProperty getInvocation2TraceProperty(@NonNull String name, @NonNull RelationCallExp rInvocation) { Invocation2TraceProperty invocation2TraceProperty = new Invocation2TraceProperty(this, name, rInvocation); invocation2TraceProperty.getTraceProperty(); - Element2TraceProperty oldInvocation2TraceProperty = element2element2traceProperty.put(rInvocation, invocation2TraceProperty); + Invocation2TraceProperty oldInvocation2TraceProperty = invocation2invocation2traceProperty.put(rInvocation, invocation2TraceProperty); assert oldInvocation2TraceProperty == null; return invocation2TraceProperty; } @@ -434,11 +425,25 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass } @Override + public @NonNull Property getSignatureProperty(@NonNull VariableDeclaration rVariable) { + VariableDeclaration2TraceProperty variableDeclaration2TraceProperty = variable2variableDeclaration2traceProperty.get(rVariable); + assert variableDeclaration2TraceProperty != null; + return variableDeclaration2TraceProperty.getSignatureProperty(); + } + + @Override public org.eclipse.ocl.pivot.@NonNull Class getTraceClass() { return traceClass; } @Override + public @NonNull Property getTraceProperty(@NonNull RelationCallExp rInvocation) { + Invocation2TraceProperty invocation2TraceProperty = invocation2invocation2traceProperty.get(rInvocation); + assert invocation2TraceProperty != null; + return invocation2TraceProperty.getTraceProperty(); + } + + @Override public @NonNull Set<@NonNull Relation2TraceClass> getTransitivelyConsumedByRelation2TraceClasses() { Set<@NonNull Relation2TraceClass> transitivelyConsumedByRelation2TraceClasses2 = transitivelyConsumedByRelation2TraceClasses; if (transitivelyConsumedByRelation2TraceClasses2 == null) { @@ -492,13 +497,13 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass } private @NonNull VariableDeclaration2TraceProperty getVariableDeclaration2TraceProperty(@Nullable TypedModel rTypedModel, @NonNull VariableDeclaration variable, boolean isNestedOneToOne) { - VariableDeclaration2TraceProperty variableDeclaration2TraceProperty = (VariableDeclaration2TraceProperty) element2element2traceProperty.get(variable); + VariableDeclaration2TraceProperty variableDeclaration2TraceProperty = variable2variableDeclaration2traceProperty.get(variable); if (variableDeclaration2TraceProperty != null) { variableDeclaration2TraceProperty.refineTraceProperty(rTypedModel, isNestedOneToOne); } else { variableDeclaration2TraceProperty = new VariableDeclaration2TraceProperty(this, rTypedModel, variable, isNestedOneToOne); - element2element2traceProperty.put(variable, variableDeclaration2TraceProperty); + variable2variableDeclaration2traceProperty.put(variable, variableDeclaration2TraceProperty); } return variableDeclaration2TraceProperty; } @@ -635,8 +640,13 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass // // Create a trace property for each prepared trace property. // - for (@NonNull NamedElement traceVariable : element2element2traceProperty.keySet()) { - Element2TraceProperty vd2tp = element2element2traceProperty.get(traceVariable); + for (@NonNull VariableDeclaration traceVariable : variable2variableDeclaration2traceProperty.keySet()) { + VariableDeclaration2TraceProperty vd2tp = variable2variableDeclaration2traceProperty.get(traceVariable); + assert vd2tp != null; + vd2tp.getTraceProperty(); + } + for (@NonNull RelationCallExp traceVariable : invocation2invocation2traceProperty.keySet()) { + Invocation2TraceProperty vd2tp = invocation2invocation2traceProperty.get(traceVariable); assert vd2tp != null; vd2tp.getTraceProperty(); } @@ -658,9 +668,8 @@ abstract class AbstractRelation2TraceClass implements Relation2TraceClass org.eclipse.ocl.pivot.Class signatureClass = basicGetSignatureClass(); if (signatureClass != null) { for (@NonNull RelationDomain rDomain : QVTrelationUtil.getOwnedDomains(relation)) { - TypedModel rTypedModel = rDomain.getTypedModel(); for (@NonNull Variable rootVariable : QVTrelationUtil.getRootVariables(rDomain)) { - Element2TraceProperty rootVariableDeclaration2TraceProperty = element2element2traceProperty.get(rootVariable); + VariableDeclaration2TraceProperty rootVariableDeclaration2TraceProperty = variable2variableDeclaration2traceProperty.get(rootVariable); assert rootVariableDeclaration2TraceProperty != null; rootVariableDeclaration2TraceProperty.getSignatureProperty(); } diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Element2TraceProperty.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Element2TraceProperty.java index 48ceead68..48b06755a 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Element2TraceProperty.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Element2TraceProperty.java @@ -14,7 +14,6 @@ import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.utilities.Nameable; -import org.eclipse.qvtd.pivot.qvtbase.TypedModel; /** * Element2TraceProperty defines the requirements on a future trace property. @@ -47,11 +46,6 @@ abstract class Element2TraceProperty implements Nameable */ private @Nullable Property traceProperty; - /** - * The lazily created signature property. - */ - private @Nullable Property signatureProperty; - protected Element2TraceProperty(@NonNull Relation2TraceClass relation2traceClass, @NonNull String name, org.eclipse.ocl.pivot.@NonNull Class type, boolean isRequired) { this.relation2traceClass = relation2traceClass; this.name = relation2traceClass.getUniqueTracePropertyName(this, name); @@ -59,8 +53,6 @@ abstract class Element2TraceProperty implements Nameable this.isRequired = isRequired; } - protected abstract @NonNull Property createSignatureProperty(); - protected abstract @NonNull Property createTraceProperty(); @Override @@ -68,14 +60,6 @@ abstract class Element2TraceProperty implements Nameable return name; } - public @NonNull Property getSignatureProperty() { - Property signatureProperty2 = signatureProperty; - if (signatureProperty2 == null) { - signatureProperty = signatureProperty2 = createSignatureProperty(); - } - return signatureProperty2; - } - public @NonNull Property getTraceProperty() { Property traceProperty2 = traceProperty; if (traceProperty2 == null) { @@ -84,8 +68,6 @@ abstract class Element2TraceProperty implements Nameable return traceProperty2; } - public abstract void refineTraceProperty(@Nullable TypedModel rTypedModel, boolean isNestedOneToOne); - @Override public String toString() { return name + ":" + type + (isRequired? "[1]" : "[?]"); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Invocation2TraceProperty.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Invocation2TraceProperty.java index 64201d3ff..27c5b5771 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Invocation2TraceProperty.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Invocation2TraceProperty.java @@ -11,10 +11,8 @@ package org.eclipse.qvtd.compiler.internal.qvtr2qvtc.trace; import org.eclipse.jdt.annotation.NonNull; -import org.eclipse.jdt.annotation.Nullable; import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Property; -import org.eclipse.qvtd.pivot.qvtbase.TypedModel; import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp; import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil; @@ -24,19 +22,17 @@ import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil; class Invocation2TraceProperty extends Element2TraceProperty { /** - * The variable whose value is persisted by the trace property. + * The invocation whose usa is persisted by the signature property. */ // final @NonNull RelationCallExp invocation; public Invocation2TraceProperty(@NonNull Relation2TraceClass relation2traceClass, @NonNull String name, @NonNull RelationCallExp invocation) { super(relation2traceClass, name, relation2traceClass.getRelationalTransformation2TracePackage().getRelation2TraceClass(QVTrelationUtil.getReferredRelation(invocation)).getSignatureClass(), true); - // this.invocation = invocation; } /** * Create the trace Property for a signatureClass with a type. - */ - @Override + * protected @NonNull Property createSignatureProperty() { Property signatureProperty = PivotFactory.eINSTANCE.createProperty(); signatureProperty.setName(name); @@ -46,13 +42,14 @@ class Invocation2TraceProperty extends Element2TraceProperty signatureProperty.setIsTransient(true); signatureProperty.setOwningClass(relation2traceClass.getSignatureClass()); return signatureProperty; - } + } */ /** * Create the trace Property for a signatureClass with a type. */ @Override protected @NonNull Property createTraceProperty() { + // return ((AbstractRelation2TraceClass) relation2traceClass).createProperty(null, relation2traceClass.getTraceClass(), name, type, isRequired, true); Property signatureProperty = PivotFactory.eINSTANCE.createProperty(); signatureProperty.setName(name); signatureProperty.setType(type); @@ -62,9 +59,4 @@ class Invocation2TraceProperty extends Element2TraceProperty signatureProperty.setOwningClass(relation2traceClass.getTraceClass()); return signatureProperty; } - - @Override - public void refineTraceProperty(@Nullable TypedModel rTypedModel, boolean isNestedOneToOne) { - throw new IllegalStateException(); - } }
\ No newline at end of file diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Relation2TraceClass.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Relation2TraceClass.java index e68f9ceaf..fccd41298 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Relation2TraceClass.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/Relation2TraceClass.java @@ -14,8 +14,8 @@ import java.util.Set; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.Property; +import org.eclipse.ocl.pivot.VariableDeclaration; import org.eclipse.qvtd.compiler.CompilerChainException; import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.QVTrNameGenerator; import org.eclipse.qvtd.pivot.qvtrelation.Relation; @@ -31,8 +31,7 @@ interface Relation2TraceClass extends Comparable<@NonNull Relation2TraceClass> void analyzeInheritance(); void analyzeProperties() throws CompilerChainException; org.eclipse.ocl.pivot.@Nullable Class basicGetSignatureClass(); - @Nullable Property basicGetSignatureProperty(@NonNull NamedElement rNamedElement); - @Nullable Property basicGetTraceProperty(@NonNull NamedElement rNamedElement); + @Nullable Property basicGetTraceProperty(@NonNull VariableDeclaration rVariable); org.eclipse.ocl.pivot.@NonNull Class getBagOfTraceClass(); @Nullable Iterable<@NonNull Relation2TraceClass> getConsumedByRelation2TraceClasses(); @Nullable Iterable<@NonNull Relation2TraceClass> getConsumedRelation2TraceClasses(); @@ -41,7 +40,9 @@ interface Relation2TraceClass extends Comparable<@NonNull Relation2TraceClass> @NonNull Relation getRelation(); @NonNull RelationalTransformation2TracePackage getRelationalTransformation2TracePackage(); org.eclipse.ocl.pivot.@NonNull Class getSignatureClass(); + @NonNull Property getSignatureProperty(@NonNull VariableDeclaration rVariable); org.eclipse.ocl.pivot.@NonNull Class getTraceClass(); + @NonNull Property getTraceProperty(@NonNull RelationCallExp rInvocation); @NonNull Set<@NonNull Relation2TraceClass> getTransitivelyConsumedByRelation2TraceClasses(); @NonNull Set<@NonNull Relation2TraceClass> getTransitivelyConsumedByRelation2TraceClasses(@NonNull Set<@NonNull Relation2TraceClass> accumulator); @NonNull Set<@NonNull Relation2TraceClass> getTransitivelyConsumedRelation2TraceClasses(); diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/RelationalTransformation2TracePackage.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/RelationalTransformation2TracePackage.java index 4ec495bcd..6884dd091 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/RelationalTransformation2TracePackage.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/RelationalTransformation2TracePackage.java @@ -19,10 +19,10 @@ import java.util.Map; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.Nullable; -import org.eclipse.ocl.pivot.NamedElement; import org.eclipse.ocl.pivot.PivotFactory; import org.eclipse.ocl.pivot.Property; import org.eclipse.ocl.pivot.Type; +import org.eclipse.ocl.pivot.VariableDeclaration; import org.eclipse.ocl.pivot.utilities.ClassUtil; import org.eclipse.qvtd.compiler.CompilerChainException; import org.eclipse.qvtd.compiler.internal.qvtr2qvtc.QVTr2QVTc; @@ -99,20 +99,16 @@ public class RelationalTransformation2TracePackage } } - public Property basicGetSignatureProperty(@NonNull Type aClass, @NonNull NamedElement rNamedElement) { - Relation2TraceClass relation2TraceClass = traceClass2relation2traceClass.get(aClass); - if (relation2TraceClass == null) { - return null; - } - return relation2TraceClass.basicGetSignatureProperty(rNamedElement); + public org.eclipse.ocl.pivot.@Nullable Class basicGetSignatureClass(@NonNull Relation rRelation) { + return getRelation2TraceClass(rRelation).basicGetSignatureClass(); } - public Property basicGetTraceProperty(@NonNull Type aClass, @NonNull NamedElement rNamedElement) { + public @Nullable Property basicGetTraceProperty(@NonNull Type aClass, @NonNull VariableDeclaration rVariable) { Relation2TraceClass relation2TraceClass = traceClass2relation2traceClass.get(aClass); if (relation2TraceClass == null) { return null; } - return relation2TraceClass.basicGetTraceProperty(rNamedElement); + return relation2TraceClass.basicGetTraceProperty(rVariable); } /** @@ -390,6 +386,12 @@ public class RelationalTransformation2TracePackage return getRelation2TraceClass(rRelation).getSignatureClass(); } + public @NonNull Property getSignatureProperty(org.eclipse.ocl.pivot.@NonNull Class aClass, @NonNull VariableDeclaration rVariable) { + Relation2TraceClass relation2TraceClass = traceClass2relation2traceClass.get(aClass); + assert relation2TraceClass != null; + return relation2TraceClass.getSignatureProperty(rVariable); + } + // public @NonNull Property getSignatureProperty(@NonNull RelationCallExp rInvocation) { // Relation2TraceClass relation2TraceClass = getRelation2TraceClass(QVTrelationUtil.getContainingRelation(rInvocation)); // return ClassUtil.nonNullState(relation2TraceClass.basicGetSignatureProperty(rInvocation)); @@ -401,7 +403,7 @@ public class RelationalTransformation2TracePackage public @NonNull Property getTraceProperty(@NonNull RelationCallExp rInvocation) { Relation2TraceClass relation2TraceClass = getRelation2TraceClass(QVTrelationUtil.getContainingRelation(rInvocation)); - return ClassUtil.nonNullState(relation2TraceClass.basicGetTraceProperty(rInvocation)); + return relation2TraceClass.getTraceProperty(rInvocation); } protected @NonNull String getUniqueTraceClassName(@NonNull Relation2TraceClass mapping2traceClass, @NonNull String name) { diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/VariableDeclaration2TraceProperty.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/VariableDeclaration2TraceProperty.java index 2d7fab6da..59abfb290 100644 --- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/VariableDeclaration2TraceProperty.java +++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvtc/trace/VariableDeclaration2TraceProperty.java @@ -42,6 +42,11 @@ class VariableDeclaration2TraceProperty extends Element2TraceProperty */ private boolean unitOpposite; + /** + * The lazily created signature property. + */ + private @Nullable Property signatureProperty; + public VariableDeclaration2TraceProperty(@NonNull Relation2TraceClass relation2traceClass, @Nullable TypedModel rTypedModel, @NonNull VariableDeclaration variable, boolean unitOpposite) { super(relation2traceClass, relation2traceClass.getNameGenerator().createTracePropertyName(variable), QVTrelationUtil.getClass(variable), variable.isIsRequired()); this.rTypedModel = rTypedModel; @@ -53,11 +58,8 @@ class VariableDeclaration2TraceProperty extends Element2TraceProperty * Create the name Property for a traceClass with a type. If unitOpposite is not set there may be many trace class instances referencing the same object through * the trace property and so the implicit opposite must be a Bag. */ - @Override protected @NonNull Property createSignatureProperty() { - // throw new UnsupportedOperationException(); - return ((AbstractRelation2TraceClass) relation2traceClass).createTraceProperty(rTypedModel, relation2traceClass.getSignatureClass(), name, type, isRequired, false); - // createTraceProperty(rTypedModel, signatureClass, rootVariableDeclaration2TraceProperty.getName(), QVTrelationUtil.getClass(rootVariable), rootVariable.isIsRequired(), false); + return ((AbstractRelation2TraceClass) relation2traceClass).createProperty(rTypedModel, relation2traceClass.getSignatureClass(), name, type, isRequired, unitOpposite); } /** @@ -66,7 +68,15 @@ class VariableDeclaration2TraceProperty extends Element2TraceProperty */ @Override protected @NonNull Property createTraceProperty() { - return ((AbstractRelation2TraceClass) relation2traceClass).createTraceProperty(rTypedModel, relation2traceClass.getTraceClass(), name, type, isRequired, unitOpposite); + return ((AbstractRelation2TraceClass) relation2traceClass).createProperty(rTypedModel, relation2traceClass.getTraceClass(), name, type, isRequired, unitOpposite); + } + + public @NonNull Property getSignatureProperty() { + Property signatureProperty2 = signatureProperty; + if (signatureProperty2 == null) { + signatureProperty = signatureProperty2 = createSignatureProperty(); + } + return signatureProperty2; } public void refineTraceProperty(@Nullable TypedModel rTypedModel, boolean isNestedOneToOne) { |