blob: 99187cde6b8a3b5231b2e971c5c60df5f0bff446 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2016 The University of York and Willink Transformations.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Horacio Hoyos - initial API and implementation
******************************************************************************/
package org.eclipse.qvtd.compiler.internal.qvtr2qvtc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.IteratorVariable;
import org.eclipse.ocl.pivot.LetVariable;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.qvtd.compiler.CompilerChainException;
import org.eclipse.qvtd.pivot.qvtbase.Domain;
import org.eclipse.qvtd.pivot.qvtbase.Pattern;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.Transformation;
import org.eclipse.qvtd.pivot.qvtbase.TypedModel;
import org.eclipse.qvtd.pivot.qvtbase.utilities.QVTbaseUtil;
import org.eclipse.qvtd.pivot.qvtcore.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcore.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcore.CorePattern;
import org.eclipse.qvtd.pivot.qvtcore.GuardPattern;
import org.eclipse.qvtd.pivot.qvtcore.Mapping;
import org.eclipse.qvtd.pivot.qvtcore.NavigationAssignment;
import org.eclipse.qvtd.pivot.qvtcore.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtcore.VariableAssignment;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreHelper;
import org.eclipse.qvtd.pivot.qvtcore.utilities.QVTcoreUtil;
import org.eclipse.qvtd.pivot.qvtrelation.DomainPattern;
import org.eclipse.qvtd.pivot.qvtrelation.Key;
import org.eclipse.qvtd.pivot.qvtrelation.Relation;
import org.eclipse.qvtd.pivot.qvtrelation.RelationCallExp;
import org.eclipse.qvtd.pivot.qvtrelation.RelationDomain;
import org.eclipse.qvtd.pivot.qvtrelation.RelationalTransformation;
import org.eclipse.qvtd.pivot.qvtrelation.utilities.QVTrelationUtil;
import org.eclipse.qvtd.pivot.qvttemplate.CollectionTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.ObjectTemplateExp;
import org.eclipse.qvtd.pivot.qvttemplate.PropertyTemplateItem;
import org.eclipse.qvtd.pivot.qvttemplate.TemplateExp;
/**
* AbstractQVTr2QVTcRelations defines the mapping from a Relation, with a nested AbstractEnforceableRelationDomain2CoreMapping
* for each distinct enforcement of that relation and a further nested AbstractOtherRelationDomain2CoreDomain for each
* other domain of the distinct enforcement.
*/
/*public*/ abstract class AbstractQVTr2QVTcRelations extends QVTcoreHelper
{
/**
* The AbstractEnforceableRelationDomain2CoreMapping supervises the conversion of the enforced
* domains while enforcing a relation for a particular enforced domain.
*/
protected abstract class AbstractEnforceableRelationDomain2CoreMapping
{
/**
* The AbstractOtherRelationDomain2CoreDomain supervises the conversion of one of the not-enforced
* domains while enforcing a relation for a particular enforced domain.
*/
protected abstract class AbstractOtherRelationDomain2CoreDomain
{
// relations
/**
* The not-enforced domain being converted
*/
protected final @NonNull RelationDomain rOtherDomain;
/**
* The name of the not-enforced domain: rOtherDomain.getName()
*/
protected final @NonNull String rOtherDomainName;
/**
* The relations TypedModel of the not-enforced domain: rOtherDomain.getTypedModel()
*/
protected final @NonNull TypedModel rOtherTypedModel;
/**
* Mapping from each bound variable in the not-enforced relation domain to the TemplateExp that bindsTo it.
* Excludes CollectionTemplateExp.member, CollectionTemplateExp.rest.
*/
protected final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> rOtherBoundVariables;
/**
* Mapping from each member variable in the not-enforced relation domain to each CollectionTemplateExp that
* has a VariableExp member that refers to it.
*/
protected final @Nullable Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> rOtherMemberVariables;
/**
* Mapping from each rest variable in the not-enforced relation domain to its CollectionTemplateExp.
*/
protected final @Nullable Map<@NonNull Variable, @NonNull CollectionTemplateExp> rOtherRestVariables;
/**
* All variables defined or referenced in this other domain
*/
protected final @NonNull Set<@NonNull Variable> rOtherReferredVariables;
/**
* The template expression variables (the root variables of this other domain pattern)
*/
protected final @NonNull List<@NonNull Variable> rOtherRootVariables;
// core
/**
* The corresponding core TypedModel of the not-enforced domain: cOtherDomain.getTypedModel()
*/
protected final @NonNull TypedModel cOtherTypedModel;
/**
* The converted not-enforced domain.
*/
protected final @NonNull CoreDomain cOtherDomain;
/**
* The guard pattern of the not-enforced domain: cOtherDomain.getOwnedGuardPattern().
*/
protected final @NonNull GuardPattern cOtherGuardPattern;
/**
* The bottom pattern of the not-enforced domain: cOtherDomain.getOwnedBottomPattern().
*/
protected final @NonNull BottomPattern cOtherBottomPattern;
public AbstractOtherRelationDomain2CoreDomain(@NonNull RelationDomain rOtherDomain) {
this.rOtherDomain = rOtherDomain;
this.rOtherDomainName = ClassUtil.nonNullState(rOtherDomain.getName());
this.rOtherTypedModel = QVTrelationUtil.getTypedModel(rOtherDomain);
this.rOtherBoundVariables = VariablesAnalysis.gatherBoundVariables(rOtherDomain);
this.rOtherMemberVariables = VariablesAnalysis.gatherMemberVariables(rOtherDomain);
this.rOtherRestVariables = VariablesAnalysis.gatherRestVariables(rOtherDomain);
this.rOtherReferredVariables = new HashSet<>();
VariablesAnalysis.gatherReferredVariables(rOtherReferredVariables, rOtherDomain);
this.rOtherRootVariables = QVTrelationUtil.getRootVariables(rOtherDomain);
//
this.cOtherTypedModel = getCoreTypedModel(rOtherTypedModel);
this.cOtherDomain = createCoreDomain(cOtherTypedModel, false);
cOtherDomain.setIsCheckable(rOtherDomain.isIsCheckable());
cOtherDomain.setIsEnforceable(false);
this.cOtherGuardPattern = ClassUtil.nonNullState(cOtherDomain.getGuardPattern());
this.cOtherBottomPattern = ClassUtil.nonNullState(cOtherDomain.getBottomPattern());
//
for (@NonNull Variable rVariable : rOtherBoundVariables.keySet()) {
variablesAnalysis.getVariableAnalysis(rVariable).setOtherBound(cOtherDomain);
}
for (@NonNull Variable rVariable : rOtherReferredVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setOtherReferred(cOtherDomain);
}
for (@NonNull Variable rVariable : rOtherRootVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot();
}
}
// new
private void mapOtherCollectionTemplateExpression(@NonNull CollectionTemplateExp cte) throws CompilerChainException {
Variable vcte = QVTrelationUtil.getBindsTo(cte);
Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
/**
* Each CollectionTemplateExp member that is not a variable
* converts to a VariableAssignment of a new variable the member expression.
*
* ve1:T1{tp = ve2:Collection{a++b}} => a := a;
*/
Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<>();
List<@NonNull OCLExpression> rMembers = QVTrelationUtil.Internal.getOwnedMembersList(cte);
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable;
if (rMember instanceof TemplateExp) {
TemplateExp rTemplateExp = (TemplateExp)rMember;
mapOtherTemplateExpression(rTemplateExp);
Variable rVariable = QVTrelationUtil.getBindsTo(rTemplateExp);
mVariable = variablesAnalysis.getCoreVariable(rVariable);
}
else if (rMember instanceof VariableExp) {
Variable rVariable = QVTrelationUtil.getReferredVariable((VariableExp)rMember);
mVariable = variablesAnalysis.getCoreVariable(rVariable);
}
else {
OCLExpression mMember = mapExpression(rMember);
mVariable = variablesAnalysis.addCoreVariable("member", mMember);
}
rMember2mVariable.put(rMember, mVariable);
}
// CollectionTemplateExp cte = (CollectionTemplateExp) ptv;
// Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
// Variable mvcte = doRVarToMVar(vcte);
// PropertyCallExp pce = createPropertyCallExp(ve1, tp);
// VariableAssignment a = createVariableAssignment(mvcte, pce);
// mb.getAssignment().add(a);
CollectionType collectionType = QVTrelationUtil.getReferredCollectionType(cte);
int size = rMembers.size();
Variable rRest = cte.getRest();
if (rRest == null) {
/**
* The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
*
* ve1:T1{tp = ve2:Collection{a,b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
*/
List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable));
mParts.add(mItem);
}
CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts);
variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle);
}
/* else if (collectionType.isOrdered()) {
if (!rRest.isIsImplicit()) {
/**
* The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->subCollection(3,ve2->size());
* /
Variable mRest = variablesAnalysis.getCoreVariable(rRest);
String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence";
IntegerLiteralExp eStart = createIntegerLiteralExp(size);
OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size");
OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, eStart, eFinish);
VariableAssignment aRest = createVariableAssignment(mRest, eTail);
cMiddleBottomPattern.getAssignment().add(aRest);
}
/**
* The predicates for each ordered CollectionTemplateExp member variable is an element comparison.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => a = ve2->at(1);
* /
for (int i = 0; i < size; i++) {
IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1);
OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex);
OCLExpression rMember = rMembers.get(i);
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement);
}
} */
else {
if (!rRest.isIsImplicit()) {
/**
* The assignment for an unordered CollectionTemplateExp rest variable is a cumulative exclusion.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->excluding(a)->excluding(b);
*/
Variable mRest = variablesAnalysis.getCoreVariable(rRest);
OCLExpression exclusions = createVariableExp(mvcte);
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
exclusions = createOperationCallExp(exclusions, "excluding", createVariableExp(mVariable));
}
VariableAssignment aRest = createVariableAssignment(mRest, exclusions);
cMiddleBottomPattern.getAssignment().add(aRest);
}
/**
* The predicates for each unordered CollectionTemplateExp member variable is an excluded inclusion test.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => ve2->excluding(a)->includes(b);
*/
for (int i = 0; i < size; i++) {
@NonNull OCLExpression eTerm = createVariableExp(mvcte);
for (int j = 0; j < i; j++) {
OCLExpression rMember = rMembers.get(j);
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
eTerm = createOperationCallExp(eTerm, "excluding", createVariableExp(mVariable));
}
OCLExpression rMember = rMembers.get(i);
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
eTerm = createOperationCallExp(eTerm, "includes", createVariableExp(mVariable));
variablesAnalysis.addPredicate(cMiddleBottomPattern, eTerm);
}
}
}
// loop body of RDomainPatternToMDBottomPatternComposite
private void mapOtherObjectTemplateExpression(@NonNull ObjectTemplateExp rTemplateExpression) throws CompilerChainException {
Variable rTemplateVariable = QVTrelationUtil.getBindsTo(rTemplateExpression);
for (@NonNull PropertyTemplateItem propertyTemplateItem : QVTrelationUtil.getOwnedParts(rTemplateExpression)) {
Property partProperty = QVTrelationUtil.getReferredProperty(propertyTemplateItem);
Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
OCLExpression propertyTemplateValue = QVTrelationUtil.getOwnedValue(propertyTemplateItem);
if (propertyTemplateValue instanceof VariableExp) {
// body of RDomainPatternToMDBottomPatternSimpleSharedVarExpr and RDomainPatternToMDBottomPatternSimpleUnSharedVarExpr
/**
* Each PropertyTemplateItem whose value is a simple VariableExp
* converts to a domain(unshared) / middle(shared) PropertyAssignment.
*
* ve1:T{tp = ve2} => ve1.tp := ve2;
*/
Variable rVariable/*vpte*/ = QVTrelationUtil.getReferredVariable((VariableExp)propertyTemplateValue);
Variable cVariable/*mvpte*/ = variablesAnalysis.getCoreVariable(rVariable);
// BottomPattern cBottomPattern = rSharedVariables.contains(rVariable) ? cMiddleBottomPattern : cEnforcedBottomPattern;
variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(cVariable));
}
else if (propertyTemplateValue instanceof CollectionTemplateExp) {
/**
* Each PropertyTemplateItem whose value is a CollectionTemplateExp
* converts to a VariableAssignment and Predicates.
*
* ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp;
*/
CollectionTemplateExp cte = (CollectionTemplateExp)propertyTemplateValue;
Variable vcte = QVTrelationUtil.getBindsTo(cte);
Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
VariableAssignment a = createVariableAssignment(mvcte, pce);
cMiddleBottomPattern.getAssignment().add(a);
mapOtherTemplateExpression(cte);
}
else if (propertyTemplateValue instanceof ObjectTemplateExp) {
if (partProperty.isIsMany()) {
/**
* Each PropertyTemplateItem whose value is an ObjectTemplateExp
* converts to a PropertyAssignment.
*
* ve1:T1{tp = ve2:T2{...}} => ve1.tp := ve2;
*/
ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
Variable vpte = QVTrelationUtil.getBindsTo(pte);
Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
NavigationCallExp cNavigationExp = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
OperationCallExp eTerm = createOperationCallExp(cNavigationExp, "includes", createVariableExp(mvpte));
variablesAnalysis.addPredicate(cOtherBottomPattern, eTerm);
mapOtherTemplateExpression(pte);
}
else {
/**
* Each PropertyTemplateItem whose value is an ObjectTemplateExp
* converts to a PropertyAssignment.
*
* ve1:T1{tp = ve2:T2{...}} => ve1.tp := ve2;
*/
ObjectTemplateExp pte = (ObjectTemplateExp)propertyTemplateValue;
Variable vpte = QVTrelationUtil.getBindsTo(pte);
Variable mvpte = variablesAnalysis.getCoreVariable(vpte);
variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, createVariableExp(mvpte));
mapOtherTemplateExpression(pte);
}
}
else {
// loop body of RDomainPatternToMDBottomPatternSimpleNonVarExpr
/**
* Each PropertyTemplateItem whose value is not a TemplateExp and not a VariableExp
* converts to a PropertyAssignment.
*
* ve1:T{tp = me} => ve1.tp := me;
*/
variablesAnalysis.addNavigationPredicate(cOtherBottomPattern, rTemplateVariable, partProperty, mapExpression(propertyTemplateValue));
}
}
}
// RDomainPatternToMDBottomPattern
protected void mapOtherTemplateExpression(@NonNull TemplateExp rTemplateExpression) throws CompilerChainException {
if (rTemplateExpression instanceof ObjectTemplateExp) {
mapOtherObjectTemplateExpression((ObjectTemplateExp)rTemplateExpression);
}
else if (rTemplateExpression instanceof CollectionTemplateExp) {
mapOtherCollectionTemplateExpression((CollectionTemplateExp)rTemplateExpression);
}
OCLExpression rGuardPredicate = rTemplateExpression.getWhere();
if (rGuardPredicate != null) {
cMiddleBottomPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate)));
}
}
public void synthesize() throws CompilerChainException {
List<@NonNull TemplateExp> rOtherTemplateExpressions = getRootTemplateExpressions(rOtherDomain);
for (@NonNull TemplateExp rOtherTemplateExpression : rOtherTemplateExpressions) {
mapOtherTemplateExpression(rOtherTemplateExpression);
}
}
}
/**
* An ExpressionCopier deep copies an OCLExpression tree, exploiting the forward traceability of context to
* update references and using sibling to distinguish multiple targets.
*/
@SuppressWarnings("serial")
protected class ExpressionCopier extends EcoreUtil.Copier
{ // FIXME enforce unique names on let-variables, iterators
@Override
public EObject get(Object oIn) {
if (oIn instanceof Element) {
List<@NonNull Element> oOuts = source2targets.get(oIn);
if (oOuts != null) {
assert oOuts.size() == 1;
return oOuts.get(0);
}
oOuts = qvtr2qvtc.getGlobalTargets((Element) oIn);
if (oOuts != null) {
assert oOuts.size() == 1;
return oOuts.get(0);
}
}
return super.get(oIn);
}
@Override
public EObject copy(EObject oIn) {
try {
if (oIn instanceof IteratorVariable) {
return variablesAnalysis.getCoreVariable((IteratorVariable)oIn);
}
else if (oIn instanceof LetVariable) {
return variablesAnalysis.getCoreVariable((LetVariable)oIn);
}
} catch (CompilerChainException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.copy(oIn);
}
}
// Relations
/**
* rd: The relation domain to be enforced
*/
protected final @NonNull RelationDomain rEnforcedDomain;
/**
* The TypedModel of the enforced domain: rEnforcedDomain.getTypedModel()
*/
protected final @NonNull TypedModel rEnforcedTypedModel;
/**
* The name of the enforced domain: rEnforcedDomain.getName()
*/
protected final @NonNull String rEnforcedDomainName;
/**
* Mapping from each bound variable in the enforced relation domain to the TemplateExp that bindsTo it.
* Excludes CollectionTemplateExp.member, CollectionTemplateExp.rest.
*/
protected final @NonNull Map<@NonNull Variable, @NonNull TemplateExp> rEnforcedBoundVariables;
/**
* Mapping from each member variable in the enforced relation domain to each CollectionTemplateExp that
* has a VariableExp member that refers to it.
*/
protected final @Nullable Map<@NonNull Variable, @NonNull List<@NonNull CollectionTemplateExp>> rEnforcedMemberVariables;
/**
* Mapping from each rest variable in the enforced relation domain to its CollectionTemplateExp.
*/
protected final @Nullable Map<@NonNull Variable, @NonNull CollectionTemplateExp> rEnforcedRestVariables;
/**
* All variables defined or referenced in the enforced relation domain
*/
protected final @NonNull Set<@NonNull Variable> rEnforcedReferredVariables;
/**
* te: The template expressions defining the roots of the enforced domain pattern
*/
protected final @NonNull List<@NonNull/*Object*/TemplateExp> rEnforcedRootTemplateExpressions;
/**
* tev: The template expression root variables (the root variables of the enforced domain pattern)
*/
protected final @NonNull List<@NonNull Variable> rEnforcedRootVariables;
/**
* The conversion for each other domains sharing the parent of this domain
*/
protected final @NonNull List<@NonNull AbstractOtherRelationDomain2CoreDomain> otherDomain2coreDomains;
/**
* All variables defined in other domains
*/
protected final @NonNull Set<@NonNull Variable> rAllOtherBoundVariables;
/**
* All variables defined or referenced in other domains
*/
protected final @NonNull Set<@NonNull Variable> rAllOtherReferredVariables;
// Core
/**
* m: The resultant mapping
*/
protected final @NonNull Mapping cMapping;
/**
* mg: The resultant mapping guard pattern: cMapping.getOwnedGuardPattern()
*/
protected final @NonNull GuardPattern cMiddleGuardPattern;
/**
* mb : The resultant mapping bottom pattern: cMapping.getOwnedBottomPattern()
*/
protected final @NonNull BottomPattern cMiddleBottomPattern;
/**
* mdir: The resultant enforced typed model
*/
protected final @NonNull TypedModel cEnforcedTypedModel;
/**
* md: The resultant enforced domain
*/
protected final @NonNull CoreDomain cEnforcedDomain;
/**
* dg: The resultant enforced domain guard pattern
*/
protected final @NonNull GuardPattern cEnforcedGuardPattern;
/**
* db: The resultant enforced domain bottom pattern
*/
protected final @NonNull BottomPattern cEnforcedBottomPattern;
/**
* The analysis of each viariable in the relation.
*/
protected final @NonNull VariablesAnalysis variablesAnalysis;
/**
* tcv: The trace class variable (the middle variable identifying the middle object)
*/
protected final @NonNull RealizedVariable cMiddleRealizedVariable;
/**
* Mapping from each relation element to its corresponding core element(s).
*/
private final @NonNull Map<@NonNull Element, @NonNull List<@NonNull Element>> source2targets = new HashMap<>();
/**
* Mapping from each core element to its corresponding relation element.
*/
private final @NonNull Map<@NonNull Element, @NonNull Element> target2source = new HashMap<>();
public AbstractEnforceableRelationDomain2CoreMapping(@NonNull RelationDomain rEnforcedDomain, @NonNull String cMappingName) throws CompilerChainException {
this.rEnforcedDomain = rEnforcedDomain;
//
this.rEnforcedBoundVariables = VariablesAnalysis.gatherBoundVariables(rEnforcedDomain);
this.rEnforcedMemberVariables = VariablesAnalysis.gatherMemberVariables(rEnforcedDomain);
this.rEnforcedRestVariables = VariablesAnalysis.gatherRestVariables(rEnforcedDomain);
this.rEnforcedReferredVariables = new HashSet<>();
VariablesAnalysis.gatherReferredVariables(rEnforcedReferredVariables, rEnforcedDomain);
this.rEnforcedRootTemplateExpressions = getRootTemplateExpressions(rEnforcedDomain);
this.rEnforcedRootVariables = QVTrelationUtil.getRootVariables(rEnforcedDomain);
this.rEnforcedTypedModel = QVTrelationUtil.getTypedModel(rEnforcedDomain);
this.rEnforcedDomainName = ClassUtil.nonNullState(rEnforcedDomain.getName());
@NonNull Type traceClass = qvtr2qvtc.getTraceClass(rRelation);
//
this.cEnforcedTypedModel = getCoreTypedModel(rEnforcedTypedModel);
this.cMapping = qvtr2qvtc.createMapping(rRelation, cMappingName);
this.cMiddleGuardPattern = ClassUtil.nonNullState(cMapping.getGuardPattern());
this.cMiddleBottomPattern = ClassUtil.nonNullState(cMapping.getBottomPattern());
this.cEnforcedDomain = createCoreDomain(cEnforcedTypedModel, true);
this.cEnforcedGuardPattern = ClassUtil.nonNullState(cEnforcedDomain.getGuardPattern());
this.cEnforcedBottomPattern = ClassUtil.nonNullState(cEnforcedDomain.getBottomPattern());
//
this.variablesAnalysis = createVariablesAnalysis(rEnforcedDomain, traceClass);
this.cMiddleRealizedVariable = variablesAnalysis.getMiddleRealizedVariable();
// putTrace(cMiddleRealizedVariable, cMiddleBottomPattern);
//
this.otherDomain2coreDomains = new ArrayList<>();
this.rAllOtherBoundVariables = new HashSet<>();
for (@NonNull Domain rDomain : ClassUtil.nullFree(rEnforcedDomain.getRule().getDomain())) {
if ((rDomain != rEnforcedDomain) && (rDomain instanceof RelationDomain)) {
RelationDomain rRelationDomain = (RelationDomain)rDomain;
otherDomain2coreDomains.add(createOtherDomain2CoreDomain(rRelationDomain));
}
}
Set<@NonNull Variable> rUnsharedEnforcedDomainVariables = new HashSet<>(rEnforcedReferredVariables);
rUnsharedEnforcedDomainVariables.removeAll(rSharedVariables);
this.rAllOtherReferredVariables = new HashSet<>(rAllVariables);
rAllOtherReferredVariables.removeAll(rUnsharedEnforcedDomainVariables);
//
for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhenVariable2rTypedModel.entrySet()) {
TypedModel rWhenTypedModel = entry.getValue();
if (rWhenTypedModel != null) {
variablesAnalysis.getVariableAnalysis(entry.getKey()).setWhen(getCoreDomain(rWhenTypedModel));
}
}
for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhereVariable2rTypedModel.entrySet()) {
TypedModel rWhereTypedModel = entry.getValue();
if (rWhereTypedModel != null) {
variablesAnalysis.getVariableAnalysis(entry.getKey()).setWhere(getCoreDomain(rWhereTypedModel));
}
}
for (@NonNull Variable rVariable : rEnforcedBoundVariables.keySet()) {
Key rKey = qvtr2qvtc.getKeyForType(QVTrelationUtil.getType(rVariable));
variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedBound(rEnforcedBoundVariables.get(rVariable), rEnforcedTypedModel, rKey);
}
for (@NonNull Variable rVariable : rEnforcedReferredVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setIsEnforcedReferred();
}
for (@NonNull Variable rVariable : rEnforcedRootVariables) {
variablesAnalysis.getVariableAnalysis(rVariable).setIsRoot();
}
//
for (Map.Entry<@NonNull Variable, @Nullable TypedModel> entry : rWhenVariable2rTypedModel.entrySet()) {
Variable rWhenVariable = entry.getKey();
TypedModel rWhenTypedModel = entry.getValue();
VariableAnalysis variableAnalysis = variablesAnalysis.getVariableAnalysis(rWhenVariable);
if (rWhenTypedModel == null) {
OCLExpression rWhenInit = rWhenVariable.getOwnedInit();
if (rWhenInit != null) {
Set<@NonNull Variable> rReferredVariables = new HashSet<>();
VariablesAnalysis.gatherReferredVariables(rReferredVariables, rWhenInit);
for (Variable rReferredVariable : rReferredVariables) {
VariableAnalysis referredVariableAnalysis = variablesAnalysis.basicGetVariableAnalysis(rReferredVariable);
if (referredVariableAnalysis != null) {
CorePattern corePattern = referredVariableAnalysis.getCorePattern();
if (corePattern != null) {
variableAnalysis.setPredicate(ClassUtil.nonNullState(corePattern.getArea())); // FIXME need QVTrDomainAnalayis
}
break;
}
}
}
}
}
//
QVTr2QVTc.VARIABLES.println(" In " + cMapping + "\n\t\t" + variablesAnalysis.toString().replace("\n", "\n\t\t"));
for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) {
Variable rVariable = analysis.getRelationVariable();
if (rVariable != null) {
Variable cVariable = analysis.getCoreVariable();
putTrace(cVariable, rVariable);
}
}
for (@NonNull VariableAnalysis analysis : variablesAnalysis.getAnalyses()) {
Variable rVariable = analysis.getRelationVariable();
if (rVariable != null) {
OCLExpression rOwnedInit = rVariable.getOwnedInit();
if (rOwnedInit != null) {
Variable cVariable = analysis.getCoreVariable();
cVariable.setOwnedInit(mapExpression(rOwnedInit));
// variablesAnalysis.addConditionPredicate(analysis.getCorePattern(), createVariableExp(cVariable), mapExpression(rOwnedInit));
}
}
}
}
// Quad call of RDomainPatternExprToMappingXXXX
private void addPropertyAssignmentToMiddleBottomPattern(@NonNull Variable rTargetVariable, @NonNull Property targetProperty, @NonNull OCLExpression rExpression) throws CompilerChainException {
Variable cTargetVariable = null;
OCLExpression cExpression = null;
if (rExpression instanceof ObjectTemplateExp) {
// body of RDomainPatternExprToMappingDomainTemplateVarAssignment
Variable rBoundVariable = ClassUtil.nonNullState(((ObjectTemplateExp)rExpression).getBindsTo());
if (!rSharedVariables.contains(rBoundVariable)) {
Variable cBoundVariable = variablesAnalysis.getCoreVariable(rBoundVariable); // FIXME whenVariable(cMiddleBottomPattern, rBoundVariable);
cExpression = createVariableExp(cBoundVariable);
cTargetVariable = variablesAnalysis.addTraceNavigationAssignment(rBoundVariable, false);
}
}
else if (rExpression instanceof VariableExp) {
cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable); // getCoreVariable should do and be uniform
Variable rReferredVariable = ClassUtil.nonNullState((Variable) ((VariableExp)rExpression).getReferredVariable());
Variable cReferredVariable = variablesAnalysis.getCoreVariable(rReferredVariable);
if (rSharedVariables.contains(rReferredVariable) ) {
// body of RDomainPatternExprToMappingBottomVarAssignment
}
else {
// body of RDomainPatternExprToMappingDomainVarAssignment
if (!cEnforcedBottomPattern.getRealizedVariable().contains(cTargetVariable)) {
// FIXME variables should have been plotted earlier
cEnforcedBottomPattern.getRealizedVariable().add((RealizedVariable)cTargetVariable);
}
}
cExpression = createVariableExp(cReferredVariable);
}
else {
// body of RDomainPatternExprToMappingDomainAssignment
cTargetVariable = variablesAnalysis.getCoreVariable(rTargetVariable);
cExpression = mapExpression(rExpression);
}
if ((cTargetVariable != null) && (cExpression != null)) {
variablesAnalysis.addNavigationAssignment(rTargetVariable, targetProperty, cExpression, false);
}
}
private @NonNull CoreDomain createCoreDomain(@NonNull TypedModel cTypedModel, boolean isEnforced) {
CoreDomain coreDomain = qvtr2qvtc.createCoreDomain(cTypedModel);
coreDomain.setIsCheckable(false);
coreDomain.setIsEnforceable(isEnforced);
coreDomain.setRule(cMapping);
return coreDomain;
}
protected abstract @NonNull AbstractOtherRelationDomain2CoreDomain createOtherDomain2CoreDomain(@NonNull RelationDomain rRelationDomain);
protected abstract @NonNull VariablesAnalysis createVariablesAnalysis(@NonNull RelationDomain rEnforcedDomain, @NonNull Type traceClass) throws CompilerChainException;
// protected @NonNull CoreDomain getCoreDomain(@NonNull RelationDomain rDomain) {
// return getCoreDomain(QVTrelationUtil.getTypedModel(rDomain));
// }
protected @NonNull CoreDomain getCoreDomain(@NonNull TypedModel rTypedModel) {
TypedModel cTypedModel = getCoreTypedModel(rTypedModel);
for (@NonNull Domain cDomain : ClassUtil.nullFree(cMapping.getDomain())) { // FIXME provide a Map cache
if (QVTcoreUtil.getTypedModel(cDomain) == cTypedModel) {
return (CoreDomain) cDomain;
}
}
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);
for (@NonNull TypedModel cTypedModel : QVTcoreUtil.getModelParameters(cTransformation)) {
if (name.equals(cTypedModel.getName())) {
assert cTypedModel.getUsedPackage().equals(usedPackages);
return cTypedModel;
}
}
return ClassUtil.nonNullState(null);
}
protected abstract @NonNull Set<@NonNull Variable> getEnforcedBottomDomainVariables();
// protected abstract @NonNull Set<@NonNull Variable> getEnforcedDomainGuardVariables(@NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables);
protected @NonNull Set<@NonNull RelationDomain> getOtherRelationDomains() {
Set<@NonNull RelationDomain> relationDomains = new HashSet<>();
for (@NonNull Domain relationDomain : QVTrelationUtil.getOwnedDomains(rRelation)) {
relationDomains.add((RelationDomain) relationDomain);
}
relationDomains.remove(rEnforcedDomain);
return relationDomains;
}
protected @NonNull List<@NonNull TemplateExp> getRootTemplateExpressions(@NonNull RelationDomain rRelationDomain) {
List<@NonNull TemplateExp> rTemplateExpressions = new ArrayList<>();
for (@NonNull DomainPattern rDomainPattern : QVTrelationUtil.getOwnedPatterns(rRelationDomain)) {
rTemplateExpressions.add(QVTrelationUtil.getOwnedTemplateExpression(rDomainPattern));
}
return rTemplateExpressions;
}
private boolean isVarBoundToSomeOtherTemplate(ObjectTemplateExp rootTe, /*Object*/TemplateExp skipTe, Variable v) {
if (rootTe == skipTe) {
return false;
}
if (rootTe.getBindsTo().equals(v)) {
return true;
} else {
boolean exists = false;
for (PropertyTemplateItem p : rootTe.getPart()) {
if (p.getValue() instanceof ObjectTemplateExp) {
exists |= isVarBoundToSomeOtherTemplate((ObjectTemplateExp) p.getValue(), skipTe, v);
}
}
return exists;
}
}
protected void mapEnforcedCollectionTemplateExpression(@NonNull CollectionTemplateExp rEnforcedCollectionTemplateExp, @Nullable Key key) throws CompilerChainException {
// Property partProperty = ClassUtil.nonNullState(propertyTemplateItem.getReferredProperty());
// Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
@NonNull CollectionTemplateExp cte = rEnforcedCollectionTemplateExp;
/**
* Each PropertyTemplateItem whose value is a CollectionTemplateExp
* converts to a VariableAssignment and Predicates.
*
* ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp;
*/
Variable vcte = QVTrelationUtil.getBindsTo(cte);
Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
/* NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
VariableAssignment a = createVariableAssignment(mvcte, pce);
cMiddleBottomPattern.getAssignment().add(a);
/**
* Each CollectionTemplateExp member that is not a variable
* converts to a VariableAssignment of a new variable the member expression.
*
* ve1:T1{tp = ve2:Collection{a++b}} => a := a;
*/
Map<@NonNull OCLExpression, @NonNull Variable> rMember2mVariable = new HashMap<>();
List<@NonNull OCLExpression> rMembers = QVTrelationUtil.Internal.getOwnedMembersList(cte);
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable;
if (rMember instanceof TemplateExp) {
TemplateExp rTemplateExp = (TemplateExp)rMember;
mapEnforcedTemplateExpression(rTemplateExp);
Variable rVariable = QVTrelationUtil.getBindsTo(rTemplateExp);
mVariable = variablesAnalysis.getCoreVariable(rVariable);
}
else if (rMember instanceof VariableExp) {
Variable rVariable = QVTrelationUtil.getReferredVariable((VariableExp)rMember);
mVariable = variablesAnalysis.getCoreVariable(rVariable);
}
else {
OCLExpression mMember = mapExpression(rMember);
mVariable = variablesAnalysis.addCoreVariable("member", mMember);
}
rMember2mVariable.put(rMember, mVariable);
}
// CollectionTemplateExp cte = (CollectionTemplateExp) ptv;
// Variable vcte = ClassUtil.nonNullState(cte.getBindsTo());
// Variable mvcte = doRVarToMVar(vcte);
// PropertyCallExp pce = createPropertyCallExp(ve1, tp);
// VariableAssignment a = createVariableAssignment(mvcte, pce);
// mb.getAssignment().add(a);
CollectionType collectionType = QVTrelationUtil.getReferredCollectionType(cte);
Variable rRest = cte.getRest();
if (rRest == null) {
/**
* The predicate for a CollectionTemplateExp without a rest variable is a total comparison.
*
* ve1:T1{tp = ve2:Collection{a,b}} => ve2 := ve1.tp; ve2 = Collection{a,b};
*/
List<@NonNull CollectionLiteralPart> mParts = new ArrayList<>();
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
CollectionLiteralPart mItem = createCollectionItem(createVariableExp(mVariable));
mParts.add(mItem);
}
CollectionLiteralExp cle = createCollectionLiteralExp(collectionType, mParts);
variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mvcte), cle);
}
/* else if (collectionType.isOrdered()) {
if (!rRest.isIsImplicit()) {
/**
* The assignment for an ordered CollectionTemplateExp rest variable is a sub-collection assignment.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => c := ve2->subCollection(3,ve2->size());
* /
Variable mRest = variablesAnalysis.getCoreVariable(rRest);
String opName = collectionType.isUnique() ? "subOrderedSet" : "subSequence";
IntegerLiteralExp eStart = createIntegerLiteralExp(size);
OCLExpression eFinish = createOperationCallExp(createVariableExp(mvcte), "size");
OCLExpression eTail = createOperationCallExp(createVariableExp(mvcte), opName, eStart, eFinish);
VariableAssignment aRest = createVariableAssignment(mRest, eTail);
cMiddleBottomPattern.getAssignment().add(aRest);
}
/**
* The predicates for each ordered CollectionTemplateExp member variable is an element comparison.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => a = ve2->at(1);
* /
for (int i = 0; i < size; i++) {
IntegerLiteralExp eIndex = createIntegerLiteralExp(i+1);
OCLExpression vElement = createOperationCallExp(createVariableExp(mvcte), "at", eIndex);
OCLExpression rMember = rMembers.get(i);
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
variablesAnalysis.addConditionPredicate(cMiddleBottomPattern, createVariableExp(mVariable), vElement);
}
} */
else if (rRest.isIsImplicit()) {
PropertyTemplateItem rPropertyTemplateItem = (PropertyTemplateItem) cte.eContainer();
assert rPropertyTemplateItem != null;
ObjectTemplateExp rObjectTemplateExp = QVTrelationUtil.getOwningObjectTemplateExp(rPropertyTemplateItem);
Variable vote = QVTrelationUtil.getBindsTo(rObjectTemplateExp);
Variable cvote = variablesAnalysis.getCoreVariable(vote);
/**
* The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
*
* ve1:T1{tp = ve2:Collection{a,b++_}} => ve1.tp += a; ve1.tp += b;
*/
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
NavigationAssignment aRest = createNavigationAssignment(createVariableExp(cvote), QVTrelationUtil.getReferredProperty(rPropertyTemplateItem), createVariableExp(mVariable), true);
cMiddleBottomPattern.getAssignment().add(aRest);
}
}
else {
/**
* The assignment for a CollectionTemplateExp variable is a literal for the members and an addition of the rest.
*
* ve1:T1{tp = ve2:Collection{a,b++c}} => ve2 := Collection{a,b}->includingAll(c);
*/
List<@NonNull CollectionLiteralPart> ownedParts = new ArrayList<>();
for (@NonNull OCLExpression rMember : rMembers) {
Variable mVariable = ClassUtil.nonNullState(rMember2mVariable.get(rMember));
ownedParts.add(createCollectionItem(createVariableExp(mVariable)));
}
OCLExpression cExpression = createCollectionLiteralExp(collectionType, ownedParts);
Variable mRest = variablesAnalysis.getCoreVariable(rRest);
cExpression = createOperationCallExp(cExpression, "includingAll", createVariableExp(mRest));
VariableAssignment aRest = createVariableAssignment(mvcte, cExpression);
cMiddleBottomPattern.getAssignment().add(aRest);
}
}
// RDomainToMDBottomForEnforcement (second half)
protected void mapEnforcedDomainPatterns() throws CompilerChainException {
for (@NonNull TemplateExp rEnforcedRootTemplateExpression/*te*/ : rEnforcedRootTemplateExpressions) {
mapEnforcedTemplateExpression(rEnforcedRootTemplateExpression);
}
}
protected void mapEnforcedObjectTemplateExpression(@NonNull ObjectTemplateExp rEnforcedObjectTemplateExpression, @Nullable Key key) throws CompilerChainException {
Variable rTemplateVariable/*v*/ = QVTrelationUtil.getBindsTo(rEnforcedObjectTemplateExpression);
for (@NonNull PropertyTemplateItem pt : QVTrelationUtil.getOwnedParts(rEnforcedObjectTemplateExpression)) {
Property partProperty = QVTrelationUtil.getReferredProperty(pt);
OCLExpression rPartValue/*pte*/ = QVTrelationUtil.getOwnedValue(pt);
if ((key != null) && key.getPart().contains(partProperty)) {
// body of RDomainToMDBottomForEnforcementOfIdentityProp
addPropertyAssignmentToMiddleBottomPattern(rTemplateVariable, partProperty, rPartValue);
}
else if (rPartValue instanceof CollectionTemplateExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
CollectionTemplateExp cte = (CollectionTemplateExp)rPartValue;
/**
* Each PropertyTemplateItem whose value is a CollectionTemplateExp
* converts to a VariableAssignment and Predicates.
*
* ve1:T1{tp = ve2:Collection{a++b}} => ve2 := ve1.tp;
*/
/*Realized*/Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
Variable vcte = QVTrelationUtil.getBindsTo(cte);
Variable mvcte = variablesAnalysis.getCoreVariable(vcte);
NavigationCallExp pce = createNavigationCallExp(createVariableExp(cTemplateVariable), partProperty);
VariableAssignment a = createVariableAssignment(mvcte, pce);
cMiddleBottomPattern.getAssignment().add(a);
mapEnforcedTemplateExpression(cte);
}
else if (rPartValue instanceof ObjectTemplateExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropObject
ObjectTemplateExp ote = (ObjectTemplateExp)rPartValue;
Variable pv = ClassUtil.nonNullState(ote.getBindsTo());
/*Realized*/Variable cTargetVariable/*mpv*/ = variablesAnalysis.getCoreVariable(pv); //rWhenVariables.contains(pv) ? getCoreVariable(pv) : whenRealizedVariable(cEnforcedBottomPattern, pv);
// Variable cTemplateVariable/*mv*/ = variablesAnalysis.getCoreVariable(rTemplateVariable);
variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, createVariableExp(cTargetVariable), null);
mapEnforcedTemplateExpression(ote);
// Property cTargetProperty2 = qvtr2qvtc.getProperty(cMiddleRealizedVariable.getType(), cTargetVariable);
// variablesAnalysis.addNavigationAssignment(rMiddleRealizedVariable, cTargetProperty2, createVariableExp(cTargetVariable));
}
else if (rPartValue instanceof VariableExp) {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
// Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
//RDomainToMComposedMappingGuardrEnforcedDomain
Variable rPartVariable = QVTrelationUtil.getReferredVariable((VariableExp)rPartValue);
for (@NonNull TemplateExp rTemplateExpression : rEnforcedRootTemplateExpressions) {
if (rTemplateExpression instanceof ObjectTemplateExp) {
// check
if (isVarBoundToSomeOtherTemplate((ObjectTemplateExp) rTemplateExpression, rEnforcedObjectTemplateExpression, rPartVariable)) {
Variable cReferredVariable = variablesAnalysis.getCoreVariable(rPartVariable);
Property cTargetProperty = qvtr2qvtc.getTraceProperty(QVTrelationUtil.getType(cReferredVariable), cReferredVariable);
NavigationCallExp cPropertyCallExp = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), cTargetProperty);
variablesAnalysis.addConditionPredicate(cMiddleGuardPattern, cPropertyCallExp, createVariableExp(cReferredVariable));
cEnforcedGuardPattern.getBindsTo().add(cReferredVariable);
}
}
}
variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
if (!rAllOtherReferredVariables.contains(rPartVariable)) { // Avoid duplicate assignment
variablesAnalysis.addTraceNavigationAssignment(rPartVariable, false);
}
}
else {
// body of RDomainToMDBottomForEnforcementOfNonIdentityPropPrimitive
// Variable cTemplateVariable = variablesAnalysis.getCoreVariable(rTemplateVariable);
//RDomainToMComposedMappingGuardrEnforcedDomain
variablesAnalysis.addNavigationAssignment(rTemplateVariable, partProperty, mapExpression(rPartValue), null);
}
}
}
// RDomainToMDBottomForEnforcement
private void mapEnforcedTemplateExpression(@NonNull TemplateExp rEnforcedTemplateExpression/*te*/) throws CompilerChainException {
Variable rTemplateVariable/*v*/ = QVTrelationUtil.getBindsTo(rEnforcedTemplateExpression);
Type rTemplateVariableType/*c*/ = QVTrelationUtil.getType(rTemplateVariable);
Key key = qvtr2qvtc.getKeyForType(rTemplateVariableType);
VariableAnalysis variableAnalysis = variablesAnalysis.getVariableAnalysis(rTemplateVariable);
if (variableAnalysis.hasWhenDomain()) {
key = null;
}
// if (key == null){
// // Nothing to do
// }
/*else*/ if (rEnforcedTemplateExpression instanceof ObjectTemplateExp) {
mapEnforcedObjectTemplateExpression((ObjectTemplateExp)rEnforcedTemplateExpression, key);
}
else if (rEnforcedTemplateExpression instanceof CollectionTemplateExp) {
mapEnforcedCollectionTemplateExpression((CollectionTemplateExp)rEnforcedTemplateExpression, key);
}
else {
throw new CompilerChainException("Missing mapEnforcedTemplateExpression support " + rEnforcedTemplateExpression.eClass().getName());
}
// This call is wrong as the trace variable is realized, it can't be guarded.
// This should only be done in a nested mapping or later mapping
//doRDomainToMBottomPredicateForEnforcement(r, rd, te, predicatesWithoutVarBindings, unboundDomainVars, mb);
/*
* Creates the assignment of the middle model to the L/R models
*/
// RDomainVarToMDBottomAssignmnetForEnforcement
variablesAnalysis.addTraceNavigationAssignment(rTemplateVariable, false);
OCLExpression rGuardPredicate = rEnforcedTemplateExpression.getWhere();
if (rGuardPredicate != null) {
cMiddleGuardPattern.getPredicate().add(createPredicate(mapExpression(rGuardPredicate)));
}
}
// 15
/*
* Creates a Predicate, who's ConditionExpression is an
* OperationCallExp:
* trace.<v.name> = v;
* TODO Suggest better name: RDomainPatternVariableToTracePredicate?
*
private void doRDomainToMBottomPredicateForEnforcement(@NonNull Set<@NonNull Predicate> predicatesWithoutVarBindings, @NonNull Set<@NonNull Variable> unboundDomainVars) throws CompilerChainException
{
Set<@NonNull Variable> remainingUnBoundDomainVars = new HashSet<>(unboundDomainVars);
remainingUnBoundDomainVars.removeAll(rEnforcedRootVariables);
Set<@NonNull Predicate> predicatesWithVarBindings =
selectPredicatesThatReferToVariables(predicatesWithoutVarBindings, remainingUnBoundDomainVars);
mapPredicatesToPredicates(predicatesWithVarBindings);
// assign
for (@NonNull Variable v : rEnforcedRootVariables) {
@NonNull Variable mv = getCoreVariable(v);
Property pep = getProperty(cMiddleRealizedVariable.getType(), v);
NavigationCallExp pe = createNavigationCallExp(createVariableExp(cMiddleRealizedVariable), pep);
addConditionPredicate(cMiddleBottomPattern, pe, createVariableExp(mv));
}
} */
/*
* The issue with this method is that all variables should have been
* transformed so all variable references can be correctly pointed.
* However, if we call it after all variable modifying relations it
* should work.
*/
// 25
protected @NonNull OCLExpression mapExpression(@NonNull OCLExpression rExpression) {
EcoreUtil.Copier copier = new ExpressionCopier();
OCLExpression eOut = (OCLExpression) copier.copy(rExpression);
copier.copyReferences();
for (EObject eSource : copier.keySet()) {
EObject eTarget = copier.get(eSource);
if (eTarget != null) {
assert eSource != null;
putTrace((Element)eTarget, (Element)eSource);
}
}
assert eOut != null;
return eOut;
}
protected void mapIncomingInvocation() throws CompilerChainException {}
// IROppositeDomainsToMappingForEnforcement
protected void mapOtherDomainPatterns() throws CompilerChainException {
for (@NonNull AbstractOtherRelationDomain2CoreDomain otherDomain2coreDomain : otherDomain2coreDomains) {
otherDomain2coreDomain.synthesize();
}
}
// ROppositeDomainVarsToTraceClassProps
protected void mapOtherDomainVariables(@NonNull Set<@NonNull Variable> rDomainVariables) throws CompilerChainException {
for (@NonNull Variable rDomainVariable : rDomainVariables) {
// VariableAnalysis analysis = getVariableAnalysis(rDomainVariable);
// TemplateExp rTemplateExp = analysis.getTemplateExp();
// if (dvte instanceof ObjectTemplateExp) {
// tp=dv:T{...} => tcv.tp := dv;
variablesAnalysis.addTraceNavigationAssignment(rDomainVariable, true);
// }
/* else if (dvte instanceof CollectionTemplateExp) {
// tp=dv:T{...} => tcv.tp := dv;
Variable mdv = doRVarToMVar(dv);
// VariableExp ve1 = createVariableExp(tcv);
VariableExp ve2 = createVariableExp(mdv);
VariableAssignment a = createVariableAssignment(mdv, ve2);
mb.getAssignment().add(a);
} */
/* else if (dvte instanceof CollectionTemplateExp) {
CollectionTemplateExp collectionTemplateExp = (CollectionTemplateExp)dvte;
} */
}
}
// protected @NonNull Variable mapRealizedVariable(@NonNull Variable rVariable) {
// return whenRealizedVariable(cEnforcedBottomPattern, rVariable);
// }
protected abstract @NonNull AbstractEnforceableRelationDomain2CoreMapping mapOverrides(@NonNull AbstractQVTr2QVTcRelations relation2Mappings);
/**
* Transform a rule implemented by a black box into an enforcement operation
*
* @param rRelation the r
* @param rEnforcedDomain the rd
* @param cMiddleBottomPattern the mb
*/
// RRelImplToMBottomEnforcementOperation
protected void mapRelationImplementation() {
// TODO Code this when testing transformations with operational implementations.
}
// protected void mapVariables(@NonNull Iterable<@NonNull Variable> rVariables, @NonNull CorePattern cPattern) { // RVarSetToDGVarSet, RVarSetToMBVarSet
// for (@NonNull Variable rVariable : rVariables) {
// whenVariable(cPattern, rVariable);
// }
// }
// RWhenPatternToMGuardPattern
protected void mapWhenPattern() throws CompilerChainException {
Pattern rWhenPattern = rRelation.getWhen();
if (rWhenPattern != null) {
Set<@NonNull Variable> rMiddleGuardDomainVariables = new HashSet<>(rWhenVariable2rTypedModel.keySet());
rMiddleGuardDomainVariables.removeAll(rAllVariables);
//
for (@NonNull Predicate rWhenPredicate : QVTrelationUtil.getOwnedPredicates(rWhenPattern)) {
OCLExpression rConditionExpression = QVTrelationUtil.getConditionExpression(rWhenPredicate);
if (rConditionExpression instanceof RelationCallExp) {
// body of RWhenRelCallToMGuard
RelationCallExp rInvocation = (RelationCallExp)rConditionExpression;
Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rInvokedRelation);
int iSize = rArguments.size();
assert iSize == rParameters.size();
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 {
// body of RSimplePatternToMPattern
OCLExpression cConditionExpression = mapExpression(rConditionExpression);
variablesAnalysis.addPredicate(cMiddleGuardPattern, cConditionExpression);
// Predicate mpd = createPredicate(mapExpression(rConditionExpression)); // FIXME orphan
// addPredicate(composedMappingGuardPattern, cConditionExpression);
}
}
//doUnsharedWhenVarsToMgVars(unsharedWhenVars, mg);
// mapVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern);
}
}
// RPredicateSetToMBPredicateSet
protected void mapWhereBottomPredicates(@NonNull Iterable<@NonNull Predicate> rWherePredicates) throws CompilerChainException {
for (@NonNull Predicate rWherePredicate : rWherePredicates) {
OCLExpression rExpression = QVTrelationUtil.getConditionExpression(rWherePredicate);
variablesAnalysis.addPredicate(cMiddleBottomPattern, mapExpression(rExpression));
}
/*
// check
if(predSeq.isEmpty()) {
return;
}
Predicate rp = predSeq.remove(0);
OCLExpression re = rp.getConditionExpression();
assert re != null;
// init
@NonNull Predicate mp = createPredicate();
// when
@NonNull OCLExpression me = doRExpToMExp(re);
doRPredicateSetToMBPredicateSet(predSeq, mb);
// assign
mp.setConditionExpression(me);
mb.getPredicate().add(mp); */
}
// RDomainToMDBottomForEnforcement (first half)
protected void mapWhereGuardPredicates(@NonNull Set<@NonNull Predicate> rWhereGuardPredicates, @NonNull Set<@NonNull Variable> rEnforcedBottomDomainVariables) throws CompilerChainException
{
Set<@NonNull Variable> nonRootEnforcedBottomDomainVariables = new HashSet<>(rEnforcedBottomDomainVariables);
nonRootEnforcedBottomDomainVariables.removeAll(rEnforcedRootVariables);
//
Set<@NonNull Predicate> wherePredicatesWithVarBindings = selectPredicatesThatReferToVariables(rWhereGuardPredicates, nonRootEnforcedBottomDomainVariables);
Set<@NonNull Predicate> remainingWherePredicatesWithoutVarBindings = new HashSet<>(rWhereGuardPredicates);
remainingWherePredicatesWithoutVarBindings.removeAll(wherePredicatesWithVarBindings);
// FIXME How does this do anything?
}
protected void mapWherePattern() throws CompilerChainException {
Pattern rWherePattern = rRelation.getWhere();
if (rWherePattern != null) {
// Set<@NonNull Variable> rMiddleBottomDomainVariables = new HashSet<>(rWhenVariable2rTypedModel.keySet());
// rMiddleGuardDomainVariables.removeAll(rAllVariables);
//
for (@NonNull Predicate rWherePredicate : QVTrelationUtil.getOwnedPredicates(rWherePattern)) {
OCLExpression rConditionExpression = QVTrelationUtil.getConditionExpression(rWherePredicate);
if (rConditionExpression instanceof RelationCallExp) {
RelationCallExp rInvocation = (RelationCallExp)rConditionExpression;
Relation rInvokedRelation = QVTrelationUtil.getReferredRelation(rInvocation);
Type invokedSignatureClass/*tc*/ = qvtr2qvtc.getSignatureClass(rInvokedRelation);
List<@NonNull OCLExpression> rArguments = QVTrelationUtil.Internal.getOwnedArgumentsList(rInvocation);
String invokedName = "where_" + invokedSignatureClass.getName()/* + vdId*/;
Variable cInvocationVariable/*vd*/ = variablesAnalysis.addCoreRealizedVariable(invokedName, invokedSignatureClass); // FIXME
Property cInvocationProperty/*pep*/ = qvtr2qvtc.getTraceProperty(rInvocation);
variablesAnalysis.addTraceNavigationAssignment(cInvocationProperty, cInvocationVariable);
VariableAnalysis signatureVariableAnalysis = variablesAnalysis.getCoreVariableAnalysis(cInvocationVariable);
List<@NonNull Variable> rParameters = qvtr2qvtc.getRootVariables(rInvokedRelation);
int iSize = rArguments.size();
assert iSize == rParameters.size();
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 {
// body of RSimplePatternToMPattern
// OCLExpression cConditionExpression = mapExpression(rConditionExpression);
// variablesAnalysis.addPredicate(cMiddleGuardPattern, cConditionExpression);
// Predicate mpd = createPredicate(mapExpression(rConditionExpression)); // FIXME orphan
// addPredicate(composedMappingGuardPattern, cConditionExpression);
}
}
//doUnsharedWhenVarsToMgVars(unsharedWhenVars, mg);
// mapVariables(rMiddleGuardDomainVariables, cMiddleGuardPattern);
}
}
private void putTrace(@NonNull Element coreElement, @NonNull Element relationElement) {
Element oldRelationElement = target2source.put(coreElement, relationElement);
assert (oldRelationElement == relationElement) || (oldRelationElement == null);
List<@NonNull Element> targets = source2targets.get(relationElement);
if (targets == null) {
targets = new ArrayList<>();
source2targets.put(relationElement, targets);
}
targets.add(coreElement);
}
protected @NonNull Set<@NonNull Predicate> selectPredicatesThatReferToVariables(@NonNull Set<@NonNull Predicate> rPredicates, @NonNull Set<@NonNull Variable> rVariables) {
Set<@NonNull Predicate> rPredicatesThatReferToVariables = new HashSet<>();
for (@NonNull Predicate rPredicate : rPredicates) {
// OCLExpression conditionExpression = rPredicate.getConditionExpression();
// assert conditionExpression != null;
Set<@NonNull Variable> rPredicateVariables = new HashSet<>();
VariablesAnalysis.gatherReferredVariables(rPredicateVariables, rPredicate);
rPredicateVariables.retainAll(rVariables);
if (rPredicateVariables.isEmpty()) { // FIXME smelly polarity
rPredicatesThatReferToVariables.add(rPredicate);
}
}
return rPredicatesThatReferToVariables;
}
/**
* Exploit the constructed/analyzed context to synthesize the Core constructs.
* @throws CompilerChainException
*/
protected void synthesize() throws CompilerChainException {
// Relation rOverride = QVTrelationUtil.basicGetOverridden(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);
Set<@NonNull Predicate> rWhereGuardPredicates = new HashSet<>(rWherePredicates);
rWhereGuardPredicates.removeAll(rWhereBottomPredicates);
//
// Set<@NonNull Variable> rEnforcedDomainGuardVariables = getEnforcedDomainGuardVariables(rEnforcedBottomDomainVariables);
// Relation Calls
mapWhereBottomPredicates(rWhereBottomPredicates);
// mapVariables(rEnforcedDomainGuardVariables, cEnforcedGuardPattern);
// mapVariables(rMiddleBottomDomainVariables, cMiddleBottomPattern);
mapOtherDomainPatterns();
// Invoked here so the variables are instantiated
mapIncomingInvocation(); // Only for Invoked rather than Top relation
mapOtherDomainVariables(rAllOtherReferredVariables);
mapWhenPattern();
mapWhereGuardPredicates(rWhereGuardPredicates, rEnforcedBottomDomainVariables);
mapEnforcedDomainPatterns();
mapWherePattern();
if (rEnforcedMemberVariables != null) { // FIXME mapOtherDomainVariables duploication/irregularity
for (@NonNull Variable rMemberVariable : rEnforcedMemberVariables.keySet()) {
variablesAnalysis.addTraceNavigationAssignment(rMemberVariable, true);
}
}
mapRelationImplementation();
// Rule rOverrides = rRelation.getOverrides();
// if (rOverrides != null) {
// AbstractQVTr2QVTcRelations overridesRelation2mapping = qvtr2qvtc.getRelation2Mappings(rOverride)relation2relation2mapping.get(rOverrides);
// if (overridesRelation2mapping != null) {
// Mapping cMapping = relation2mapping.get
// }
// }
}
@Override
public @NonNull String toString() {
return rRelationName + "::" + rEnforcedDomainName + " => " + cMapping.getName() + "::" + cEnforcedDomain.getName();
}
}
/**
* 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
*/
protected final @NonNull Transformation cTransformation;
protected AbstractQVTr2QVTcRelations(@NonNull QVTr2QVTc qvtr2qvtc, @NonNull Relation rRelation) {
super(qvtr2qvtc.getEnvironmentFactory());
this.qvtr2qvtc = qvtr2qvtc;
this.rRelation = rRelation;
this.rTransformation = QVTrelationUtil.getTransformation(rRelation);
this.rRelationName = PivotUtil.getName(rRelation);
//
this.rWhenVariable2rTypedModel = new HashMap<>();
this.rWhenPredicates = new HashSet<>();
Pattern rWhenPattern = rRelation.getWhen();
if (rWhenPattern != null) {
VariablesAnalysis.gatherReferredVariablesWithTypedModels(rWhenVariable2rTypedModel, rWhenPattern);
// FIXME assert rWhenPattern.getBindsTo().equals(rWhenVariables);
// rWhenPattern.getBindsTo().addAll(rWhenVariables);
for (@NonNull Predicate rWhenPredicate : QVTrelationUtil.getOwnedPredicates(rWhenPattern)) {
if (!(rWhenPredicate.getConditionExpression() instanceof RelationCallExp)) { // FIXME Eliminate this redundant distinction
rWhenPredicates.add(rWhenPredicate);
}
}
}
//
this.rWhereVariable2rTypedModel = new HashMap<>();
this.rWherePredicates = new HashSet<>();
Pattern rWherePattern = rRelation.getWhere();
if (rWherePattern != null) {
VariablesAnalysis.gatherReferredVariablesWithTypedModels(rWhereVariable2rTypedModel, rWherePattern);
// FIXME assert rWherePattern.getBindsTo().equals(rWhereVariables);
// rWherePattern.getBindsTo().addAll(rWhereVariables);
for (@NonNull Predicate rWherePredicate : QVTrelationUtil.getOwnedPredicates(rWherePattern)) {
if (!(rWherePredicate.getConditionExpression() instanceof RelationCallExp)) {
rWherePredicates.add(rWherePredicate);
}
}
}
//
this.rAllVariables = new HashSet<>();
VariablesAnalysis.gatherReferredVariables(rAllVariables, QVTrelationUtil.getOwnedDomains(rRelation));
if (rWhenPattern != null) {
VariablesAnalysis.gatherReferredVariables(rAllVariables, rWhenPattern);
}
if (rWherePattern != null) {
VariablesAnalysis.gatherReferredVariables(rAllVariables, rWherePattern);
}
//
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.basicGetOverridden(rOverriding);
if (rOverridden != null) {
gatherOverrides(rOverridden);
}
}
else {
System.err.println("Override cycle for " + this + " at " + rOverriding);
};
}
/**
* Create an AbstractEnforceableRelationDomain2CoreMapping for each Core Mapping that is to be synthesized.
*/
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;
}
}