Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEd Willink2020-02-24 20:07:54 +0000
committerEd Willink2020-02-26 13:35:13 +0000
commitaf572b95c927d79c9a864af1b9b4125db43c2c22 (patch)
tree9edaa5a3f7010eaf399e2750b1ef017884ab3385
parent3fba3fb7006c2649e7b6e93c6b509ee8b40a9f32 (diff)
downloadorg.eclipse.qvtd-af572b95c927d79c9a864af1b9b4125db43c2c22.tar.gz
org.eclipse.qvtd-af572b95c927d79c9a864af1b9b4125db43c2c22.tar.xz
org.eclipse.qvtd-af572b95c927d79c9a864af1b9b4125db43c2c22.zip
[560427] wip Relation2WrapperClassewillink/560427
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationNameGenerator.java12
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java65
-rw-r--r--plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2WrapperClass.java115
3 files changed, 192 insertions, 0 deletions
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationNameGenerator.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationNameGenerator.java
index 974f1d829..cac28ada8 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationNameGenerator.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/QVTrelationNameGenerator.java
@@ -45,6 +45,7 @@ public class QVTrelationNameGenerator extends NameGenerator
public static final @NonNull String TRACE_INVOCATION_CLASS_NAME_PREFIX = "C";
public static final @NonNull String TRACE_INTERFACE_CLASS_NAME_PREFIX = "I";
public static final @NonNull String TRACE_TRACE_CLASS_NAME_PREFIX = "T";
+ public static final @NonNull String TRACE_WRAPPER_CLASS_NAME_PREFIX = "W";
public static final @NonNull String TRACE_DISPATCH_CLASS_DISPATCH_PROPERTY_NAME_PREFIX = "do";
public static final @NonNull String TRACE_DISPATCH_PROPERTY_NAME_PREFIX = "d";
@@ -53,6 +54,7 @@ public class QVTrelationNameGenerator extends NameGenerator
public static final @NonNull String TRACE_INVOCATION_TRACE_PROPERTY_NAME_PREFIX = "w";
public static final @NonNull String TRACE_SUCCESS_PROPERTY_NAME_PREFIX = "s";
public static final @NonNull String TRACE_TRACE_PROPERTY_NAME_PREFIX = "t";
+ public static final @NonNull String TRACE_WRAPPER_CLASS_PROPERTY_NAME_PREFIX = "ts";
public static final @NonNull String TRACE_WHEN_PROPERTY_NAME_PREFIX = "when_";
public static final @NonNull String TRACE_WHERE_PROPERTY_NAME_PREFIX = "where_";
@@ -198,4 +200,14 @@ public class QVTrelationNameGenerator extends NameGenerator
public @NonNull String createWhereInvocationPropertyName(@NonNull Rule rule) {
return TRACE_WHERE_PROPERTY_NAME_PREFIX + QVTbaseUtil.getName(rule);
}
+
+ public @NonNull String createWrapperClassPropertyName(@Nullable TypedModel typedModel, @NonNull VariableDeclaration variable) {
+ int index = QVTbaseUtil.getTypedModelIndex(typedModel);
+ String name = QVTrelationUtil.getName(variable);
+ return TRACE_WRAPPER_CLASS_PROPERTY_NAME_PREFIX + index + name;
+ }
+
+ public @NonNull String createWrapperClassName(@NonNull Rule rule) {
+ return TRACE_WRAPPER_CLASS_NAME_PREFIX + QVTbaseUtil.getName(rule);
+ }
}
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
index bbfe76065..98c011a0e 100644
--- a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2TraceGroup.java
@@ -11,12 +11,15 @@
package org.eclipse.qvtd.compiler.internal.qvtr2qvts.trace;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
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.compiler.internal.qvtb2qvts.HeadNodeGroup;
@@ -31,6 +34,7 @@ import org.eclipse.qvtd.pivot.qvtbase.Rule;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
import org.eclipse.qvtd.pivot.qvtschedule.Node;
+import com.google.common.collect.Iterables;
/**
* A Relation2TraceGroup manages the mapping between the analysis of a single rule and the one to four
@@ -43,6 +47,7 @@ public class Relation2TraceGroup extends Rule2TraceGroup
protected final @Nullable Relation2TraceInterface relation2traceInterface;
protected final @Nullable Relation2InvocationClass relation2invocationClass;
protected final @Nullable Relation2DispatchClass relation2dispatchClass;
+ private @Nullable Relation2WrapperClass relation2wrapperClass = null;
private final @NonNull List<@NonNull TracingStrategy> tracingStrategies = new ArrayList<>();
@@ -116,6 +121,14 @@ public class Relation2TraceGroup extends Rule2TraceGroup
// Determine a head node for the minimum number of sub-regions that have a to-one path from the head.
//
List<@NonNull HeadNodeGroup> headNodeGroups = TracedHeadAnalysis.computeTraceHeadGroupNodes(relationAnalysis.getRegion(), excludedNodes);
+ Map<@NonNull VariableDeclaration, @NonNull Node> rootVariable2headNode = analyzeWrapper(relationAnalysis, headNodeGroups);
+ if (rootVariable2headNode != null) {
+ assert relation2wrapperClass == null;
+ QVTrelationNameGenerator nameGenerator = getNameGenerator();
+ String wrapperClassName = nameGenerator.createWrapperClassName(relationAnalysis.getRule());
+ relation2wrapperClass = new Relation2WrapperClass(this, wrapperClassName, rootVariable2headNode);
+ relation2wrapperClass.analyzeTraceElements(headNodeGroups, relationAnalysis);
+ }
Relation2TraceInterface relation2traceInterface2 = relation2traceInterface;
if (relation2traceInterface2 != null) {
relation2traceInterface2.analyzeTraceElements(headNodeGroups, relationAnalysis);
@@ -134,6 +147,55 @@ public class Relation2TraceGroup extends Rule2TraceGroup
}
}
+ protected @Nullable Map<@NonNull VariableDeclaration, @NonNull Node> analyzeWrapper(@NonNull RelationAnalysis relationAnalysis, @NonNull List<@NonNull HeadNodeGroup> headNodeGroups) {//, @NonNull RelationAnalysis relationAnalysis) {
+ Relation relation = relationAnalysis.getRule();
+ String name = relationAnalysis.getName();
+ if ("FtoP1_Daughter2Female".equals(name)) {
+ getClass();
+ }
+ boolean compatibleRootVariables = true;
+ Iterable<@NonNull VariableDeclaration> rootVariables = QVTrelationUtil.getRootVariables(relation);
+ for (@NonNull VariableDeclaration rootVariable : rootVariables) {
+ boolean foundHeadGroup = false;
+ Node rootNode = relationAnalysis.getReferenceNode(rootVariable);
+ for (@NonNull HeadNodeGroup headNodeGroup : headNodeGroups) {
+ if (Iterables.contains(headNodeGroup.getHeadNodes(), rootNode)) {
+ foundHeadGroup = true;
+ }
+ else {
+ Iterable<@NonNull Node> uniqueNodes = headNodeGroup.getUniqueNodes();
+ if ((uniqueNodes != null) && Iterables.contains(uniqueNodes, rootNode)) {
+ foundHeadGroup = true;
+ compatibleRootVariables = false;
+ }
+ }
+ }
+ assert foundHeadGroup;
+ }
+ if (compatibleRootVariables) {
+ return null;
+ }
+ Map<@NonNull VariableDeclaration, @NonNull Node> rootVariable2headNode = new HashMap<>();
+ for (@NonNull VariableDeclaration rootVariable : rootVariables) {
+ Node rootNode = relationAnalysis.getReferenceNode(rootVariable);
+ Node preferredHeadNode = null;
+ for (@NonNull HeadNodeGroup headNodeGroup : headNodeGroups) {
+ Iterable<@NonNull Node> headNodes = headNodeGroup.getHeadNodes();
+ if (!Iterables.contains(headNodes, rootNode)) {
+ Iterable<@NonNull Node> uniqueNodes = headNodeGroup.getUniqueNodes();
+ if ((uniqueNodes == null) || !Iterables.contains(uniqueNodes, rootNode)) {
+ continue;
+ }
+ }
+ assert preferredHeadNode == null;
+ preferredHeadNode = headNodeGroup.getPreferredHeadNode(headNodes);
+ }
+ assert preferredHeadNode != null;
+ rootVariable2headNode.put(rootVariable, preferredHeadNode);
+ }
+ return rootVariable2headNode;
+ }
+
@Override
public @Nullable Element2MiddleProperty basicGetRelation2GlobalSuccessProperty() {
return relation2traceClass != null ? relation2traceClass.basicGetRelation2GlobalSuccessProperty() : null;
@@ -245,6 +307,9 @@ public class Relation2TraceGroup extends Rule2TraceGroup
if (relation2invocationClass != null) {
relation2invocationClass.synthesizeTraceModel(ruleAnalysis);
}
+ if (relation2wrapperClass != null) {
+ relation2wrapperClass.synthesizeTraceModel(ruleAnalysis);
+ }
}
@Override
diff --git a/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2WrapperClass.java b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2WrapperClass.java
new file mode 100644
index 000000000..5d9f631ac
--- /dev/null
+++ b/plugins/org.eclipse.qvtd.compiler/src/org/eclipse/qvtd/compiler/internal/qvtr2qvts/trace/Relation2WrapperClass.java
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2017, 2018 Willink Transformations and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ *
+ * Contributors:
+ * E.D.Willink - initial API and implementation (inspired by Horacio Hoyos' prototype)
+ ******************************************************************************/
+package org.eclipse.qvtd.compiler.internal.qvtr2qvts.trace;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.ocl.pivot.VariableDeclaration;
+import org.eclipse.qvtd.compiler.CompilerChainException;
+import org.eclipse.qvtd.compiler.internal.qvtb2qvts.HeadNodeGroup;
+import org.eclipse.qvtd.compiler.internal.qvtb2qvts.RuleAnalysis;
+import org.eclipse.qvtd.compiler.internal.qvtb2qvts.trace.Element2MiddleProperty;
+import org.eclipse.qvtd.compiler.internal.qvtr2qvts.QVTrelationNameGenerator;
+import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
+import org.eclipse.qvtd.pivot.qvtschedule.Node;
+
+/**
+ * A Relation2WrapperClass supervises the creation of multiple traces to bridge the gap
+ * from declared root variables to actula head variables.
+ */
+public class Relation2WrapperClass extends AbstractRelation2MiddleType
+{
+ /**
+ * Name to corresponding future trace property
+ */
+ private final @NonNull Map<@NonNull String, /*@NonNull*/ Element2MiddleProperty> name2element2traceProperty = new HashMap<>();
+
+ private final @NonNull Map<@NonNull VariableDeclaration, @NonNull Node> rootVariable2headNode;
+
+ /**
+ * The future Property that provides the result of the invoked mapping.
+ */
+ private @Nullable Relation2ResultProperty relation2doesProperty = null;
+ private boolean frozenRelation2doesProperty = false; // True once the presence/absence has been tested
+
+ public Relation2WrapperClass(@NonNull Relation2TraceGroup relation2traceGroup, @NonNull String middleClassName,
+ @NonNull Map<@NonNull VariableDeclaration, @NonNull Node> rootVariable2headNode) {
+ super(relation2traceGroup, middleClassName);
+ // middleClass.setIsAbstract(true);
+ this.rootVariable2headNode = rootVariable2headNode;
+ }
+
+ @Override
+ public void analyzeTraceElements(@NonNull List<@NonNull HeadNodeGroup> headNodeGroups, @NonNull RuleAnalysis ruleAnalysis) throws CompilerChainException {
+ //
+ // The AbstractTrace clast is the superclass.
+ //
+ middleClass.getSuperClasses().add(getTransformation2TracePackage().getExecutionClass());
+ //
+ //
+ //
+ // QVTrelationNameGenerator nameGenerator = relation2traceGroup.getNameGenerator();
+ // for (@NonNull VariableDeclaration rootVariable : rootVariable2headNode.keySet()) {
+ // Node node = rootVariable2headNode.get(rootVariable);
+ // assert node != null;
+ // createTracePropertyName(outgoingWhereInvocationAnalysis);
+ // createVariableDeclaration2TraceProperty(node, rootVariables, allHeadGroupNodes, manyTracesPerHead);
+ // getVariableDeclaration2TraceProperty(node.getClassDatum().getReferredTypedModel(), rootVariable, false/*unitOpposite*/);
+ // }
+ //
+ // No result property.
+ //
+ getRelation2DoesProperty();
+ //
+ // One trace property per root variable.
+ //
+ analyzeRootTemplateVariables(headNodeGroups);
+ //
+ // One trace property per root variable.
+ //
+ // if (!QVTrelationUtil.hasOverrides(relation)) {
+ // analyzeRootTemplateVariables(headNodeGroups);
+ // }
+ }
+
+ @Override
+ protected @NonNull String createTracePropertyName(@Nullable TypedModel typedModel, @NonNull VariableDeclaration variable) {
+ return getTransformation2TracePackage().getNameGenerator().createWrapperClassPropertyName(typedModel, variable);
+ }
+
+ public @NonNull Relation2ResultProperty getRelation2DoesProperty() {
+ Relation2ResultProperty relation2doesProperty2 = relation2doesProperty;
+ if (relation2doesProperty2 == null) {
+ assert !frozenRelation2doesProperty;
+ QVTrelationNameGenerator nameGenerator = relation2traceGroup.getNameGenerator();
+ String resultPropertyName = "does"; //nameGenerator.createDispatchClassResultPropertyName();
+ relation2doesProperty = relation2doesProperty2 = new Relation2ResultProperty(this, resultPropertyName, relation2traceGroup.getTraceInterface());
+ }
+ return relation2doesProperty2;
+ }
+
+ @Override
+ public @NonNull String getUniquePropertyName(@NonNull Element2MiddleProperty element2traceProperty, @NonNull String name) {
+ return QVTrelationNameGenerator.getUniqueName(name2element2traceProperty, name, element2traceProperty);
+ }
+
+ @Override
+ public void synthesizeTraceModel(@NonNull RuleAnalysis ruleAnalysis) {
+ super.synthesizeTraceModel(ruleAnalysis);
+ if (relation2doesProperty != null) {
+ relation2doesProperty.getTraceProperty();
+ }
+ }
+} \ No newline at end of file

Back to the top