Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2016-05-14 06:23:53 -0400
committerEd Willink2016-05-18 09:17:53 -0400
commite631413bcae2533300507ece490b99ec86095a22 (patch)
treecfb430c48c89117928a67e85687ed7a4680823bd
parentf28b29fd477c595ec722421ed0f14b28614c4c18 (diff)
downloadorg.eclipse.qvtd-e631413bcae2533300507ece490b99ec86095a22.tar.gz
org.eclipse.qvtd-e631413bcae2533300507ece490b99ec86095a22.tar.xz
org.eclipse.qvtd-e631413bcae2533300507ece490b99ec86095a22.zip
[486722] Provide explicit null/type predicates
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java584
-rw-r--r--plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAnalyzer.java12
2 files changed, 363 insertions, 233 deletions
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
index 8c11b8dec..822c32845 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAS2CGVisitor.java
@@ -33,6 +33,7 @@ import org.eclipse.ocl.examples.codegen.cgmodel.CGExecutorProperty;
import org.eclipse.ocl.examples.codegen.cgmodel.CGExecutorType;
import org.eclipse.ocl.examples.codegen.cgmodel.CGFinalVariable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIfExp;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGIsEqualExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsKindOfExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterator;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLetExp;
@@ -61,6 +62,7 @@ import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.ids.TypeId;
+import org.eclipse.ocl.pivot.internal.complete.StandardLibraryInternal;
import org.eclipse.ocl.pivot.library.LibraryProperty;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.NameUtil;
@@ -166,262 +168,379 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
return n1.compareTo(n2);
}
}
-
- protected final @NonNull QVTiAnalyzer analyzer;
- protected final @NonNull QVTiGlobalContext globalContext;
- public QVTiAS2CGVisitor(@NonNull QVTiAnalyzer analyzer, @NonNull QVTiGlobalContext globalContext) {
- super(analyzer);
- this.analyzer = analyzer;
- this.globalContext = globalContext;
- }
-
- private <T extends CGValuedElement> @NonNull T addLeafExp(@NonNull CGMapping cgMapping, @Nullable CGValuedElement cgLeafExp, @NonNull T cgElement) {
- CGValuedElement cgElementRoot = cgElement;
- while (cgElementRoot.eContainer() != null) {
- cgElementRoot = (CGValuedElement) cgElementRoot.eContainer();
- }
- if (cgMapping.getBody() == null) {
- cgMapping.setBody(cgElementRoot);
- }
- if (cgLeafExp instanceof CGLetExp) {
- ((CGLetExp)cgLeafExp).setIn(cgElementRoot);
- }
- else if (cgLeafExp instanceof CGIfExp) {
- ((CGIfExp)cgLeafExp).setThenExpression(cgElementRoot);
- }
- else {
- assert cgLeafExp == null;
+ /**
+ * PredicateTreeBuilder supports building a CGMapping.body as a nest of if/let expressions top-down,
+ * continually appending to the 'leaf' which is the then-expression of an if, or the in-expression of a let.
+ */
+ protected class PredicateTreeBuilder
+ {
+ protected final @NonNull Mapping asMapping;
+ protected final @NonNull CGMapping cgMapping;
+ private @Nullable CGValuedElement cgLeafExp = null;
+
+ public PredicateTreeBuilder(@NonNull Mapping asMapping, @NonNull CGMapping cgMapping) {
+ this.asMapping = asMapping;
+ this.cgMapping = cgMapping;
}
- return cgElement;
- }
- protected @NonNull CGLetExp createBooleanCGLetExp(@NonNull CGMapping cgMapping, @Nullable CGValuedElement cgLeafExp, @NonNull Variable asVariable, @NonNull OCLExpression asInit) {
- CGValuedElement initExpression = doVisit(CGValuedElement.class, asInit);
- initExpression.setName(asVariable.getName());
- CGFinalVariable cgVariable = (CGFinalVariable) createCGVariable(asVariable); // FIXME Lose cast
- cgVariable.setInit(initExpression);
- CGLetExp cgLetExp = CGModelFactory.eINSTANCE.createCGLetExp();
- setAst(cgLetExp, asVariable);
- cgLetExp.setInit(cgVariable);
- cgLetExp.setTypeId(context.getTypeId(TypeId.BOOLEAN));
- return addLeafExp(cgMapping, cgLeafExp, cgLetExp);
- }
+ /**
+ * Add a let expression sub-tree that exposes asVariable after initialization with asInit, as the 'leaf' of an existing expression sub-tree at cgLeafExp.
+ * If cgLeafExp is null then cgMapping.getBody() is the existing 'leaf'. Returns cgElement as the new 'leaf'.
+ * If asInit may be null but asVariable may not, a null value predicate as appended to enforce the non-nullness.
+ * If asInit.getType() does not conform to asVariable.getType() a ttype conformace predicate is appended to enforce type compatibility.
+ *
+ * This method supports building a nest of if/let expressions top-down, continually appending to the 'leaf' which is
+ * the then-expression of an if, or the in-expression of a let.
+ */
+ private void appendCheckedLetVariable(@NonNull Variable asVariable, @NonNull OCLExpression asInit) {
+ Type sourceType = ClassUtil.nonNullState(asInit.getType());
+ Type targetType = ClassUtil.nonNullState(asVariable.getType());
+ boolean needsNullTest = !asInit.isIsRequired() && asVariable.isIsRequired();
+ boolean needsTypeCheck = !sourceType.conformsTo(standardLibrary, targetType);
+ //
+ CGValuedElement cgInit = doVisit(CGValuedElement.class, asInit);
- @Override
- protected <T extends EObject> @NonNull T createCopy(@NonNull T aPrototype) {
- Copier copier = new EcoreUtil.Copier();
- EObject aCopy = copier.copy(aPrototype);
- assert aCopy != null;
- copier.copyReferences();
- Transformation asTransformation = QVTbaseUtil.getContainingTransformation(aPrototype);
- if (asTransformation != null) {
-// System.out.println("Copying " + aPrototype);
- QVTiCodeGenerator codeGenerator = analyzer.getCodeGenerator();
- QVTiTransformationAnalysis transformationAnalysis = codeGenerator.getTransformationAnalysis(asTransformation);
- QVTimperativeDomainUsageAnalysis domainUsageAnalysis = transformationAnalysis.getDomainUsageAnalysis();
- for (EObject prototypeEObject : copier.keySet()) {
- EObject clonedEObject = copier.get(prototypeEObject);
- assert clonedEObject != null;
- DomainUsage usage = domainUsageAnalysis.basicGetUsage((Element)prototypeEObject);
-// System.out.println(" " + prototypeEObject.eClass().getName() + "@" + Integer.toHexString(System.identityHashCode(prototypeEObject)) + " => " + usage + " : " + prototypeEObject);
- if (usage != null) {
-// System.out.println(" " + clonedEObject.eClass().getName() + "@" + Integer.toHexString(System.identityHashCode(clonedEObject)) + " <= " + usage + " : " + clonedEObject);
- domainUsageAnalysis.setUsage((Element) clonedEObject, usage);
+ if (needsTypeCheck || needsNullTest) {
+ CGFinalVariable cgRawVariable = CGModelFactory.eINSTANCE.createCGFinalVariable();
+ setAst(cgRawVariable, asInit);
+ cgRawVariable.setInit(cgInit);
+ cgRawVariable.setName("raw_" + asVariable.getName());
+ //
+ CGLetExp cgRawLetExp = CGModelFactory.eINSTANCE.createCGLetExp();
+ setAst(cgRawLetExp, asInit);
+ cgRawLetExp.setInit(cgRawVariable);
+// cgRawLetExp.setIn(cgIn);
+ cgRawLetExp.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+ //
+ appendSubTree(cgRawLetExp);
+ //
+ if (needsNullTest) {
+ appendNonNullPredicate(cgRawVariable);
+ }
+ if (needsTypeCheck) {
+ CGExecutorType cgType = analyzer.createExecutorType(targetType);
+ appendIsKindOfPredicate(cgRawVariable, cgType);
+ CGCastExp cgCastExp = CGModelFactory.eINSTANCE.createCGCastExp();
+ cgCastExp.setSource(analyzer.createCGVariableExp(cgRawVariable));
+ cgCastExp.setExecutorType(cgType);
+ cgCastExp.setTypeId(codeGenerator.getAnalyzer().getTypeId(asVariable.getTypeId()));
+ cgInit = cgCastExp;
+ }
+ else {
+ cgInit = analyzer.createCGVariableExp(cgRawVariable);
}
}
+ CGFinalVariable cgVariable = (CGFinalVariable) createCGVariable(asVariable); // FIXME Lose cast
+ cgVariable.setInit(cgInit);
+ CGLetExp cgLetExp = CGModelFactory.eINSTANCE.createCGLetExp();
+ setAst(cgLetExp, asVariable);
+ cgLetExp.setInit(cgVariable);
+ cgLetExp.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+ appendSubTree(cgLetExp);
}
- @SuppressWarnings("unchecked") T castCopy = (T) aCopy;
- return castCopy;
- }
- protected @Nullable CGValuedElement doBottoms(@NonNull Mapping pMapping, @NonNull CGMapping cgMapping, @NonNull CGMappingExp cgMappingExp, @Nullable CGValuedElement cgGuardExp) {
- CGValuedElement cgLeafExp = cgGuardExp;
- List<@NonNull BottomPattern> pBottomPatterns = new ArrayList<@NonNull BottomPattern>();
- {
- BottomPattern pBottomPattern = pMapping.getBottomPattern();
- if (pBottomPattern != null) {
- pBottomPatterns.add(pBottomPattern);
+ /**
+ * Add an expression sub-tree that ensures that cgVariable conforms to cgExecutorType.
+ */
+ private void appendIsKindOfPredicate(@NonNull CGFinalVariable cgVariable, @NonNull CGExecutorType cgExecutorType) {
+ @NonNull CGIsKindOfExp cgCondition = CGModelFactory.eINSTANCE.createCGIsKindOfExp();
+ cgCondition.setSource(analyzer.createCGVariableExp(cgVariable));
+ cgCondition.setExecutorType(cgExecutorType);
+// setAst(cgCondition, asVariable);
+ cgCondition.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+// cgCondition.setInvalidating(false);
+// cgCondition.setValidating(true);
+ //
+ CGIfExp cgIfExp = CGModelFactory.eINSTANCE.createCGIfExp();
+// setAst(cgIfExp, asVariable);
+ cgIfExp.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+// cgIfExp.setName(cgVariable.getName());
+ cgIfExp.setCondition(cgCondition);
+// cgIfExp.setThenExpression(cgUnsafeExp);
+ cgIfExp.setElseExpression(analyzer.createCGConstantExp(analyzer.getBoolean(false)));
+ //
+ appendSubTree(cgIfExp);
+ }
+
+ /**
+ * Add an expression sub-tree that ensures that cgVariable is non-null.
+ */
+ private void appendNonNullPredicate(@NonNull CGFinalVariable cgVariable) {
+ CGIsEqualExp cgCondition = CGModelFactory.eINSTANCE.createCGIsEqualExp();
+ cgCondition.setNotEquals(true);
+ cgCondition.setSource(analyzer.createCGVariableExp(cgVariable));
+ cgCondition.setArgument(analyzer.createCGConstantExp(analyzer.getNull()));
+// setAst(cgCondition, asExpression);
+ cgCondition.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+ cgCondition.setInvalidating(false);
+ cgCondition.setValidating(true);
+ //
+ CGIfExp cgIfExp = CGModelFactory.eINSTANCE.createCGIfExp();
+// setAst(cgIfExp, asExpression);
+ cgIfExp.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
+ cgIfExp.setName(cgVariable.getName());
+ cgIfExp.setCondition(cgCondition);
+ cgIfExp.setElseExpression(analyzer.createCGConstantExp(analyzer.getBoolean(false)));
+ //
+ appendSubTree(cgIfExp);
+ }
+
+ /**
+ * Add the expression sub-tree whose 'leaf' is at cgElement, as the 'leaf' of an existing expression sub-tree at cgLeafExp.
+ * If cgLeafExp is null then cgMapping.getBody() is the existing 'leaf'. Returns cgElement as the new 'leaf'.
+ *
+ * This method supports building a nest of if/let expressions top-down, continually appending to the 'leaf' which is
+ * the then-expression of an if, or the in-expression of a let.
+ */
+ private void appendSubTree(@NonNull CGValuedElement cgElement) {
+ CGValuedElement cgElementRoot = cgElement;
+ while (cgElementRoot.eContainer() != null) {
+ cgElementRoot = (CGValuedElement) cgElementRoot.eContainer();
+ }
+ if (cgMapping.getBody() == null) {
+ cgMapping.setBody(cgElementRoot);
+ }
+ if (cgLeafExp instanceof CGLetExp) {
+ ((CGLetExp)cgLeafExp).setIn(cgElementRoot);
+ }
+ else if (cgLeafExp instanceof CGIfExp) {
+ ((CGIfExp)cgLeafExp).setThenExpression(cgElementRoot);
+ }
+ else {
+ assert cgLeafExp == null;
}
- for (@NonNull Domain pDomain : ClassUtil.nullFree(pMapping.getDomain())) {
- if (pDomain instanceof CoreDomain) {
- pBottomPattern = ((CoreDomain)pDomain).getBottomPattern();
- if (pBottomPattern != null) {
- pBottomPatterns.add(pBottomPattern);
+ cgLeafExp = cgElement;
+ }
+
+ public void doBottoms(@NonNull CGMappingExp cgMappingExp) {
+ List<@NonNull BottomPattern> pBottomPatterns = new ArrayList<@NonNull BottomPattern>();
+ {
+ BottomPattern pBottomPattern = asMapping.getBottomPattern();
+ if (pBottomPattern != null) {
+ pBottomPatterns.add(pBottomPattern);
+ }
+ for (@NonNull Domain pDomain : ClassUtil.nullFree(asMapping.getDomain())) {
+ if (pDomain instanceof CoreDomain) {
+ pBottomPattern = ((CoreDomain)pDomain).getBottomPattern();
+ if (pBottomPattern != null) {
+ pBottomPatterns.add(pBottomPattern);
+ }
}
}
}
- }
- for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- for (@NonNull Variable asVariable : ClassUtil.nullFree(pBottomPattern.getVariable())) {
- OCLExpression asInit = asVariable.getOwnedInit();
- if (asVariable instanceof ConnectionVariable) {
- CGAccumulator cgAccumulator = CGModelFactory.eINSTANCE.createCGAccumulator();
- cgAccumulator.setAst(asVariable);
- cgAccumulator.setName(asVariable.getName());
- if (asInit != null) {
- CGValuedElement cgInit = doVisit(CGValuedElement.class, asInit);
- cgAccumulator.setTypeId(cgInit.getTypeId());
- cgAccumulator.setInit(cgInit);
-// cgAccumulator.setRequired(true);
+ for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
+ for (@NonNull Variable asVariable : ClassUtil.nullFree(pBottomPattern.getVariable())) {
+ OCLExpression asInit = asVariable.getOwnedInit();
+ if (asVariable instanceof ConnectionVariable) {
+ CGAccumulator cgAccumulator = CGModelFactory.eINSTANCE.createCGAccumulator();
+ cgAccumulator.setAst(asVariable);
+ cgAccumulator.setName(asVariable.getName());
+ if (asInit != null) {
+ CGValuedElement cgInit = doVisit(CGValuedElement.class, asInit);
+ cgAccumulator.setTypeId(cgInit.getTypeId());
+ cgAccumulator.setInit(cgInit);
+// cgAccumulator.setRequired(true);
+ }
+ else {
+ cgAccumulator.setTypeId(analyzer.getTypeId(asVariable.getTypeId()));
+ }
+ cgAccumulator.setNonNull();
+ cgMappingExp.getOwnedAccumulators().add(cgAccumulator);
+ getVariablesStack().putVariable(asVariable, cgAccumulator);
}
else {
- cgAccumulator.setTypeId(context.getTypeId(asVariable.getTypeId()));
+ if (asInit != null) {
+ appendCheckedLetVariable(asVariable, asInit);
+ }
}
- cgAccumulator.setNonNull();
- cgMappingExp.getOwnedAccumulators().add(cgAccumulator);
- getVariablesStack().putVariable(asVariable, cgAccumulator);
}
- else {
- if (asInit != null) {
- cgLeafExp = createBooleanCGLetExp(cgMapping, cgLeafExp, asVariable, asInit);
+ }
+ for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
+ List<@NonNull Assignment> assignment = ClassUtil.nullFree(pBottomPattern.getAssignment());
+ for (@NonNull Assignment pAssignment : assignment) {
+ if (pAssignment instanceof VariableAssignment) {
+ VariableAssignment asVariableAssignment = (VariableAssignment) pAssignment;
+ Variable asVariable = asVariableAssignment.getTargetVariable();
+ OCLExpression asInit = asVariableAssignment.getValue();
+ assert (asVariable != null) && (asInit != null);
+ appendCheckedLetVariable(asVariable, asInit);
}
}
}
- }
- for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- List<@NonNull Assignment> assignment = ClassUtil.nullFree(pBottomPattern.getAssignment());
- for (@NonNull Assignment pAssignment : assignment) {
- if (pAssignment instanceof VariableAssignment) {
- VariableAssignment asVariableAssignment = (VariableAssignment) pAssignment;
- Variable asVariable = asVariableAssignment.getTargetVariable();
- OCLExpression asInit = asVariableAssignment.getValue();
- assert (asVariable != null) && (asInit != null);
- cgLeafExp = createBooleanCGLetExp(cgMapping, cgLeafExp, asVariable, asInit);
+ for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
+ for (@NonNull Predicate asPredicate : ClassUtil.nullFree(pBottomPattern.getPredicate())) {
+ appendSubTree(doVisit(CGValuedElement.class, asPredicate));
}
}
- }
- for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- for (@NonNull Predicate asPredicate : ClassUtil.nullFree(pBottomPattern.getPredicate())) {
- cgLeafExp = addLeafExp(cgMapping, cgLeafExp, doVisit(CGValuedElement.class, asPredicate));
- }
- }
- List<@NonNull RealizedVariable> pRealizedVariables = new ArrayList<@NonNull RealizedVariable>();
- for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- for (@NonNull RealizedVariable asRealizedVariable : ClassUtil.nullFree(pBottomPattern.getRealizedVariable())) {
- OCLExpression asInit = asRealizedVariable.getOwnedInit();
- if (asInit == null) {
- pRealizedVariables.add(asRealizedVariable);
+ List<@NonNull RealizedVariable> pRealizedVariables = new ArrayList<@NonNull RealizedVariable>();
+ for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
+ for (@NonNull RealizedVariable asRealizedVariable : ClassUtil.nullFree(pBottomPattern.getRealizedVariable())) {
+ OCLExpression asInit = asRealizedVariable.getOwnedInit();
+ if (asInit == null) {
+ pRealizedVariables.add(asRealizedVariable);
+ }
+ else {
+ appendCheckedLetVariable(asRealizedVariable, asInit);
+ }
}
- else {
- cgLeafExp = createBooleanCGLetExp(cgMapping, cgLeafExp, asRealizedVariable, asInit);
+ }
+ Collections.sort(pRealizedVariables, NameUtil.NAMEABLE_COMPARATOR);
+ List<@NonNull CGValuedElement> cgRealizedVariables = ClassUtil.nullFree(cgMappingExp.getRealizedVariables());
+ for (@NonNull RealizedVariable pRealizedVariable : pRealizedVariables) {
+ CGRealizedVariable cgVariable = getRealizedVariable(pRealizedVariable);
+ cgRealizedVariables.add(cgVariable);
+ }
+ List<@NonNull CGConnectionAssignment> cgConnectionAssignments = ClassUtil.nullFree(cgMappingExp.getConnectionAssignments());
+ List<@NonNull CGPropertyAssignment> cgPropertyAssignments = ClassUtil.nullFree(cgMappingExp.getAssignments());
+ for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
+ List<@NonNull Assignment> assignment = ClassUtil.nullFree(pBottomPattern.getAssignment());
+ for (@NonNull Assignment pAssignment : assignment) {
+ if (pAssignment instanceof PropertyAssignment) {
+ cgPropertyAssignments.add(doVisit(CGPropertyAssignment.class, pAssignment));
+ }
+ else if (pAssignment instanceof ConnectionAssignment) {
+ cgConnectionAssignments.add(doVisit(CGConnectionAssignment.class, pAssignment));
+ }
+ else {
+ assert pAssignment instanceof VariableAssignment;
+ }
}
}
+ appendSubTree(cgMappingExp);
}
- Collections.sort(pRealizedVariables, NameUtil.NAMEABLE_COMPARATOR);
- List<@NonNull CGValuedElement> cgRealizedVariables = ClassUtil.nullFree(cgMappingExp.getRealizedVariables());
- for (@NonNull RealizedVariable pRealizedVariable : pRealizedVariables) {
- CGRealizedVariable cgVariable = getRealizedVariable(pRealizedVariable);
- cgRealizedVariables.add(cgVariable);
- }
- List<@NonNull CGConnectionAssignment> cgConnectionAssignments = ClassUtil.nullFree(cgMappingExp.getConnectionAssignments());
- List<@NonNull CGPropertyAssignment> cgPropertyAssignments = ClassUtil.nullFree(cgMappingExp.getAssignments());
- for (@NonNull BottomPattern pBottomPattern : pBottomPatterns) {
- List<@NonNull Assignment> assignment = ClassUtil.nullFree(pBottomPattern.getAssignment());
- for (@NonNull Assignment pAssignment : assignment) {
- if (pAssignment instanceof PropertyAssignment) {
- cgPropertyAssignments.add(doVisit(CGPropertyAssignment.class, pAssignment));
- }
- else if (pAssignment instanceof ConnectionAssignment) {
- cgConnectionAssignments.add(doVisit(CGConnectionAssignment.class, pAssignment));
+
+ public void doGuards() {
+ List<@NonNull GuardPattern> guardPatterns = new ArrayList<@NonNull GuardPattern>();
+ {
+ GuardPattern pGuardPattern = asMapping.getGuardPattern();
+ if (pGuardPattern != null) {
+ guardPatterns.add(pGuardPattern);
}
- else {
- assert pAssignment instanceof VariableAssignment;
+ for (@NonNull Domain pDomain : ClassUtil.nullFree(asMapping.getDomain())) {
+ if (pDomain instanceof CoreDomain) {
+ GuardPattern guardPattern = ((CoreDomain)pDomain).getGuardPattern();
+ if (guardPattern != null) {
+ guardPatterns.add(guardPattern);
+ }
+ }
}
}
- }
- return cgLeafExp;
- }
-
- protected @Nullable CGValuedElement doGuards(@NonNull Mapping pMapping, @NonNull CGMapping cgMapping) {
- CGValuedElement cgLeafExp = null;
- List<@NonNull GuardPattern> guardPatterns = new ArrayList<@NonNull GuardPattern>();
- {
- GuardPattern pGuardPattern = pMapping.getGuardPattern();
- if (pGuardPattern != null) {
- guardPatterns.add(pGuardPattern);
+ Set<@NonNull Variable> predicatedVariables = new HashSet<@NonNull Variable>();
+ for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
+ for (Predicate predicate : pGuardPattern.getPredicate()) {
+ if (predicate instanceof VariablePredicate) {
+ Variable targetVariable = ((VariablePredicate)predicate).getTargetVariable();
+ assert targetVariable != null;
+ predicatedVariables.add(targetVariable);
+ }
+ };
}
- for (@NonNull Domain pDomain : ClassUtil.nullFree(pMapping.getDomain())) {
- if (pDomain instanceof CoreDomain) {
- GuardPattern guardPattern = ((CoreDomain)pDomain).getGuardPattern();
- if (guardPattern != null) {
- guardPatterns.add(guardPattern);
+ List<@NonNull Variable> pGuardVariables = new ArrayList<@NonNull Variable>();
+ for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
+// pGuardPattern.getPredicate();
+ for (@NonNull Variable pGuardVariable : ClassUtil.nullFree(pGuardPattern.getVariable())) {
+ if (!predicatedVariables.contains(pGuardVariable)) {
+ pGuardVariables.add(pGuardVariable);
}
}
}
- }
- Set<@NonNull Variable> predicatedVariables = new HashSet<@NonNull Variable>();
- for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
- for (Predicate predicate : pGuardPattern.getPredicate()) {
- if (predicate instanceof VariablePredicate) {
- Variable targetVariable = ((VariablePredicate)predicate).getTargetVariable();
- assert targetVariable != null;
- predicatedVariables.add(targetVariable);
+ Collections.sort(pGuardVariables, new Comparator<@NonNull NamedElement>()
+ {
+ @Override
+ public int compare(@NonNull NamedElement o1, @NonNull NamedElement o2) {
+ return o1.getName().compareTo(o2.getName());
+ }
+ });
+ List<@NonNull CGGuardVariable> cgFreeVariables = new ArrayList<@NonNull CGGuardVariable>();
+// List<CGFinalVariable> cgBoundVariables = new ArrayList<CGFinalVariable>();
+ for (@NonNull Variable pGuardVariable : pGuardVariables) {
+ OCLExpression initExpression = pGuardVariable.getOwnedInit();
+ if (initExpression == null) {
+ CGGuardVariable cgUnboundVariable = getGuardVariable(pGuardVariable);
+ cgFreeVariables.add(cgUnboundVariable);
}
- };
- }
- List<@NonNull Variable> pGuardVariables = new ArrayList<@NonNull Variable>();
- for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
- pGuardPattern.getPredicate();
- for (@NonNull Variable pGuardVariable : ClassUtil.nullFree(pGuardPattern.getVariable())) {
- if (!predicatedVariables.contains(pGuardVariable)) {
- pGuardVariables.add(pGuardVariable);
+ else {
+ CGFinalVariable cgBoundVariable = (CGFinalVariable) getVariable(pGuardVariable);
+ CGValuedElement cgInit = doVisit(CGValuedElement.class, initExpression);
+ cgBoundVariable.setInit(cgInit);
+ JavaLocalContext<?> localContext = globalContext.getLocalContext(cgMapping);
+ if (localContext != null) {
+ // FIXME localContext.addLocalVariable(cgBoundVariable);
+ }
+// cgBoundVariables.add(cgBoundVariable);
}
}
- }
- Collections.sort(pGuardVariables, new Comparator<@NonNull NamedElement>()
+ Collections.sort(cgFreeVariables, new Comparator<@NonNull CGGuardVariable>()
{
@Override
- public int compare(@NonNull NamedElement o1, @NonNull NamedElement o2) {
- return o1.getName().compareTo(o2.getName());
- }
+ public int compare(@NonNull CGGuardVariable o1, @NonNull CGGuardVariable o2) {
+ String n1 = o1.getName();
+ String n2 = o2.getName();
+ return n1.compareTo(n2);
+ }
});
- List<@NonNull CGGuardVariable> cgFreeVariables = new ArrayList<@NonNull CGGuardVariable>();
-// List<CGFinalVariable> cgBoundVariables = new ArrayList<CGFinalVariable>();
- for (@NonNull Variable pGuardVariable : pGuardVariables) {
- OCLExpression initExpression = pGuardVariable.getOwnedInit();
- if (initExpression == null) {
- CGGuardVariable cgUnboundVariable = getGuardVariable(pGuardVariable);
- cgFreeVariables.add(cgUnboundVariable);
- }
- else {
- CGFinalVariable cgBoundVariable = (CGFinalVariable) getVariable(pGuardVariable);
- CGValuedElement cgInit = doVisit(CGValuedElement.class, initExpression);
- cgBoundVariable.setInit(cgInit);
- JavaLocalContext<?> localContext = globalContext.getLocalContext(cgMapping);
- if (localContext != null) {
-// FIXME localContext.addLocalVariable(cgBoundVariable);
+ /* Collections.sort(cgBoundVariables, new Comparator<CGFinalVariable>()
+ {
+ @Override
+ public int compare(CGFinalVariable o1, CGFinalVariable o2) {
+ String n1 = o1.getName();
+ String n2 = o2.getName();
+ return n1.compareTo(n2);
+ }
+ }); */
+ cgMapping.getFreeVariables().addAll(cgFreeVariables);
+// cgMappingExp.getBoundVariables().addAll(cgBoundVariables);
+// List<CGPredicate> cgGuardExpressions = cgMappingExp.getPredicates();
+ for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
+ for (@NonNull Predicate asPredicate : ClassUtil.nullFree(pGuardPattern.getPredicate())) {
+ appendSubTree(doVisit(CGValuedElement.class, asPredicate));
}
-// cgBoundVariables.add(cgBoundVariable);
}
}
- Collections.sort(cgFreeVariables, new Comparator<@NonNull CGGuardVariable>()
- {
- @Override
- public int compare(@NonNull CGGuardVariable o1, @NonNull CGGuardVariable o2) {
- String n1 = o1.getName();
- String n2 = o2.getName();
- return n1.compareTo(n2);
- }
- });
-/* Collections.sort(cgBoundVariables, new Comparator<CGFinalVariable>()
- {
- @Override
- public int compare(CGFinalVariable o1, CGFinalVariable o2) {
- String n1 = o1.getName();
- String n2 = o2.getName();
- return n1.compareTo(n2);
- }
- }); */
- cgMapping.getFreeVariables().addAll(cgFreeVariables);
-// cgMappingExp.getBoundVariables().addAll(cgBoundVariables);
-// List<CGPredicate> cgGuardExpressions = cgMappingExp.getPredicates();
- for (@NonNull GuardPattern pGuardPattern : guardPatterns) {
- for (@NonNull Predicate asPredicate : ClassUtil.nullFree(pGuardPattern.getPredicate())) {
- cgLeafExp = addLeafExp(cgMapping, cgLeafExp, doVisit(CGValuedElement.class, asPredicate));
+
+ @Override
+ public String toString() {
+ return String.valueOf(cgMapping.getBody());
+ }
+ }
+
+ protected final @NonNull QVTiAnalyzer analyzer;
+ protected final @NonNull QVTiGlobalContext globalContext;
+ protected final @NonNull StandardLibraryInternal standardLibrary;
+
+ public QVTiAS2CGVisitor(@NonNull QVTiAnalyzer analyzer, @NonNull QVTiGlobalContext globalContext) {
+ super(analyzer);
+ this.analyzer = analyzer;
+ this.globalContext = globalContext;
+ this.standardLibrary = environmentFactory.getStandardLibrary();
+ }
+
+ @Override
+ protected <T extends EObject> @NonNull T createCopy(@NonNull T aPrototype) {
+ Copier copier = new EcoreUtil.Copier();
+ EObject aCopy = copier.copy(aPrototype);
+ assert aCopy != null;
+ copier.copyReferences();
+ Transformation asTransformation = QVTbaseUtil.getContainingTransformation(aPrototype);
+ if (asTransformation != null) {
+// System.out.println("Copying " + aPrototype);
+ QVTiCodeGenerator codeGenerator = analyzer.getCodeGenerator();
+ QVTiTransformationAnalysis transformationAnalysis = codeGenerator.getTransformationAnalysis(asTransformation);
+ QVTimperativeDomainUsageAnalysis domainUsageAnalysis = transformationAnalysis.getDomainUsageAnalysis();
+ for (EObject prototypeEObject : copier.keySet()) {
+ EObject clonedEObject = copier.get(prototypeEObject);
+ assert clonedEObject != null;
+ DomainUsage usage = domainUsageAnalysis.basicGetUsage((Element)prototypeEObject);
+// System.out.println(" " + prototypeEObject.eClass().getName() + "@" + Integer.toHexString(System.identityHashCode(prototypeEObject)) + " => " + usage + " : " + prototypeEObject);
+ if (usage != null) {
+// System.out.println(" " + clonedEObject.eClass().getName() + "@" + Integer.toHexString(System.identityHashCode(clonedEObject)) + " <= " + usage + " : " + clonedEObject);
+ domainUsageAnalysis.setUsage((Element) clonedEObject, usage);
+ }
}
}
- return cgLeafExp;
+ @SuppressWarnings("unchecked") T castCopy = (T) aCopy;
+ return castCopy;
}
/* protected @NonNull CGValuedElement generateMiddlePropertyCallExp(@NonNull CGValuedElement cgSource, @NonNull MiddlePropertyCallExp asMiddlePropertyCallExp) {
@@ -430,7 +549,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
globalContext.addToMiddleProperty(asOppositeProperty);
// LibraryProperty libraryProperty = metamodelManager.getImplementation(asProperty);
CGMiddlePropertyCallExp cgPropertyCallExp = QVTiCGModelFactory.eINSTANCE.createCGMiddlePropertyCallExp();
-// CGExecutorProperty cgExecutorProperty = context.getExecutorProperty(asProperty);
+// CGExecutorProperty cgExecutorProperty = analyzer.getExecutorProperty(asProperty);
// cgExecutorPropertyCallExp.setExecutorProperty(cgExecutorProperty);
// cgPropertyCallExp = cgExecutorPropertyCallExp;
// cgPropertyCallExp.getDependsOn().add(cgExecutorProperty);
@@ -448,7 +567,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
if (cgSource == null) { // FIXME workaround for BUG 481664
Transformation asTransformation = QVTbaseUtil.getContainingTransformation(asOperationCallExp);
if (asTransformation != null) {
- Variable asThis = QVTbaseUtil.getContextVariable(metamodelManager.getStandardLibrary(), asTransformation);
+ Variable asThis = QVTbaseUtil.getContextVariable(standardLibrary, asTransformation);
VariableExp asThisExp = PivotUtil.createVariableExp(asThis);
cgSource = doVisit(CGValuedElement.class, asThisExp);
}
@@ -482,7 +601,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
// LibraryProperty libraryProperty = metamodelManager.getImplementation(asProperty);
CGMiddlePropertyCallExp cgPropertyCallExp = QVTiCGModelFactory.eINSTANCE.createCGMiddlePropertyCallExp();
cgPropertyCallExp.setAst(asOppositePropertyCallExp);
- // CGExecutorProperty cgExecutorProperty = context.getExecutorProperty(asProperty);
+ // CGExecutorProperty cgExecutorProperty = analyzer.getExecutorProperty(asProperty);
// cgExecutorPropertyCallExp.setExecutorProperty(cgExecutorProperty);
// cgPropertyCallExp = cgExecutorPropertyCallExp;
// cgPropertyCallExp.getDependsOn().add(cgExecutorProperty);
@@ -512,9 +631,9 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
CGFunctionParameter cgFunctionParameter = (CGFunctionParameter)getVariablesStack().getParameter(asFunctionParameter);
if (cgFunctionParameter == null) {
cgFunctionParameter = QVTiCGModelFactory.eINSTANCE.createCGFunctionParameter();
- context.setNames(cgFunctionParameter, asFunctionParameter);
+ analyzer.setNames(cgFunctionParameter, asFunctionParameter);
setAst(cgFunctionParameter, asFunctionParameter);
- cgFunctionParameter.setTypeId(context.getTypeId(asFunctionParameter.getTypeId()));
+ cgFunctionParameter.setTypeId(analyzer.getTypeId(asFunctionParameter.getTypeId()));
addParameter(asFunctionParameter, cgFunctionParameter);
}
return cgFunctionParameter;
@@ -531,9 +650,9 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
else {
cgGuardVariable = QVTiCGModelFactory.eINSTANCE.createCGGuardVariable();
}
- context.setNames(cgGuardVariable, asVariable);
+ analyzer.setNames(cgGuardVariable, asVariable);
setAst(cgGuardVariable, asVariable);
- cgGuardVariable.setTypeId(context.getTypeId(asVariable.getTypeId()));
+ cgGuardVariable.setTypeId(analyzer.getTypeId(asVariable.getTypeId()));
if (!isConnectionVariable && !isPrimitiveVariable) {
cgGuardVariable.setTypedModel(getTypedModel(asVariable));
}
@@ -723,11 +842,10 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
TypeId pivotTypeId = TypeId.BOOLEAN; //pMapping.getTypeId();
CGMappingExp cgMappingExp = QVTiCGModelFactory.eINSTANCE.createCGMappingExp();
setAst(cgMappingExp, pMapping);
- cgMappingExp.setTypeId(context.getTypeId(pivotTypeId));
-// cgMapping.setBody(cgMappingExp);
- CGValuedElement cgGuardExp = doGuards(pMapping, cgMapping);
- CGValuedElement cgBottomExp = doBottoms(pMapping, cgMapping, cgMappingExp, cgGuardExp);
- addLeafExp(cgMapping, cgBottomExp, cgMappingExp);
+ cgMappingExp.setTypeId(analyzer.getTypeId(pivotTypeId));
+ PredicateTreeBuilder bodyBuilder = new PredicateTreeBuilder(pMapping, cgMapping);
+ bodyBuilder.doGuards();
+ bodyBuilder.doBottoms(cgMappingExp);
MappingStatement mappingStatements = pMapping.getMappingStatement();
if (mappingStatements != null) {
cgMappingExp.setBody(doVisit(CGValuedElement.class, mappingStatements));
@@ -776,7 +894,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
Variable asIterator = asIterators.get(0);
if (asIterator != null) {
CGIterator cgIterator = getIterator(asIterator);
- cgIterator.setTypeId(context.getTypeId(asIterator.getTypeId()));
+ cgIterator.setTypeId(analyzer.getTypeId(asIterator.getTypeId()));
cgIterator.setRequired(asIterator.isIsRequired());
if (asIterator.isIsRequired()) {
cgIterator.setNonNull();
@@ -788,7 +906,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
// cgIterator.setNonInvalid();
// cgIterator.setNonNull();
cgMappingLoop.setAst(asMappingLoop);
- CollectionType collectionType = metamodelManager.getStandardLibrary().getCollectionType();
+ CollectionType collectionType = standardLibrary.getCollectionType();
Operation forAllIteration = NameUtil.getNameable(collectionType.getOwnedOperations(), "forAll");
cgMappingLoop.setReferredIteration((Iteration) forAllIteration);
cgMappingLoop.setBody(doVisit(CGValuedElement.class, asMappingLoop.getOwnedBody()));
@@ -881,7 +999,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
// cgMappingCallBinding.setValueName(localnameasMappingCallBinding.getBoundVariable().getName());
cgPropertyAssignment.setInitValue(doVisit(CGValuedElement.class, asNavigationAssignment.getValue()));
- CGExecutorProperty cgExecutorProperty = context.createExecutorProperty(asTargetProperty);
+ CGExecutorProperty cgExecutorProperty = analyzer.createExecutorProperty(asTargetProperty);
cgPropertyAssignment.setExecutorProperty(cgExecutorProperty);
return cgPropertyAssignment;
}
@@ -900,7 +1018,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
OCLExpression asConditionExpression = asPredicate.getConditionExpression();
assert asConditionExpression != null;
cgPredicate.setCondition(doVisit(CGValuedElement.class, asConditionExpression));
- CGConstantExp cgElse = context.createCGConstantExp(asConditionExpression, context.getBoolean(false));
+ CGConstantExp cgElse = analyzer.createCGConstantExp(asConditionExpression, analyzer.getBoolean(false));
setAst(cgElse, asConditionExpression);
cgElse.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
cgElse.setRequired(true);
@@ -943,7 +1061,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
@Override
public @Nullable CGNamedElement visitRealizedVariable(@NonNull RealizedVariable object) {
-// CGExecutorType cgExecutorType = context.createExecutorType(pTypeExp.getReferredType());
+// CGExecutorType cgExecutorType = analyzer.createExecutorType(pTypeExp.getReferredType());
// cgTypeExp.setExecutorType(cgExecutorType);
return visiting(object);
}
@@ -1035,7 +1153,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
CGIfExp cgPredicate = CGModelFactory.eINSTANCE.createCGIfExp();
cgPredicate.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
cgPredicate.setRequired(true);
- CGConstantExp cgElse = context.createCGConstantExp(asExpression, context.getBoolean(false));
+ CGConstantExp cgElse = analyzer.createCGConstantExp(asExpression, analyzer.getBoolean(false));
setAst(cgElse, asPredicate);
cgElse.setTypeId(analyzer.getTypeId(TypeId.BOOLEAN));
cgElse.setRequired(true);
@@ -1050,7 +1168,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
cgUncastVariableExp1.setRequired(cgUncastVariable.isRequired());
cgIsKindOfExp.setSource(cgUncastVariableExp1);
- CGExecutorType cgExecutorType = context.createExecutorType(ClassUtil.nonNullState(asVariable.getType()));
+ CGExecutorType cgExecutorType = analyzer.createExecutorType(ClassUtil.nonNullState(asVariable.getType()));
cgIsKindOfExp.setExecutorType(cgExecutorType);
cgPredicate.setCondition(cgIsKindOfExp);
cgOuterLetExp.setIn(cgPredicate);
@@ -1065,7 +1183,7 @@ public class QVTiAS2CGVisitor extends AS2CGVisitor implements QVTimperativeVisit
cgCastExp.setExecutorType(cgExecutorType);
TypeId asTypeId = cgExecutorType.getASTypeId();
assert asTypeId != null;
- cgCastExp.setTypeId(context.getTypeId(asTypeId));
+ cgCastExp.setTypeId(analyzer.getTypeId(asTypeId));
CGFinalVariable cgCastVariable = (CGFinalVariable) createCGVariable(asVariable); // FIXME Lose cast
cgCastVariable.setInit(cgCastExp);
diff --git a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAnalyzer.java b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAnalyzer.java
index 6c090d0ec..707f6e3ef 100644
--- a/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAnalyzer.java
+++ b/plugins/org.eclipse.qvtd.codegen/src/org/eclipse/qvtd/codegen/qvti/analyzer/QVTiAnalyzer.java
@@ -16,6 +16,9 @@ import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.analyzer.CodeGenAnalyzer;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGModelFactory;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGVariable;
+import org.eclipse.ocl.examples.codegen.cgmodel.CGVariableExp;
import org.eclipse.qvtd.codegen.qvti.java.QVTiCodeGenerator;
import org.eclipse.qvtd.codegen.qvticgmodel.CGFunction;
import org.eclipse.qvtd.codegen.qvticgmodel.CGMapping;
@@ -46,6 +49,15 @@ public class QVTiAnalyzer extends CodeGenAnalyzer
cgTypedModels.put(pTypedModel, cgTypedModel);
}
+ public @NonNull CGVariableExp createCGVariableExp(@NonNull CGVariable cgVariable) {
+ CGVariableExp cgVariableExp = CGModelFactory.eINSTANCE.createCGVariableExp();
+ cgVariableExp.setTypeId(cgVariable.getTypeId());
+ cgVariableExp.setAst(cgVariable.getAst());
+ cgVariableExp.setReferredVariable(cgVariable);
+ cgVariableExp.setRequired(cgVariable.isRequired());
+ return cgVariableExp;
+ }
+
@Override
public @NonNull QVTiCodeGenerator getCodeGenerator() {
return (QVTiCodeGenerator) super.getCodeGenerator();

Back to the top