blob: 5684eb7ca303728a16b718712265a29e2cc4f64b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2020 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
*******************************************************************************/
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.Property;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
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.basecs.ConstraintCS;
import org.eclipse.ocl.xtext.essentialoclcs.ExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.ShadowPartCS;
import org.eclipse.qvtd.pivot.qvtbase.Function;
import org.eclipse.qvtd.pivot.qvtimperative.AddStatement;
import org.eclipse.qvtd.pivot.qvtimperative.BufferStatement;
import org.eclipse.qvtd.pivot.qvtimperative.CheckStatement;
import org.eclipse.qvtd.pivot.qvtimperative.DeclareStatement;
import org.eclipse.qvtd.pivot.qvtimperative.EntryPoint;
import org.eclipse.qvtd.pivot.qvtimperative.GuardParameter;
import org.eclipse.qvtd.pivot.qvtimperative.LoopVariable;
import org.eclipse.qvtd.pivot.qvtimperative.MappingLoop;
import org.eclipse.qvtd.pivot.qvtimperative.NewStatement;
import org.eclipse.qvtd.pivot.qvtimperative.NewStatementPart;
import org.eclipse.qvtd.pivot.qvtimperative.SetStatement;
import org.eclipse.qvtd.pivot.qvtimperative.SimpleParameter;
import org.eclipse.qvtd.pivot.qvtimperative.SimpleParameterBinding;
import org.eclipse.qvtd.pivot.qvtimperative.SpeculateStatement;
import org.eclipse.qvtd.xtext.qvtimperativecs.AddStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.AppendParameterBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.BufferStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.CheckStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.DeclareStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.DirectionCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.EntryPointCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.GuardParameterBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.GuardParameterCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.LoopParameterBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.MappingLoopCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.NewStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.QueryCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.SetStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.SimpleParameterBindingCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.SimpleParameterCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.SpeculateStatementCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.TopLevelCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.TransformationCS;
import org.eclipse.qvtd.xtext.qvtimperativecs.util.AbstractQVTimperativeCSPostOrderVisitor;
public class QVTimperativeCSPostOrderVisitor extends AbstractQVTimperativeCSPostOrderVisitor
{
protected static class SimpleParameterBindingCSCompletion extends SingleContinuation<SimpleParameterBindingCS>
{
public SimpleParameterBindingCSCompletion(@NonNull CS2ASConversion context, @NonNull SimpleParameterBindingCS csElement) {
super(context, null, null, csElement);
}
@Override
public BasicContinuation<?> execute() {
SimpleParameterBinding pBinding = PivotUtil.getPivot(SimpleParameterBinding.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);
}
/* protected @Nullable Statement refreshPropertyAssignment(@NonNull NavigationCallExp 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(PivotUtil.getReferredProperty(propertyCallExp));
// propertyAssignment.setIsOpposite(target instanceof FeatureCallExp); // FIXME isOpposite
}
return propertyAssignment;
} */
@Override
public @Nullable Continuation<?> visitAddStatementCS(@NonNull AddStatementCS csElement) {
AddStatement asAddStatement = PivotUtil.getPivot(AddStatement.class, csElement);
if (asAddStatement != null) {
asAddStatement.setTargetVariable(csElement.getTargetVariable());
ExpCS csInitializer = csElement.getOwnedExpression();
if (csInitializer != null) {
OCLExpression initializer = context.visitLeft2Right(OCLExpression.class, csInitializer);
asAddStatement.setOwnedExpression(initializer);
}
}
return null;
}
@Override
public Continuation<?> visitAppendParameterBindingCS(@NonNull AppendParameterBindingCS csElement) {
return null;
}
@Override
public Continuation<?> visitBufferStatementCS(@NonNull BufferStatementCS csElement) {
BufferStatement asOutStatement = PivotUtil.getPivot(BufferStatement.class, csElement);
if (asOutStatement != null) {
ExpCS expression = csElement.getOwnedExpression();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
asOutStatement.setOwnedExpression(target);
if ((csElement.getOwnedType() == null) && (target != null)) {
Type targetType = target.getType();
boolean isRequired = target.isIsRequired();
if (targetType instanceof CollectionType) {
CollectionType collectionType = (CollectionType)targetType;
targetType = collectionType.getElementType();
isRequired = collectionType.isIsNullFree();
}
// FIXME else => error
// FIXME !isRequired => error
// FIXME isStrict
helper.setType(asOutStatement, targetType, isRequired, target.getTypeValue());
}
}
}
return null;
}
@Override
public Continuation<?> visitCheckStatementCS(@NonNull CheckStatementCS csElement) {
CheckStatement asPredicate = PivotUtil.getPivot(CheckStatement.class, csElement);
if (asPredicate != null) {
OCLExpression asCondition = null;
ExpCS csCondition = csElement.getOwnedCondition();
if (csCondition != null) {
asCondition = context.visitLeft2Right(OCLExpression.class, csCondition);
}
asPredicate.setOwnedExpression(asCondition);
}
return null;
}
@Override
public Continuation<?> visitConstraintCS(@NonNull ConstraintCS object) {
return null;
}
@Override
public Continuation<?> visitDeclareStatementCS(@NonNull DeclareStatementCS csElement) {
DeclareStatement asVariable = PivotUtil.getPivot(DeclareStatement.class, csElement);
if (asVariable != null) {
ExpCS expression = csElement.getOwnedExpression();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
asVariable.setOwnedExpression(target);
if ((csElement.getOwnedType() == null) && (target != null)) {
helper.setType(asVariable, target.getType(), target.isIsRequired(), target.getTypeValue());
}
}
}
return null;
}
/* @Override
public Continuation<?> visitCheckVariableStatementCS(@NonNull CheckVariableStatementCS csElement) {
ExpCS csTarget = csElement.getOwnedTarget();
assert csTarget != null;
OCLExpression target = context.visitLeft2Right(OCLExpression.class, csTarget);
ExpCS csInitializer = csElement.getOwnedExpression();
assert csInitializer != null;
CheckVariableStatement assignment = null;
if (target instanceof NavigationCallExp) {
throw new IllegalStateException();
}
else if (target instanceof VariableExp) {
CheckVariableStatement variableAssignment = PivotUtil.getPivot(CheckVariableStatement.class, csElement);
if (variableAssignment != null) {
variableAssignment.setTargetVariable(((VariableExp)target).getReferredVariable());
}
}
else if (target != null) {
context.addDiagnostic(csElement, "unrecognised Constraint target " + target.eClass().getName());
}
if (assignment != null) {
OCLExpression initializer = context.visitLeft2Right(OCLExpression.class, csInitializer);
assignment.setOwnedExpression(initializer);
// pAssignments.add(assignment);
}
return null;
} */
@Override
public Continuation<?> visitDirectionCS(@NonNull DirectionCS object) {
return null;
}
@Override
public @Nullable Continuation<?> visitEntryPointCS(@NonNull EntryPointCS csElement) {
EntryPoint asEntryPoint = PivotUtil.getPivot(EntryPoint.class, csElement);
if (asEntryPoint != null) {
context.refreshList(asEntryPoint.getInputTypedModels(), csElement.getInputTypedModels());
context.refreshList(asEntryPoint.getOutputTypedModels(), csElement.getOutputTypedModels());
}
return null;
}
@Override
public Continuation<?> visitGuardParameterCS(@NonNull GuardParameterCS csElement) {
GuardParameter asGuardParameter = PivotUtil.getPivot(GuardParameter.class, csElement);
if (asGuardParameter != null) {
asGuardParameter.setReferredTypedModel(csElement.getReferredTypedModel());
asGuardParameter.setSuccessProperty(csElement.getSuccessProperty());
}
return null;
}
@Override
public Continuation<?> visitGuardParameterBindingCS(@NonNull GuardParameterBindingCS csElement) {
return null;
}
@Override
public Continuation<?> visitLoopParameterBindingCS(@NonNull LoopParameterBindingCS csElement) {
return null;
}
@Override
public Continuation<?> visitMappingCS(@NonNull MappingCS csElement) {
return null;
}
@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);
if (target != null) {
pMappingLoop.setOwnedExpression(target);
List<LoopVariable> iterators = pMappingLoop.getOwnedIterators();
if (iterators.size() > 0) {
LoopVariable 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<?> visitNewStatementCS(@NonNull NewStatementCS csElement) {
NewStatement asNewStatement = PivotUtil.getPivot(NewStatement.class, csElement);
if (asNewStatement != null) {
asNewStatement.setReferredTypedModel(csElement.getReferredTypedModel());
ExpCS expression = csElement.getOwnedExpression();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
asNewStatement.setOwnedExpression(target);
}
}
return null;
}
@Override
public Continuation<?> visitQueryCS(@NonNull QueryCS csElement) {
Function pFunction = PivotUtil.getPivot(Function.class, csElement);
if (pFunction != null) {
ExpCS expression = csElement.getOwnedExpression();
if (expression != null) {
OCLExpression target = context.visitLeft2Right(OCLExpression.class, expression);
pFunction.setQueryExpression(target);
}
}
return null;
}
@Override
public Continuation<?> visitSetStatementCS(@NonNull SetStatementCS csElement) {
SetStatement setStatement = PivotUtil.getPivot(SetStatement.class, csElement);
if (setStatement != null) {
VariableDeclaration targetVariable = csElement.getReferredVariable();
assert targetVariable != null;
setStatement.setTargetVariable(targetVariable);
Property targetProperty = csElement.getReferredProperty();
boolean isImplicit = targetProperty.isIsImplicit();
setStatement.setTargetProperty(isImplicit ? targetProperty.getOpposite() : targetProperty);
setStatement.setIsOpposite(isImplicit);
ExpCS csInitializer = csElement.getOwnedExpression();
OCLExpression target = csInitializer != null ? context.visitLeft2Right(OCLExpression.class, csInitializer) : null;
setStatement.setOwnedExpression(target);
// pAssignments.add(assignment);
}
return null;
}
@Override
public @Nullable Continuation<?> visitShadowPartCS(@NonNull ShadowPartCS csShadowPart) {
if (QVTimperativeCS2AS.isNewStatementPartCS(csShadowPart)) {
NewStatementPart pivotElement = PivotUtil.getPivot(NewStatementPart.class, csShadowPart);
if (pivotElement != null) {
Property property = csShadowPart.getReferredProperty();
pivotElement.setReferredProperty(property);
ExpCS csInitExpression = csShadowPart.getOwnedInitExpression();
if (csInitExpression != null) {
OCLExpression initExpression = context.visitLeft2Right(OCLExpression.class, csInitExpression);
pivotElement.setOwnedExpression(initExpression);
}
}
return null;
}
return super.visitShadowPartCS(csShadowPart);
}
@Override
public Continuation<?> visitSimpleParameterCS(@NonNull SimpleParameterCS csElement) {
SimpleParameter asSimpleParameter = PivotUtil.getPivot(SimpleParameter.class, csElement);
if (asSimpleParameter != null) {
asSimpleParameter.setReferredTypedModel(csElement.getReferredTypedModel());
}
return null;
}
@Override
public Continuation<?> visitSimpleParameterBindingCS(@NonNull SimpleParameterBindingCS csElement) {
return new SimpleParameterBindingCSCompletion(context, csElement); // Must wait till MappingLoop iterators initialized
}
@Override
public Continuation<?> visitSpeculateStatementCS(@NonNull SpeculateStatementCS csElement) {
SpeculateStatement asSpeculateStatement = PivotUtil.getPivot(SpeculateStatement.class, csElement);
if (asSpeculateStatement != null) {
List<@NonNull OCLExpression> asExpressions = new ArrayList<>();
for (@NonNull ExpCS csExp : ClassUtil.nullFree(csElement.getOwnedConditions())) {
OCLExpression asExpression = context.visitLeft2Right(OCLExpression.class, csExp);
if (asExpression != null) {
asExpressions.add(asExpression);
}
}
context.refreshList(asSpeculateStatement.getOwnedExpressions(), asExpressions);
}
return null;
}
@Override
public Continuation<?> visitTopLevelCS(@NonNull TopLevelCS object) {
return null;
}
@Override
public Continuation<?> visitTransformationCS(@NonNull TransformationCS object) {
return null;
}
}