blob: 4ae4bed133dd7dccb74e8a831d8e32d9cd023fe5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010, 2017 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
* E.D.Willink (Obeo) - Bug 416287 - tuple-valued constraints
*******************************************************************************/
package org.eclipse.ocl.xtext.essentialocl.as2cs;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.BooleanLiteralExp;
import org.eclipse.ocl.pivot.CallExp;
import org.eclipse.ocl.pivot.CollectionItem;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.CollectionLiteralPart;
import org.eclipse.ocl.pivot.CollectionRange;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.EnumLiteralExp;
import org.eclipse.ocl.pivot.EnumerationLiteral;
import org.eclipse.ocl.pivot.ExpressionInOCL;
import org.eclipse.ocl.pivot.IfExp;
import org.eclipse.ocl.pivot.IntegerLiteralExp;
import org.eclipse.ocl.pivot.InvalidLiteralExp;
import org.eclipse.ocl.pivot.IterateExp;
import org.eclipse.ocl.pivot.IteratorExp;
import org.eclipse.ocl.pivot.LanguageExpression;
import org.eclipse.ocl.pivot.LetExp;
import org.eclipse.ocl.pivot.MapLiteralExp;
import org.eclipse.ocl.pivot.MapLiteralPart;
import org.eclipse.ocl.pivot.MessageExp;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.NavigationCallExp;
import org.eclipse.ocl.pivot.NullLiteralExp;
import org.eclipse.ocl.pivot.OCLExpression;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.PivotPackage;
import org.eclipse.ocl.pivot.Precedence;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.RealLiteralExp;
import org.eclipse.ocl.pivot.ShadowExp;
import org.eclipse.ocl.pivot.ShadowPart;
import org.eclipse.ocl.pivot.StateExp;
import org.eclipse.ocl.pivot.StringLiteralExp;
import org.eclipse.ocl.pivot.TupleLiteralExp;
import org.eclipse.ocl.pivot.TupleLiteralPart;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.TypeExp;
import org.eclipse.ocl.pivot.TypedElement;
import org.eclipse.ocl.pivot.UnlimitedNaturalLiteralExp;
import org.eclipse.ocl.pivot.Variable;
import org.eclipse.ocl.pivot.VariableDeclaration;
import org.eclipse.ocl.pivot.VariableExp;
import org.eclipse.ocl.pivot.ids.IdManager;
import org.eclipse.ocl.pivot.ids.TuplePartId;
import org.eclipse.ocl.pivot.ids.TupleTypeId;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.internal.complete.CompleteClassInternal;
import org.eclipse.ocl.pivot.internal.manager.PrecedenceManager;
import org.eclipse.ocl.pivot.internal.prettyprint.PrettyPrinter;
import org.eclipse.ocl.pivot.utilities.NameUtil;
import org.eclipse.ocl.pivot.utilities.PivotConstants;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
import org.eclipse.ocl.xtext.base.as2cs.AS2CSConversion;
import org.eclipse.ocl.xtext.base.as2cs.BaseDeclarationVisitor;
import org.eclipse.ocl.xtext.basecs.BaseCSFactory;
import org.eclipse.ocl.xtext.basecs.BaseCSPackage;
import org.eclipse.ocl.xtext.basecs.ConstraintCS;
import org.eclipse.ocl.xtext.basecs.ElementCS;
import org.eclipse.ocl.xtext.basecs.PathElementCS;
import org.eclipse.ocl.xtext.basecs.PathNameCS;
import org.eclipse.ocl.xtext.basecs.TypedRefCS;
import org.eclipse.ocl.xtext.essentialoclcs.BooleanLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.CollectionLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.CollectionLiteralPartCS;
import org.eclipse.ocl.xtext.essentialoclcs.CollectionTypeCS;
import org.eclipse.ocl.xtext.essentialoclcs.CurlyBracketedClauseCS;
import org.eclipse.ocl.xtext.essentialoclcs.EssentialOCLCSFactory;
import org.eclipse.ocl.xtext.essentialoclcs.EssentialOCLCSPackage;
import org.eclipse.ocl.xtext.essentialoclcs.ExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.ExpSpecificationCS;
import org.eclipse.ocl.xtext.essentialoclcs.IfExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.IfThenExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.InfixExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.InvalidLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.LetExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.LetVariableCS;
import org.eclipse.ocl.xtext.essentialoclcs.MapLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.MapLiteralPartCS;
import org.eclipse.ocl.xtext.essentialoclcs.MapTypeCS;
import org.eclipse.ocl.xtext.essentialoclcs.NameExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.NavigatingArgCS;
import org.eclipse.ocl.xtext.essentialoclcs.NestedExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.NullLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.NumberLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.PrefixExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.RoundBracketedClauseCS;
import org.eclipse.ocl.xtext.essentialoclcs.SelfExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.ShadowPartCS;
import org.eclipse.ocl.xtext.essentialoclcs.SquareBracketedClauseCS;
import org.eclipse.ocl.xtext.essentialoclcs.StringLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.TupleLiteralExpCS;
import org.eclipse.ocl.xtext.essentialoclcs.TupleLiteralPartCS;
import com.google.common.collect.Iterables;
public class EssentialOCLDeclarationVisitor extends BaseDeclarationVisitor
{
public static final @NonNull TuplePartId TUPLE_MESSAGE_STATUS_0 = IdManager.getTuplePartId(0, PivotConstants.MESSAGE_PART_NAME, TypeId.STRING);
public static final @NonNull TuplePartId TUPLE_MESSAGE_STATUS_1 = IdManager.getTuplePartId(1, PivotConstants.STATUS_PART_NAME, TypeId.BOOLEAN);
public static final @NonNull TupleTypeId TUPLE_MESSAGE_STATUS = IdManager.getTupleTypeId("Tuple", TUPLE_MESSAGE_STATUS_0, TUPLE_MESSAGE_STATUS_1);
public EssentialOCLDeclarationVisitor(@NonNull AS2CSConversion context) {
super(context);
}
protected ExpCS createExpCS(OCLExpression oclExpression) {
return context.visitDeclaration(ExpCS.class, oclExpression);
}
protected @NonNull InfixExpCS createInfixExpCS(ExpCS csSource, String operationName, ExpCS csArgument) {
InfixExpCS csNew = EssentialOCLCSFactory.eINSTANCE.createInfixExpCS();
csNew.setName(operationName);
csNew.setOwnedRight(csArgument);
if (csSource instanceof InfixExpCS) { // Must add additional InfixExpCS to transitive right.
InfixExpCS csRoot = (InfixExpCS)csSource;
InfixExpCS csParent = csRoot;
ExpCS csRight;
while ((csRight = csParent.getOwnedRight()) instanceof InfixExpCS) {
csParent = (InfixExpCS)csRight;
}
csParent.setOwnedRight(null); // Bypass child stealing detector
csNew.setOwnedLeft(csRight);
csParent.setOwnedRight(csNew);
return csRoot;
}
else {
csNew.setOwnedLeft(csSource);
return csNew;
}
}
protected @NonNull NameExpCS createNameExpCS(/*@NonNull*/NamedElement asNamedElement) {
NameExpCS csNameExp = EssentialOCLCSFactory.eINSTANCE.createNameExpCS();
PathNameCS csPathName = createPathNameCS(asNamedElement);
csNameExp.setOwnedPathName(csPathName);
return csNameExp;
}
protected @NonNull NameExpCS createNameExpCS(/*@NonNull*/ NamedElement asNamedElement, @Nullable Namespace scope) {
assert asNamedElement != null;
NameExpCS csNameExp = EssentialOCLCSFactory.eINSTANCE.createNameExpCS();
PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
csNameExp.setOwnedPathName(csPathName);
context.refreshPathName(csPathName, asNamedElement, scope);
return csNameExp;
}
protected @NonNull NavigatingArgCS createNavigatingArgCS(@Nullable String prefix, /*@NonNull*/ OCLExpression csExp) {
NavigatingArgCS csNavigatingArg = EssentialOCLCSFactory.eINSTANCE.createNavigatingArgCS();
csNavigatingArg.setPrefix(prefix);
csNavigatingArg.setOwnedNameExpression(createExpCS(csExp));
return csNavigatingArg;
}
protected NavigatingArgCS createNavigatingArgCS(@Nullable String prefix, /*@NonNull*/ NamedElement asNamedElement, @Nullable TypedElement asTypedElement, @Nullable OCLExpression csInit) {
NavigatingArgCS csNavigatingArg = EssentialOCLCSFactory.eINSTANCE.createNavigatingArgCS();
csNavigatingArg.setPrefix(prefix);
csNavigatingArg.setOwnedNameExpression(createNameExpCS(asNamedElement));
if (asTypedElement != null) {
csNavigatingArg.setOwnedType(createTypeRefCS(asTypedElement.getType()));
}
if (csInit != null) {
csNavigatingArg.setOwnedInitExpression(createExpCS(csInit));
}
return csNavigatingArg;
}
protected @NonNull ExpCS createNavigationOperatorCS(@NonNull CallExp asCallExp, @NonNull ExpCS csArgument, boolean isConverted) {
OCLExpression asSource = asCallExp.getOwnedSource();
if (asSource == null) {
return csArgument;
}
if (asSource instanceof VariableExp) {
VariableDeclaration asVariable = ((VariableExp)asSource).getReferredVariable();
if ((asVariable instanceof Variable) && ((Variable)asVariable).isIsImplicit()) { // Skip implicit iterator variables
return csArgument;
}
}
Type asType = asSource.getType();
boolean isAggregate = PivotUtil.isAggregate(asType) ^ isConverted;
String operationName = PivotUtil.getNavigationOperator(asCallExp.isIsSafe(), isAggregate);
ExpCS csSource = context.visitDeclaration(ExpCS.class, asSource);
if (asSource instanceof OperationCallExp) {
Precedence precedence = ((OperationCallExp)asSource).getReferredOperation().getPrecedence();
if (precedence != null) {
NestedExpCS csNestedExp = EssentialOCLCSFactory.eINSTANCE.createNestedExpCS();
csNestedExp.setOwnedExpression(csSource);
csSource = csNestedExp;
}
}
return createInfixExpCS(csSource, operationName, csArgument);
}
protected @NonNull PathNameCS createPathNameCS(NamedElement asNamedElement) {
PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
PathElementCS csPathElement = BaseCSFactory.eINSTANCE.createPathElementCS();
csPathElement.setReferredElement(asNamedElement);
csPathName.getOwnedPathElements().add(csPathElement);
return csPathName;
}
protected @NonNull SquareBracketedClauseCS createSquareBracketedClauseCS(@NonNull ExpCS @NonNull ... csExps) {
SquareBracketedClauseCS csSquareBracketedClause = EssentialOCLCSFactory.eINSTANCE.createSquareBracketedClauseCS();
for (@NonNull ExpCS csExp : csExps) {
csSquareBracketedClause.getOwnedTerms().add(csExp);
}
return csSquareBracketedClause;
}
protected @Nullable TypedRefCS createTypeRefCS(@Nullable Type asType) {
return asType != null ? context.visitReference(TypedRefCS.class, asType, null) : null;
}
protected @Nullable TypedRefCS createTypeRefCS(Type asType, @Nullable Namespace scope) {
return asType != null ? context.visitReference(TypedRefCS.class, asType, scope) : null;
}
/**
* Return a non-null operation from asOPeration, replacing any null value by the oclInvalidOperation.
*/
protected @NonNull Operation getNonNullOperation(@Nullable Operation asOperation) {
if (asOperation == null) {
asOperation = context.getMetamodelManager().getStandardLibrary().getOclInvalidOperation();
}
return asOperation;
}
/**
* Return a non-null property from asProperty, replacing any null value by the oclInvalidProperty.
*/
protected @NonNull Property getNonNullProperty(@Nullable Property asProperty) {
if (asProperty == null) {
asProperty = context.getMetamodelManager().getStandardLibrary().getOclInvalidProperty();
}
return asProperty;
}
/**
* Return a non-null type from asType, replacing any null value by the OclInvalidType.
*/
protected @NonNull Type getNonNullType(@Nullable Type asType) {
if (asType == null) {
asType = context.getMetamodelManager().getStandardLibrary().getOclInvalidType();
}
return asType;
}
protected boolean isLowerPrecedence(@Nullable OCLExpression asExp, @NonNull Precedence asThatPrecedence) {
if (!(asExp instanceof OperationCallExp)) {
return false;
}
Operation asOperation = ((OperationCallExp)asExp).getReferredOperation();
if (asOperation == null) {
return false;
}
Precedence asThisPrecedence = asOperation.getPrecedence();
if (asThisPrecedence == null) {
return false;
}
PrecedenceManager precedenceManager = context.getPrecedenceManager();
return precedenceManager.getOrder(asThisPrecedence) > precedenceManager.getOrder(asThatPrecedence);
}
protected ElementCS refreshConstraint(@NonNull ConstraintCS csElement, @NonNull Constraint object) {
if (object.eContainmentFeature() == PivotPackage.Literals.OPERATION__OWNED_POSTCONDITIONS) {
csElement.setStereotype(PivotConstants.POSTCONDITION_NAME);
}
else if (object.eContainmentFeature() == PivotPackage.Literals.OPERATION__OWNED_PRECONDITIONS) {
csElement.setStereotype(PivotConstants.PRECONDITION_NAME);
}
else {
csElement.setStereotype(PivotConstants.INVARIANT_NAME);
}
ExpSpecificationCS csStatus = null;
LanguageExpression specification = object.getOwnedSpecification();
if (specification instanceof ExpressionInOCL) {
OCLExpression bodyExpression = ((ExpressionInOCL)specification).getOwnedBody();
if ((bodyExpression instanceof TupleLiteralExp) && (bodyExpression.getTypeId() == TUPLE_MESSAGE_STATUS)) {
TupleLiteralPart messagePart = NameUtil.getNameable(((TupleLiteralExp)bodyExpression).getOwnedParts(), TUPLE_MESSAGE_STATUS_0.getName());
TupleLiteralPart statusPart = NameUtil.getNameable(((TupleLiteralExp)bodyExpression).getOwnedParts(), TUPLE_MESSAGE_STATUS_1.getName());
OCLExpression messageExpression = messagePart != null ? messagePart.getOwnedInit() : null;
OCLExpression statusExpression = statusPart != null ? statusPart.getOwnedInit() : null;
ExpSpecificationCS csMessage = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
csMessage.setExprString(messageExpression != null ? PrettyPrinter.print(messageExpression) : "null");
csElement.setOwnedMessageSpecification(csMessage);
csStatus = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
csStatus.setExprString(statusExpression != null ? PrettyPrinter.print(statusExpression) : "null");
}
else if (bodyExpression != null) {
csStatus = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
csStatus.setExprString(PrettyPrinter.print(bodyExpression));
}
}
if ((csStatus == null) && (specification != null)) {
String body = specification.getBody();
if (body != null) {
if (body.startsWith("Tuple")) {
String[] lines = body.split("\n");
int lastLineNumber = lines.length-1;
if ((lastLineNumber >= 3)
&& lines[0].replaceAll("\\s", "").equals("Tuple{")
&& lines[1].replaceAll("\\s", "").startsWith("message:String=")
&& lines[lastLineNumber].replaceAll("\\s", "").equals("}.status")) {
StringBuilder message = new StringBuilder();
message.append(lines[1].substring(lines[1].indexOf("=")+1, lines[1].length()).trim());
for (int i = 2; i < lastLineNumber; i++) {
if (!lines[i].replaceAll("\\s", "").startsWith("status:Boolean=")) {
message.append("\n" + lines[i]);
}
else {
ExpSpecificationCS csMessage = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
String messageString = message.toString();
int lastIndex = messageString.lastIndexOf(',');
if (lastIndex > 0) {
messageString = messageString.substring(0, lastIndex);
}
csMessage.setExprString(messageString);
csElement.setOwnedMessageSpecification(csMessage);
StringBuilder status = new StringBuilder();
status.append(lines[i].substring(lines[i].indexOf("=")+1, lines[i].length()).trim());
for (i++; i < lastLineNumber; i++) {
status.append("\n" + lines[i]);
}
csStatus = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
csStatus.setExprString(status.toString());
}
}
}
}
if (csStatus == null) {
csStatus = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, specification);
csStatus.setExprString(body);
}
}
}
// csElement.setSpecification(context.visitDeclaration(SpecificationCS.class, specification));
csElement.setOwnedSpecification(csStatus);
return csElement;
}
@Override
public @Nullable ElementCS visitBooleanLiteralExp(@NonNull BooleanLiteralExp asBooleanLiteralExp) {
BooleanLiteralExpCS csBooleanLiteralExp = EssentialOCLCSFactory.eINSTANCE.createBooleanLiteralExpCS();
csBooleanLiteralExp.setPivot(asBooleanLiteralExp);
csBooleanLiteralExp.setSymbol(Boolean.toString(asBooleanLiteralExp.isBooleanSymbol()));
return csBooleanLiteralExp;
}
@Override
public @Nullable ElementCS visitCallExp(@NonNull CallExp object) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable ElementCS visitCollectionItem(@NonNull CollectionItem asCollectionItem) {
CollectionLiteralPartCS csCollectionLiteralPart = EssentialOCLCSFactory.eINSTANCE.createCollectionLiteralPartCS();
csCollectionLiteralPart.setPivot(asCollectionItem);
csCollectionLiteralPart.setOwnedExpression(createExpCS(asCollectionItem.getOwnedItem()));
return csCollectionLiteralPart;
}
@Override
public @Nullable ElementCS visitCollectionLiteralExp(@NonNull CollectionLiteralExp asCollectionLiteralExp) {
CollectionLiteralExpCS csCollectionLiteralExp = EssentialOCLCSFactory.eINSTANCE.createCollectionLiteralExpCS();
csCollectionLiteralExp.setPivot(asCollectionLiteralExp);
csCollectionLiteralExp.setOwnedType((CollectionTypeCS) createTypeRefCS(asCollectionLiteralExp.getType()));
List<CollectionLiteralPartCS> csOwnedParts = csCollectionLiteralExp.getOwnedParts();
for (CollectionLiteralPart asPart : asCollectionLiteralExp.getOwnedParts()) {
csOwnedParts.add(context.visitDeclaration(CollectionLiteralPartCS.class, asPart));
}
return csCollectionLiteralExp;
}
@Override
public @Nullable ElementCS visitCollectionLiteralPart(@NonNull CollectionLiteralPart asCollectionLiteralPart) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable ElementCS visitCollectionRange(@NonNull CollectionRange asCollectionRange) {
CollectionLiteralPartCS csCollectionLiteralPart = EssentialOCLCSFactory.eINSTANCE.createCollectionLiteralPartCS();
csCollectionLiteralPart.setPivot(asCollectionRange);
csCollectionLiteralPart.setOwnedExpression(createExpCS(asCollectionRange.getOwnedFirst()));
csCollectionLiteralPart.setOwnedLastExpression(createExpCS(asCollectionRange.getOwnedLast()));
return csCollectionLiteralPart;
}
@Override
public ElementCS visitConstraint(@NonNull Constraint object) {
ConstraintCS csElement = context.refreshNamedElement(ConstraintCS.class, BaseCSPackage.Literals.CONSTRAINT_CS, object);
refreshConstraint(csElement, object);
return csElement;
}
@Override
public @Nullable ElementCS visitEnumLiteralExp(@NonNull EnumLiteralExp asEnumLiteralExp) {
EnumerationLiteral asEnumLiteral = asEnumLiteralExp.getReferredLiteral();
if (asEnumLiteral != null) {
NameExpCS csNameExp = EssentialOCLCSFactory.eINSTANCE.createNameExpCS();
PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
csNameExp.setOwnedPathName(csPathName);
context.refreshPathName(csPathName, asEnumLiteral, null);
// NameExpCS csNameExp = createNameExpCS(asEnumLiteral.getOwningEnumeration());
// PathElementCS csPathElement = BaseCSFactory.eINSTANCE.createPathElementCS();
// csPathElement.setReferredElement(asEnumLiteralExp.getReferredLiteral());
// csNameExp.getOwnedPathName().getOwnedPathElements().add(csPathElement);
return csNameExp;
}
else {
InvalidLiteralExpCS csInvalidLiteralExp = EssentialOCLCSFactory.eINSTANCE.createInvalidLiteralExpCS();
csInvalidLiteralExp.setPivot(asEnumLiteralExp);
return csInvalidLiteralExp;
}
}
// NameExpCS csNameExp = EssentialOCLCSFactory.eINSTANCE.createNameExpCS();
// PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
// csNameExp.setOwnedPathName(csPathName);
// Type asType = getNonNullType(asTypeExp.getReferredType());
// context.refreshPathName(csPathName, asType, null);
@Override
public ElementCS visitExpressionInOCL(@NonNull ExpressionInOCL object) {
OCLExpression bodyExpression = object.getOwnedBody();
if (bodyExpression != null) {
ExpSpecificationCS csElement = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, object);
String body = PrettyPrinter.print(bodyExpression);
csElement.setExprString(body);
return csElement;
}
String body = object.getBody();
if (body != null) {
ExpSpecificationCS csElement = context.refreshElement(ExpSpecificationCS.class, EssentialOCLCSPackage.Literals.EXP_SPECIFICATION_CS, object);
csElement.setExprString(body);
return csElement;
}
return null;
}
@Override
public @Nullable ElementCS visitIfExp(@NonNull IfExp asIfExp) {
if (!asIfExp.isIsElseIf()) {
IfExpCS csIfExp = EssentialOCLCSFactory.eINSTANCE.createIfExpCS();
csIfExp.setPivot(asIfExp);
csIfExp.setOwnedCondition(createExpCS(asIfExp.getOwnedCondition()));
csIfExp.setOwnedThenExpression(createExpCS(asIfExp.getOwnedThen()));
OCLExpression asElse = asIfExp.getOwnedElse();
while ((asElse instanceof IfExp) && (((IfExp)asElse).isIsElseIf())) {
ExpCS csElse = createExpCS(asElse);
csIfExp.getOwnedIfThenExpressions().add((IfThenExpCS) csElse);
asElse = ((IfExp)asElse).getOwnedElse();
}
ExpCS csElse = createExpCS(asElse);
csIfExp.setOwnedElseExpression(csElse);
return csIfExp;
}
else {
IfThenExpCS csIfThenExp = EssentialOCLCSFactory.eINSTANCE.createIfThenExpCS();
csIfThenExp.setPivot(asIfExp);
csIfThenExp.setOwnedCondition(createExpCS(asIfExp.getOwnedCondition()));
csIfThenExp.setOwnedThenExpression(createExpCS(asIfExp.getOwnedThen()));
return csIfThenExp;
}
}
@Override
public @Nullable ElementCS visitIntegerLiteralExp(@NonNull IntegerLiteralExp asIntegerLiteralExp) {
NumberLiteralExpCS csNumberLiteralExp = EssentialOCLCSFactory.eINSTANCE.createNumberLiteralExpCS();
csNumberLiteralExp.setPivot(asIntegerLiteralExp);
csNumberLiteralExp.setSymbol(asIntegerLiteralExp.getIntegerSymbol());
return csNumberLiteralExp;
}
@Override
public @Nullable ElementCS visitInvalidLiteralExp(@NonNull InvalidLiteralExp asInvalidLiteralExp) {
InvalidLiteralExpCS csInvalidLiteralExp = EssentialOCLCSFactory.eINSTANCE.createInvalidLiteralExpCS();
csInvalidLiteralExp.setPivot(asInvalidLiteralExp);
return csInvalidLiteralExp;
}
@Override
public @Nullable ElementCS visitIterateExp(@NonNull IterateExp asIterateExp) {
Operation asIteration = getNonNullOperation(asIterateExp.getReferredIteration());
NameExpCS csNameExp = createNameExpCS(asIteration);
csNameExp.setPivot(asIterateExp);
RoundBracketedClauseCS csRoundBracketedClause = EssentialOCLCSFactory.eINSTANCE.createRoundBracketedClauseCS();
csNameExp.setOwnedRoundBracketedClause(csRoundBracketedClause);;
String prefix = null;
for (Variable asIterator : asIterateExp.getOwnedIterators()) {
if (!asIterator.isIsImplicit()) {
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS(prefix, asIterator, asIterator, null));
prefix = ",";
}
}
Variable asResult = asIterateExp.getOwnedResult();
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS(";", asResult, asResult, asResult.getOwnedInit()));
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS("|", asIterateExp.getOwnedBody()));
return createNavigationOperatorCS(asIterateExp, csNameExp, false);
}
@Override
public @Nullable ElementCS visitIteratorExp(@NonNull IteratorExp asIteratorExp) {
OCLExpression body = asIteratorExp.getOwnedBody();
if (asIteratorExp.isIsImplicit() && (body instanceof CallExp)) { // Flatten implicit collect/oclAsSet
CallExp asCallExp = (CallExp)body;
OCLExpression asBodySource = asCallExp.getOwnedSource();
if (asBodySource instanceof VariableExp) {
VariableExp sourceVariableExp = (VariableExp)asBodySource;
if (sourceVariableExp.getReferredVariable() == asIteratorExp.getOwnedIterators().get(0)) {
if (body instanceof NavigationCallExp) {
NavigationCallExp asNavigationCallExp = (NavigationCallExp)body;
NameExpCS csNameExp = createNameExpCS(PivotUtil.getReferredProperty(asNavigationCallExp));
return createNavigationOperatorCS(asIteratorExp, csNameExp, true);
}
else {
ElementCS csExp = body.accept(this);
if (csExp instanceof ExpCS) {
return createNavigationOperatorCS(asIteratorExp, (ExpCS) csExp, true);
}
}
}
}
}
Operation asIteration = getNonNullOperation(asIteratorExp.getReferredIteration());
NameExpCS csNameExp = createNameExpCS(asIteration);
csNameExp.setPivot(asIteratorExp);
RoundBracketedClauseCS csRoundBracketedClause = EssentialOCLCSFactory.eINSTANCE.createRoundBracketedClauseCS();
csNameExp.setOwnedRoundBracketedClause(csRoundBracketedClause);;
String prefix = null;
for (Variable asIterator : asIteratorExp.getOwnedIterators()) {
if (!asIterator.isIsImplicit()) {
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS(prefix, asIterator, asIterator, null));
prefix = ",";
}
}
if (prefix != null) {
prefix = "|";
}
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS(prefix, body));
return createNavigationOperatorCS(asIteratorExp, csNameExp, false);
}
@Override
public @Nullable ElementCS visitLetExp(@NonNull LetExp asLetExp) {
LetExpCS csLetExp = EssentialOCLCSFactory.eINSTANCE.createLetExpCS();
csLetExp.setPivot(asLetExp);
csLetExp.setOwnedInExpression(createExpCS(asLetExp.getOwnedIn()));
Variable asVariable = asLetExp.getOwnedVariable();
LetVariableCS csLetVariable = EssentialOCLCSFactory.eINSTANCE.createLetVariableCS();
csLetVariable.setPivot(asVariable);
csLetVariable.setName(asVariable.getName());
csLetVariable.setOwnedInitExpression(createExpCS(asVariable.getOwnedInit()));
csLetVariable.setOwnedType(createTypeRefCS(asVariable.getType()));
csLetExp.getOwnedVariables().add(csLetVariable);
return csLetExp;
}
@Override
public @Nullable ElementCS visitMapLiteralExp(@NonNull MapLiteralExp asMapLiteralExp) {
MapLiteralExpCS csMapLiteralExp = EssentialOCLCSFactory.eINSTANCE.createMapLiteralExpCS();
csMapLiteralExp.setPivot(asMapLiteralExp);
csMapLiteralExp.setOwnedType((MapTypeCS) createTypeRefCS(asMapLiteralExp.getType()));
List<MapLiteralPartCS> csOwnedParts = csMapLiteralExp.getOwnedParts();
for (MapLiteralPart asPart : asMapLiteralExp.getOwnedParts()) {
csOwnedParts.add(context.visitDeclaration(MapLiteralPartCS.class, asPart));
}
return csMapLiteralExp;
}
@Override
public @Nullable ElementCS visitMapLiteralPart(@NonNull MapLiteralPart asMapLiteralPart) {
MapLiteralPartCS csMapLiteralPart = EssentialOCLCSFactory.eINSTANCE.createMapLiteralPartCS();
csMapLiteralPart.setPivot(asMapLiteralPart);
csMapLiteralPart.setOwnedKey(createExpCS(asMapLiteralPart.getOwnedKey()));
csMapLiteralPart.setOwnedValue(createExpCS(asMapLiteralPart.getOwnedValue()));
return csMapLiteralPart;
}
@Override
public @Nullable ElementCS visitMessageExp(@NonNull MessageExp object) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable ElementCS visitNavigationCallExp(@NonNull NavigationCallExp asNavigationCallExp) {
Property asProperty = PivotUtil.getReferredProperty(asNavigationCallExp);
NameExpCS csNameExp = createNameExpCS(asProperty);
Property asOpposite = asProperty.getOpposite();
if (asOpposite != null) {
String name = asProperty.getName();
Type type = asNavigationCallExp.getOwnedSource().getType();
if (type != null) {
CompleteClassInternal completeClass = context.getMetamodelManager().getCompleteClass(type);
Iterable<@NonNull Property> properties = completeClass.getProperties(name);
if ((properties != null) && Iterables.size(properties) > 1) {
NameExpCS csOppositeNameExp = createNameExpCS(asOpposite, null);
SquareBracketedClauseCS csSquareBracketedClause = createSquareBracketedClauseCS(csOppositeNameExp);
csNameExp.getOwnedSquareBracketedClauses().add(csSquareBracketedClause);
}
}
}
return createNavigationOperatorCS(asNavigationCallExp, csNameExp, false);
}
@Override
public @Nullable ElementCS visitNullLiteralExp(@NonNull NullLiteralExp asNullLiteralExp) {
NullLiteralExpCS csNullLiteralExp = EssentialOCLCSFactory.eINSTANCE.createNullLiteralExpCS();
csNullLiteralExp.setPivot(asNullLiteralExp);
return csNullLiteralExp;
}
@Override
public ElementCS visitOCLExpression(@NonNull OCLExpression object) {
return null;
}
@Override
public ElementCS visitOperationCallExp(@NonNull OperationCallExp asOperationCallExp) {
Operation asOperation = getNonNullOperation(asOperationCallExp.getReferredOperation());
String operationName = asOperation.getName();
Precedence asPrecedence = asOperation.getPrecedence();
List<OCLExpression> asArguments = asOperationCallExp.getOwnedArguments();
OCLExpression asSource = asOperationCallExp.getOwnedSource();
if ((asPrecedence == null) || (asSource == null)) {
if (asOperationCallExp.isIsImplicit()) { // oclAsSet
return createExpCS(asSource);
}
NameExpCS csNameExp = createNameExpCS(asOperationCallExp.getReferredOperation());
csNameExp.setPivot(asOperationCallExp);
RoundBracketedClauseCS csRoundBracketedClause = EssentialOCLCSFactory.eINSTANCE.createRoundBracketedClauseCS();
csNameExp.setOwnedRoundBracketedClause(csRoundBracketedClause);
String prefix = null;
for (OCLExpression asArgument : asArguments) {
csRoundBracketedClause.getOwnedArguments().add(createNavigatingArgCS(prefix, asArgument));
prefix = ",";
}
return createNavigationOperatorCS(asOperationCallExp, csNameExp, false);
}
else if (asArguments.size() == 1) {
ExpCS csSource;
if (isLowerPrecedence(asSource, asPrecedence)) {
ExpCS csExp = createExpCS(asSource);
NestedExpCS csNested = EssentialOCLCSFactory.eINSTANCE.createNestedExpCS();
csNested.setOwnedExpression(csExp);
csSource = csNested;
}
else {
csSource = context.visitDeclaration(ExpCS.class, asSource);
}
OCLExpression asArgument = asArguments.get(0);
ExpCS csArgument;
if (isLowerPrecedence(asArgument, asPrecedence)) {
ExpCS csExp = createExpCS(asArgument);
NestedExpCS csNested = EssentialOCLCSFactory.eINSTANCE.createNestedExpCS();
csNested.setOwnedExpression(csExp);
csArgument = csNested;
}
else {
csArgument = context.visitDeclaration(ExpCS.class, asArgument);
}
return createInfixExpCS(csSource, operationName, csArgument);
}
else {
ExpCS csSource;
if (isLowerPrecedence(asSource, asPrecedence)) {
ExpCS csExp = createExpCS(asSource);
NestedExpCS csNested = EssentialOCLCSFactory.eINSTANCE.createNestedExpCS();
csNested.setOwnedExpression(csExp);
csSource = csNested;
}
else {
csSource = context.visitDeclaration(ExpCS.class, asSource);
}
PrefixExpCS csPrefix = EssentialOCLCSFactory.eINSTANCE.createPrefixExpCS();
csPrefix.setName(operationName);
ExpCS csResult = csPrefix;
InfixExpCS csParent = null;
if (csSource instanceof InfixExpCS) {
csResult = csSource;
csParent = (InfixExpCS) csSource;
csSource = csParent.getOwnedLeft();
while (csSource instanceof InfixExpCS) {
csParent = (InfixExpCS) csSource;
csSource = csParent.getOwnedLeft();
}
csParent.setOwnedLeft(csPrefix);
}
csPrefix.setOwnedRight(csSource);
return csResult;
}
}
@Override
public @Nullable ElementCS visitRealLiteralExp(@NonNull RealLiteralExp asRealLiteralExp) {
NumberLiteralExpCS csNumberLiteralExp = EssentialOCLCSFactory.eINSTANCE.createNumberLiteralExpCS();
csNumberLiteralExp.setPivot(asRealLiteralExp);
csNumberLiteralExp.setSymbol(asRealLiteralExp.getRealSymbol());
return csNumberLiteralExp;
}
@Override
public @Nullable ElementCS visitShadowExp(@NonNull ShadowExp asShadowExp) {
NameExpCS csNameExp = createNameExpCS(asShadowExp.getType(), null);
csNameExp.setPivot(asShadowExp);
CurlyBracketedClauseCS csCurlyBracketedClause = EssentialOCLCSFactory.eINSTANCE.createCurlyBracketedClauseCS();
csNameExp.setOwnedCurlyBracketedClause(csCurlyBracketedClause);;
List<ShadowPartCS> csOwnedParts = csCurlyBracketedClause.getOwnedParts();
for (ShadowPart asPart : asShadowExp.getOwnedParts()) {
csOwnedParts.add(context.visitDeclaration(ShadowPartCS.class, asPart));
}
// csCurlyBracketedClause.setValue(asShadowExp.getValue());
// if ((csOwnedParts.size() == 0) && (csCurlyBracketedClause.getValue() == null)) {
// csCurlyBracketedClause.setValue("bad-value");
// }
return csNameExp;
}
@Override
public @Nullable ElementCS visitShadowPart(@NonNull ShadowPart asShadowPart) {
ShadowPartCS csShadowPart = EssentialOCLCSFactory.eINSTANCE.createShadowPartCS();
csShadowPart.setPivot(asShadowPart);
csShadowPart.setOwnedInitExpression(createExpCS(asShadowPart.getOwnedInit()));
csShadowPart.setReferredProperty(asShadowPart.getReferredProperty());
return csShadowPart;
}
@Override
public @Nullable ElementCS visitStateExp(@NonNull StateExp asStateExp) {
return createNameExpCS(asStateExp.getReferredState());
}
@Override
public @Nullable ElementCS visitStringLiteralExp(@NonNull StringLiteralExp asStringLiteralExp) {
StringLiteralExpCS csStringLiteralExp = EssentialOCLCSFactory.eINSTANCE.createStringLiteralExpCS();
csStringLiteralExp.setPivot(asStringLiteralExp);
csStringLiteralExp.getSegments().add(asStringLiteralExp.getStringSymbol());
return csStringLiteralExp;
}
@Override
public @Nullable ElementCS visitTupleLiteralExp(@NonNull TupleLiteralExp asTupleLiteralExp) {
TupleLiteralExpCS csTupleLiteralExp = EssentialOCLCSFactory.eINSTANCE.createTupleLiteralExpCS();
csTupleLiteralExp.setPivot(asTupleLiteralExp);
List<TupleLiteralPartCS> csOwnedParts = csTupleLiteralExp.getOwnedParts();
for (TupleLiteralPart asPart : asTupleLiteralExp.getOwnedParts()) {
csOwnedParts.add(context.visitDeclaration(TupleLiteralPartCS.class, asPart));
}
return csTupleLiteralExp;
}
@Override
public @Nullable ElementCS visitTupleLiteralPart(@NonNull TupleLiteralPart asTupleLiteralPart) {
TupleLiteralPartCS csTupleLiteralPart = EssentialOCLCSFactory.eINSTANCE.createTupleLiteralPartCS();
csTupleLiteralPart.setPivot(asTupleLiteralPart);
csTupleLiteralPart.setName(asTupleLiteralPart.getName());
csTupleLiteralPart.setOwnedType(createTypeRefCS(asTupleLiteralPart.getType()));
csTupleLiteralPart.setOwnedInitExpression(createExpCS(asTupleLiteralPart.getOwnedInit()));
return csTupleLiteralPart;
}
@Override
public @Nullable ElementCS visitTypeExp(@NonNull TypeExp asTypeExp) {
NameExpCS csNameExp = EssentialOCLCSFactory.eINSTANCE.createNameExpCS();
PathNameCS csPathName = BaseCSFactory.eINSTANCE.createPathNameCS();
csNameExp.setOwnedPathName(csPathName);
Type asType = getNonNullType(asTypeExp.getReferredType());
context.refreshPathName(csPathName, asType, null);
return csNameExp;
}
@Override
public @Nullable ElementCS visitUnlimitedNaturalLiteralExp(@NonNull UnlimitedNaturalLiteralExp asUnlimitedNaturalLiteralExp) {
NumberLiteralExpCS csNumberLiteralExp = EssentialOCLCSFactory.eINSTANCE.createNumberLiteralExpCS();
csNumberLiteralExp.setPivot(asUnlimitedNaturalLiteralExp);
csNumberLiteralExp.setSymbol(asUnlimitedNaturalLiteralExp.getUnlimitedNaturalSymbol());
return csNumberLiteralExp;
}
@Override
public @Nullable ElementCS visitVariable(@NonNull Variable object) {
throw new UnsupportedOperationException();
}
@Override
public @Nullable ElementCS visitVariableExp(@NonNull VariableExp asVariableExp) {
VariableDeclaration asVariable = asVariableExp.getReferredVariable();
if (asVariable != null) {
if (PivotConstants.SELF_NAME.equals(asVariable.getName())) {
EObject eContainer = asVariable.eContainer();
if (eContainer instanceof ExpressionInOCL) {
ExpressionInOCL asExpressionInOCL = (ExpressionInOCL)eContainer;
if (asVariable == asExpressionInOCL.getOwnedContext()) {
SelfExpCS csSelfExp = EssentialOCLCSFactory.eINSTANCE.createSelfExpCS();
csSelfExp.setPivot(asVariableExp);
return csSelfExp;
}
}
}
return createNameExpCS(asVariable);
}
else {
InvalidLiteralExpCS csInvalidLiteralExp = EssentialOCLCSFactory.eINSTANCE.createInvalidLiteralExpCS();
csInvalidLiteralExp.setPivot(asVariableExp);
return csInvalidLiteralExp;
}
}
}