blob: 6f1e292542c0294629959d2fb8f72faea6d9c67d [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.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.CollectionType;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.PropertyCallExp;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.xtext.base.cs2as.BasicContinuation;
import org.eclipse.ocl.xtext.base.cs2as.CS2ASConversion;
import org.eclipse.ocl.xtext.base.cs2as.Continuation;
import org.eclipse.ocl.xtext.base.cs2as.SingleContinuation;
import org.eclipse.ocl.xtext.essentialoclcs.ExpCS;
import org.eclipse.qvtd.pivot.qvtbase.Predicate;
import org.eclipse.qvtd.pivot.qvtcorebase.Assignment;
import org.eclipse.qvtd.pivot.qvtcorebase.PropertyAssignment;
import org.eclipse.qvtd.pivot.qvtimperative.Mapping;
import org.eclipse.qvtd.pivot.qvtimperative.MappingCallBinding;
import org.eclipse.qvtd.pivot.qvtimperative.MappingLoop;
import org.eclipse.qvtd.pivot.qvtimperative.QVTimperativeFactory;
import org.eclipse.qvtd.pivot.qvtimperative.VariablePredicate;
import org.eclipse.qvtd.pivot.qvtimperative.utilities.QVTimperativeUtil;
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.UnrealizedVariableCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCallBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingLoopCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.TopLevelCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.util.AbstractQVTimperativeCSPostOrderVisitor;
public class QVTimperativeCSPostOrderVisitor extends AbstractQVTimperativeCSPostOrderVisitor
{
protected static class MappingCallBindingCSCompletion extends SingleContinuation<MappingCallBindingCS>
{
public MappingCallBindingCSCompletion(@NonNull CS2ASConversion context, @NonNull MappingCallBindingCS csElement) {
super(context, null, null, csElement);
}
@Override
public BasicContinuation<?> execute() {
MappingCallBinding pBinding = PivotUtil.getPivot(MappingCallBinding.class, csElement);
if (pBinding != null) {
ExpCS expression = csElement.getOwnedValue();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
pBinding.setValue(target);
}
}
return null;
}
}
public QVTimperativeCSPostOrderVisitor(@NonNull CS2ASConversion context) {
super(context);
}
@Override
protected @Nullable Assignment refreshPropertyAssignment(@NonNull PropertyCallExp propertyCallExp, @NonNull PredicateOrAssignmentCS csConstraint) {
@Nullable PropertyAssignment propertyAssignment;
// Property referredProperty = propertyCallExp.getReferredProperty();
// Property oppositeProperty = referredProperty.getOpposite();
// if ((oppositeProperty != null) && oppositeProperty.isIsImplicit()) {
// propertyAssignment = PivotUtil.getPivot(OppositePropertyAssignment.class, csConstraint);
// }
// else {
propertyAssignment = PivotUtil.getPivot(PropertyAssignment.class, csConstraint);
// }
if (propertyAssignment != null) {
propertyAssignment.setSlotExpression(propertyCallExp.getOwnedSource());
propertyAssignment.setTargetProperty(propertyCallExp.getReferredProperty());
}
return propertyAssignment;
}
@Override
public Continuation<?> visitMappingCS(@NonNull MappingCS csElement) {
Mapping asMapping = PivotUtil.getPivot(Mapping.class, csElement);
if (asMapping != null) {
List<VariablePredicate> asVariablePredicates = null;
for (DomainCS csDomain : csElement.getOwnedDomains()) {
GuardPatternCS csGuardPattern = csDomain.getOwnedGuardPattern();
for (UnrealizedVariableCS csVariable : csGuardPattern.getOwnedUnrealizedVariables()) {
Variable asVariable = PivotUtil.getPivot(Variable.class, csVariable);
if (asVariable != null) {
ExpCS csGuardExpression = csVariable.getOwnedInitExpression();
if (csGuardExpression != null) {
OCLExpression asExpression = context.visitLeft2Right(OCLExpression.class, csGuardExpression);
if (asExpression != null) {
VariablePredicate asVariablePredicate = QVTimperativeFactory.eINSTANCE.createVariablePredicate();
asVariablePredicate.setTargetVariable(asVariable);
asVariablePredicate.setConditionExpression(asExpression);
if (asVariablePredicates == null) {
asVariablePredicates = new ArrayList<VariablePredicate>();
}
asVariablePredicates.add(asVariablePredicate);
}
}
}
}
}
if (asVariablePredicates != null) {
List<Predicate> asPredicates = asMapping.getGuardPattern().getPredicate();
List<VariablePredicate> asSortedPredicates = QVTimperativeUtil.sortVariablePredicates(asMapping, asVariablePredicates);
int j = 0;
for (VariablePredicate asVariablePredicate : asSortedPredicates) {
asPredicates.add(j++, asVariablePredicate);
}
}
}
return null;
}
@Override
public Continuation<?> visitMappingCallBindingCS(@NonNull MappingCallBindingCS csElement) {
return new MappingCallBindingCSCompletion(context, csElement); // Must wait till MappingLoop iterators initialized
}
@Override
public Continuation<?> visitMappingLoopCS(@NonNull MappingLoopCS csElement) {
MappingLoop pMappingLoop = PivotUtil.getPivot(MappingLoop.class, csElement);
if (pMappingLoop != null) {
ExpCS expression = csElement.getOwnedInExpression();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
pMappingLoop.setOwnedSource(target);
List<Variable> iterators = pMappingLoop.getOwnedIterators();
if (iterators.size() > 0) {
Variable iterator = iterators.get(0);
if (iterator.getType() == null) {
Type type = target.getType();
if (type instanceof CollectionType) {
type = ((CollectionType)type).getElementType();
}
iterator.setType(type);
}
}
}
}
return null;
}
@Override
public Continuation<?> visitPredicateCS(@NonNull PredicateCS csElement) {
Predicate asPredicate = PivotUtil.getPivot(Predicate.class, csElement);
if (asPredicate != null) {
OCLExpression asCondition = null;
ExpCS csCondition = csElement.getOwnedCondition();
if (csCondition != null) {
asCondition = context.visitLeft2Right(OCLExpression.class, csCondition);
}
asPredicate.setConditionExpression(asCondition);
}
return null;
}
@Override
public Continuation<?> visitTopLevelCS(@NonNull TopLevelCS object) {
return null;
}
@Override
public Continuation<?> visitUnrealizedVariableCS(@NonNull UnrealizedVariableCS csElement) {
if (csElement.eContainer() instanceof GuardPatternCS) {
return null; // 'initExpression' is a guardExpression resolved by MappingCS
}
return super.visitUnrealizedVariableCS(csElement);
}
}