| /******************************************************************************* |
| * 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; |
| } |
| } |
| } |