blob: bb81b709c443ac013716e26bf48d9d5dc96da2c9 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2015 Willink Transformations and others.
* 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:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.qvtd.xtext.qvtimperative.cs2as;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.ocl.pivot.Import;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.internal.utilities.PivotUtilInternal;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.xtext.base.cs2as.CS2ASConversion;
import org.eclipse.ocl.xtext.base.cs2as.Continuation;
import org.eclipse.ocl.xtext.base.utilities.BaseCSResource;
import org.eclipse.ocl.xtext.basecs.PathNameCS;
import org.eclipse.ocl.xtext.essentialoclcs.ExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.NameExpCS;
import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtbase.QVTbasePackage;
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.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.BottomPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.CoreDomain;
import org.eclipse.qvtd.pivot.qvtcorebase.EnforcementOperation;
import org.eclipse.qvtd.pivot.qvtcorebase.GuardPattern;
import org.eclipse.qvtd.pivot.qvtcorebase.PropertyAssignment;
import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBaseFactory;
import org.eclipse.qvtd.pivot.qvtcorebase.QVTcoreBasePackage;
import org.eclipse.qvtd.pivot.qvtcorebase.RealizedVariable;
import org.eclipse.qvtd.pivot.qvtcorebase.VariableAssignment;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeBottomPattern;
import org.eclipse.qvtd.pivot.qvtimperative.ImperativeModel;
import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCall;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCallBinding;
import org.eclipse.qvtd.pivot.qvtimperative.MappingLoop;
import org.eclipse.qvtd.pivot.qvtimperative.MappingSequence;
import org.eclipse.qvtd.pivot.qvtimperative.MappingStatement;
import org.eclipse.qvtd.pivot.qvtimperative.QVTimperativeFactory;
import org.eclipse.qvtd.pivot.qvtimperative.QVTimperativePackage;
import org.eclipse.qvtd.xtext.qvtcorebasecs.BottomPatternCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.DirectionCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.DomainCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.GuardPatternCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.PredicateCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.PredicateOrAssignmentCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.QueryCS;
import org.eclipse.qvtd.xtext.qvtcorebasecs.TransformationCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCallBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCallCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingLoopCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingSequenceCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.TopLevelCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.util.AbstractQVTimperativeCSContainmentVisitor;
import com.google.common.collect.Iterables;
public class QVTimperativeCSContainmentVisitor extends AbstractQVTimperativeCSContainmentVisitor
{
public QVTimperativeCSContainmentVisitor(@NonNull CS2ASConversion context) {
super(context);
}
@Override
public Continuation<?> visitBottomPatternCS(@NonNull BottomPatternCS csElement) {
@NonNull ImperativeBottomPattern pBottomPattern = context.refreshModelElement(ImperativeBottomPattern.class, QVTimperativePackage.Literals.IMPERATIVE_BOTTOM_PATTERN, csElement);
context.refreshPivotList(RealizedVariable.class, pBottomPattern.getRealizedVariable(), csElement.getOwnedRealizedVariables());
context.refreshPivotList(Variable.class, pBottomPattern.getVariable(), csElement.getOwnedUnrealizedVariables());
context.refreshPivotList(EnforcementOperation.class, pBottomPattern.getEnforcementOperation(), csElement.getOwnedEnforcementOperations());
context.refreshPivotList(Assignment.class, pBottomPattern.getOrderedAssignment(), Iterables.filter(csElement.getOwnedConstraints(), IsAssignmentPredicate.INSTANCE));
context.refreshPivotList(Predicate.class, pBottomPattern.getPredicate(), Iterables.filter(csElement.getOwnedConstraints(), IsPredicatePredicate.INSTANCE));
context.refreshComments(pBottomPattern, csElement);
return null;
}
@Override
public Continuation<?> visitDirectionCS(@NonNull DirectionCS csElement) {
Continuation<?> continuation = super.visitDirectionCS(csElement);
TypedModel asTypedModel = PivotUtil.getPivot(TypedModel.class, csElement);
if (asTypedModel != null) {
QVTbaseUtil.getContextVariable(standardLibrary, asTypedModel);
}
return continuation;
}
@Override
public Continuation<?> visitMappingCS(@NonNull MappingCS csElement) {
@NonNull Mapping pivotElement = refreshNamedElement(Mapping.class, QVTimperativePackage.Literals.MAPPING, csElement);
DomainCS csMiddle = csElement.getOwnedMiddle();
if (csMiddle != null) {
pivotElement.setBottomPattern(PivotUtil.getPivot(BottomPattern.class, csMiddle.getOwnedBottomPattern()));
pivotElement.setGuardPattern(PivotUtil.getPivot(GuardPattern.class, csMiddle.getOwnedGuardPattern()));
}
else {
BottomPattern bottomPattern = pivotElement.getBottomPattern();
if (bottomPattern == null) {
bottomPattern = QVTimperativeFactory.eINSTANCE.createImperativeBottomPattern();
bottomPattern.getAssignment().clear();
bottomPattern.getBindsTo().clear();
bottomPattern.getEnforcementOperation().clear();
bottomPattern.getPredicate().clear();
bottomPattern.getRealizedVariable().clear();
bottomPattern.getVariable().clear();
pivotElement.setBottomPattern(bottomPattern);
}
GuardPattern guardPattern = pivotElement.getGuardPattern();
if (guardPattern == null) {
guardPattern = QVTcoreBaseFactory.eINSTANCE.createGuardPattern();
guardPattern.getBindsTo().clear();
guardPattern.getPredicate().clear();
guardPattern.getVariable().clear();
pivotElement.setGuardPattern(guardPattern);
}
}
context.refreshPivotList(CoreDomain.class, pivotElement.getDomain(), csElement.getOwnedDomains());
pivotElement.setMappingStatement(PivotUtil.getPivot(MappingStatement.class, csElement.getOwnedMappingSequence()));
pivotElement.setIsDefault(csElement.isIsDefault());
return null;
}
@Override
public Continuation<?> visitMappingCallCS(@NonNull MappingCallCS csElement) {
@NonNull MappingCall pivotElement = context.refreshModelElement(MappingCall.class, QVTimperativePackage.Literals.MAPPING_CALL, csElement);
context.refreshPivotList(MappingCallBinding.class, pivotElement.getBinding(), csElement.getOwnedBindings());
pivotElement.setIsInfinite(csElement.isIsInfinite());
context.refreshComments(pivotElement, csElement);
return null;
}
@Override
public Continuation<?> visitMappingCallBindingCS(@NonNull MappingCallBindingCS csElement) {
@NonNull MappingCallBinding pivotElement = context.refreshModelElement(MappingCallBinding.class, QVTimperativePackage.Literals.MAPPING_CALL_BINDING, csElement);
pivotElement.setIsPolled(csElement.isIsPolled());
context.refreshComments(pivotElement, csElement);
return null;
}
@Override
public Continuation<?> visitMappingLoopCS(@NonNull MappingLoopCS csMappingLoop) {
@NonNull MappingLoop pivotElement = context.refreshModelElement(MappingLoop.class, QVTimperativePackage.Literals.MAPPING_LOOP, csMappingLoop);
@NonNull Variable iterator = refreshNamedElement(Variable.class, PivotPackage.Literals.VARIABLE, ClassUtil.nonNullState(csMappingLoop.getOwnedIterator()));
pivotElement.getOwnedIterators().clear();
pivotElement.getOwnedIterators().add(iterator);
pivotElement.setOwnedBody(PivotUtil.getPivot(MappingStatement.class, csMappingLoop.getOwnedMappingSequence()));
// CollectionType collectionType = metamodelManager.getCollectionType();
// DomainOperation forAllIteration = ClassUtil.getNamedElement(collectionType.getLocalOperations(), "forAll");
// pivotElement.setReferredIteration((Iteration) forAllIteration);
context.refreshComments(pivotElement, csMappingLoop);
return null;
}
@Override
public Continuation<?> visitMappingSequenceCS(@NonNull MappingSequenceCS csMappingSequence) {
@NonNull MappingSequence pivotElement = context.refreshModelElement(MappingSequence.class, QVTimperativePackage.Literals.MAPPING_SEQUENCE, csMappingSequence);
context.refreshPivotList(MappingStatement.class, pivotElement.getMappingStatements(), csMappingSequence.getOwnedMappingStatements());
return null;
}
@Override
public Continuation<?> visitPredicateCS(@NonNull PredicateCS csElement) {
context.refreshModelElement(Predicate.class, QVTbasePackage.Literals.PREDICATE, csElement);
return null;
}
@Override
public Continuation<?> visitPredicateOrAssignmentCS(@NonNull PredicateOrAssignmentCS csElement) {
ExpCS csTarget = csElement.getOwnedTarget();
EObject eContainer = csElement.eContainer();
if ((csElement.getOwnedInitExpression() == null) || (eContainer instanceof GuardPatternCS)) {
context.refreshModelElement(Predicate.class, QVTbasePackage.Literals.PREDICATE, csElement);
}
else if (csTarget instanceof NameExpCS) {
context.refreshModelElement(VariableAssignment.class, QVTcoreBasePackage.Literals.VARIABLE_ASSIGNMENT, csElement);
}
else {
context.refreshModelElement(PropertyAssignment.class, QVTcoreBasePackage.Literals.PROPERTY_ASSIGNMENT, csElement);
}
return null;
}
@Override
public Continuation<?> visitTopLevelCS(@NonNull TopLevelCS csElement) {
importPackages(csElement);
@NonNull ImperativeModel asModel = refreshRoot(ImperativeModel.class, QVTimperativePackage.Literals.IMPERATIVE_MODEL, csElement);
context.refreshPivotList(Import.class, asModel.getOwnedImports(), csElement.getOwnedImports());
List<TransformationCS> csTransformations = csElement.getOwnedTransformations();
// List<Transformation> txList = new ArrayList<Transformation>(csTransformations.size());
Map<Transformation, List<Mapping>> tx2mappings = new HashMap<Transformation, List<Mapping>>();
for (TransformationCS csTransformation : csTransformations) {
Transformation pTransformation = PivotUtil.getPivot(Transformation.class, csTransformation);
tx2mappings.put(pTransformation, new ArrayList<Mapping>());
// txList.add(pTransformation);
}
// ImperativeModel asModel = PivotUtil.getPivot(ImperativeModel.class, csElement);
// if (asModel != null) {
// PivotUtil.refreshList(asModel.getOwnedTransformations(), txList);
// }
// List<TransformationCS> csTransformations = csElement.getTransformations();
List<org.eclipse.ocl.pivot.Package> asPackages = resolveTransformations(csTransformations, asModel);
PivotUtilInternal.refreshList(asModel.getOwnedPackages(), asPackages);
//
Resource eResource = csElement.eResource();
if (eResource instanceof BaseCSResource) {
context.installRootElement((BaseCSResource)eResource, asModel); // Ensure containment viable for imported library type references
// importPackages(csElement); // FIXME This has to be after refreshPackage which is irregular and prevents local realization of ImportCS etc
}
//
for (MappingCS csMapping : csElement.getOwnedMappings()) {
PathNameCS csInPathName = csMapping.getOwnedInPathName();
if (csInPathName != null) {
Transformation asTransformation = lookupTransformation(csMapping, csInPathName, null);
if (asTransformation != null) {
List<Mapping> mappings = tx2mappings.get(asTransformation);
if (mappings != null) {
Mapping pMapping = PivotUtil.getPivot(Mapping.class, csMapping);
if (pMapping != null) {
mappings.add(pMapping);
}
}
}
}
}
Map<Transformation, List<Function>> tx2qMap = new HashMap<Transformation, List<Function>>();
for (QueryCS csQuery : csElement.getOwnedQueries()) {
Transformation transformation = csQuery.getTransformation();
Function query = PivotUtil.getPivot(Function.class, csQuery);
List<Function> queries = tx2qMap.get(transformation);
if (queries == null) {
queries = new ArrayList<Function>();
tx2qMap.put(transformation, queries);
}
queries.add(query);
}
for (Transformation pTransformation : tx2mappings.keySet()) {
PivotUtilInternal.refreshList(pTransformation.getRule(), tx2mappings.get(pTransformation));
List<Function> newElements = tx2qMap.get(pTransformation);
if (newElements != null) {
PivotUtilInternal.refreshList(pTransformation.getOwnedOperations(), newElements);
}
else {
pTransformation.getOwnedOperations().clear();
}
}
// context.refreshPivotList(Type.class, pivotElement.getOwnedType(), csElement.getOwnedType());
// context.refreshPivotList(org.eclipse.ocl.pivot.Package.class, pivotElement.getNestedPackage(), csElement.getOwnedNestedPackage());
return null;
}
@Override
public Continuation<?> visitTransformationCS( @NonNull TransformationCS csElement) {
Continuation<?> continuation = super.visitTransformationCS(csElement);
Transformation asTransformation = PivotUtil.getPivot(Transformation.class, csElement);
if (asTransformation != null) {
QVTbaseUtil.getContextVariable(standardLibrary, asTransformation);
}
return continuation;
}
}