blob: ba56ba96eae9b6690c03c521c27c0ce153d12c76 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2022 CEA LIST 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(CEA LIST) - Initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.codegen.analyzer;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGAssertNonNullExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGBoxExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGBuiltInIterationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGCastExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGCatchExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGClass;
import org.eclipse.ocl.examples.codegen.cgmodel.CGCollectionExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGCollectionPart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGConstant;
import org.eclipse.ocl.examples.codegen.cgmodel.CGConstantExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGConstraint;
import org.eclipse.ocl.examples.codegen.cgmodel.CGEcoreExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGGuardExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIfExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIndexExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGInvalid;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsEqual2Exp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsEqualExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsInvalidExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsKindOfExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIsUndefinedExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGIterator;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLetExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLibraryIterateCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLibraryOperationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGLocalVariable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGMapExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGMapPart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGModel;
import org.eclipse.ocl.examples.codegen.cgmodel.CGModelPackage;
import org.eclipse.ocl.examples.codegen.cgmodel.CGNamedElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGNativeOperationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGOperation;
import org.eclipse.ocl.examples.codegen.cgmodel.CGOperationCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGOppositePropertyCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGPackage;
import org.eclipse.ocl.examples.codegen.cgmodel.CGParameter;
import org.eclipse.ocl.examples.codegen.cgmodel.CGPropertyCallExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGShadowExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGShadowPart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGString;
import org.eclipse.ocl.examples.codegen.cgmodel.CGThrowExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTupleExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTuplePart;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTypeId;
import org.eclipse.ocl.examples.codegen.cgmodel.CGTypedElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGUnboxExp;
import org.eclipse.ocl.examples.codegen.cgmodel.CGValuedElement;
import org.eclipse.ocl.examples.codegen.cgmodel.CGVariable;
import org.eclipse.ocl.examples.codegen.cgmodel.CGVariableExp;
import org.eclipse.ocl.examples.codegen.cgmodel.util.AbstractExtendingCGModelVisitor;
import org.eclipse.ocl.examples.codegen.utilities.CGModelResource;
import org.eclipse.ocl.examples.codegen.utilities.CGModelResourceFactory;
import org.eclipse.ocl.pivot.CollectionLiteralExp;
import org.eclipse.ocl.pivot.Iteration;
import org.eclipse.ocl.pivot.LoopExp;
import org.eclipse.ocl.pivot.NamedElement;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.OperationCallExp;
import org.eclipse.ocl.pivot.OppositePropertyCallExp;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.PropertyCallExp;
import org.eclipse.ocl.pivot.ShadowExp;
import org.eclipse.ocl.pivot.ShadowPart;
import org.eclipse.ocl.pivot.Type;
import org.eclipse.ocl.pivot.ids.TypeId;
import org.eclipse.ocl.pivot.library.LibraryOperation;
import org.eclipse.ocl.pivot.library.collection.CollectionExcludingOperation;
import org.eclipse.ocl.pivot.utilities.PivotUtil;
/**
* Converts an OCL expression to a string for debugging. This is not intended to
* be used by client applications as an AST-to-text transformation.
*/
public class CG2StringVisitor extends AbstractExtendingCGModelVisitor<@Nullable String, @Nullable Object>
{
private static final Logger logger = Logger.getLogger(CG2StringVisitor.class);
public static interface Factory extends Adapter {
@NonNull CG2StringVisitor createToStringVisitor();
@NonNull EPackage getEPackage();
}
private static @NonNull Map<EPackage, Factory> factoryMap = new HashMap<EPackage, Factory>();
public static synchronized void addFactory(@NonNull Factory factory) {
factoryMap.put(factory.getEPackage(), factory);
}
public static String toString(@NonNull CGElement cgElement) {
try {
Resource resource = cgElement.eResource();
if (resource instanceof CGModelResource) {
CGModelResourceFactory resourceFactory = ((CGModelResource)resource).getResourceFactory();
CG2StringVisitor v = resourceFactory.createToStringVisitor();
cgElement.accept(v);
return v.toString();
}
EPackage ePackage = cgElement.eClass().getEPackage();
Factory factory = factoryMap.get(ePackage);
if (factory == null) {
logger.error("No CG2StringVisitor Factory registered for " + ePackage.getName());
return "null";
}
CG2StringVisitor v = factory.createToStringVisitor();
cgElement.accept(v);
return v.toString();
}
catch (Throwable e) {
return e.toString();
}
}
protected abstract static class AbstractFactory extends AdapterImpl implements CG2StringVisitor.Factory
{
@Override
public boolean isAdapterForType(Object type) {
return type == CG2StringVisitor.Factory.class;
}
}
private static final class MyFactory extends AbstractFactory
{
private MyFactory() {
CG2StringVisitor.addFactory(this);
}
@Override
public @NonNull CG2StringVisitor createToStringVisitor() {
return new CG2StringVisitor();
}
@Override
public @NonNull EPackage getEPackage() {
CGModelPackage eInstance = CGModelPackage.eINSTANCE;
assert eInstance != null;
return eInstance;
}
}
public static CG2StringVisitor.@NonNull Factory FACTORY = new MyFactory();
/**
* Indicates where a required element in the AST was <code>null</code>, so
* that it is evident in the debugger that something was missing. We don't
* want just <code>"null"</code> because that would look like the OclVoid
* literal.
*/
protected static @NonNull String NULL_PLACEHOLDER = "\"<null>\"";
protected @NonNull StringBuilder result = new StringBuilder();
/**
* Initializes me.
*/
public CG2StringVisitor() {
super(Object.class); // Useless dummy object as context
}
protected void append(Number number) {
if (number != null) {
result.append(number.toString());
}
else {
result.append(NULL_PLACEHOLDER);
}
}
protected void append(String string) {
if (string != null) {
result.append(string);
}
else {
result.append(NULL_PLACEHOLDER);
}
}
protected void appendElementType(@Nullable CGTypedElement cgTypedElement) {
if (cgTypedElement == null) {
append(NULL_PLACEHOLDER);
}
else {
safeVisit(cgTypedElement.getTypeId());
if (!cgTypedElement.isRequired()) { // FIXME use CGVariable isNonNull too
append("[?]");
}
}
}
protected void appendName(CGNamedElement cgNamedElement) {
if (cgNamedElement == null) {
result.append(NULL_PLACEHOLDER);
}
else if (cgNamedElement.getName() != null) {
result.append(cgNamedElement.getName());
}
else if (cgNamedElement.getAst() instanceof NamedElement) {
appendName((NamedElement)cgNamedElement.getAst());
}
else {
result.append(NULL_PLACEHOLDER);
}
}
protected void appendName(NamedElement namedElement) {
if (namedElement == null) {
result.append(NULL_PLACEHOLDER);
}
else {
result.append(namedElement.getName());
}
}
protected void appendOperationSignature(CGOperation cgOperation) {
appendName(cgOperation);
append("(");
boolean comma = false;
for (java.util.Iterator<CGParameter> iter = cgOperation.getParameters().iterator(); iter.hasNext();) {
CGParameter parm = iter.next();
if (comma) {
append(", ");
} else {
comma = true;
}
appendName(parm);
append(" : ");
if (parm.getTypeId() != null) {
appendElementType(parm);
} else {
append(TypeId.OCL_VOID_NAME);
}
}
append(") :");
if (cgOperation.getTypeId() != null) {
append(" ");
appendElementType(cgOperation);
}
}
protected void appendPropertySignature(CGTypedElement cgElement) {
appendName(cgElement);
if (cgElement.getTypeId() != null) {
append(" : ");
appendElementType(cgElement);
}
}
protected void appendQualifiedName(CGNamedElement parent, String separator, CGNamedElement child) {
if (parent != null) {
appendQualifiedName(parent);
append(separator);
}
appendName(child);
}
protected void appendQualifiedName(@Nullable CGNamedElement object) {
if (object == null) {
result.append(NULL_PLACEHOLDER);
}
else {
EObject container = object.eContainer();
if (container instanceof CGNamedElement) {
appendQualifiedName((CGNamedElement) container);
append("::");
}
appendName(object);
}
}
@Override
public String toString() {
return result.toString();
}
@Override
public @Nullable String visitCGAssertNonNullExp(@NonNull CGAssertNonNullExp cgAssertNonNullExp) {
append("$ASSERT_NON_NULL(");
safeVisit(cgAssertNonNullExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGBoxExp(@NonNull CGBoxExp cgBoxExp) {
append("$BOX(");
safeVisit(cgBoxExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGBuiltInIterationCallExp(@NonNull CGBuiltInIterationCallExp cgExp) {
safeVisit(cgExp.getSource());
append("->");
appendName(cgExp.getAsIteration());
append("(");
boolean isFirst = true;
List<CGIterator> cgIterators = cgExp.getIterators();
List<CGIterator> cgCoIterators = cgExp.getCoIterators();
for (int i = 0; i < cgIterators.size(); i++) {
CGValuedElement cgIterator = cgIterators.get(i);
if (!isFirst) {
append(", ");
}
safeVisit(cgIterator);
if (i < cgCoIterators.size()) {
CGValuedElement cgCoIterator = cgCoIterators.get(i);
append(" with ");
safeVisit(cgCoIterator);
}
isFirst = false;
}
CGIterator cgAccumulator = cgExp.getAccumulator();
if (cgAccumulator != null) {
append("; ");
safeVisit(cgAccumulator);
}
append(" | ");
safeVisit(cgExp.getBody());
append(")");
return null;
}
@Override
public @Nullable String visitCGCastExp(@NonNull CGCastExp cgCastExp) {
append("$CAST(");
safeVisit(cgCastExp.getExecutorType());
append(",");
safeVisit(cgCastExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGCatchExp(@NonNull CGCatchExp cgCatchExp) {
append("$CATCH(");
safeVisit(cgCatchExp.getSource());
append(")");
return null;
}
@Override
public String visitCGClass(@NonNull CGClass cgClass) {
appendQualifiedName(cgClass);
return null;
}
@Override
public @Nullable String visitCGCollectionExp(@NonNull CGCollectionExp cgCollectionExp) {
append(((CollectionLiteralExp)cgCollectionExp.getAst()).getKind() + "{");
boolean isFirst = true;
for (CGCollectionPart cgPart : cgCollectionExp.getParts()) {
if (!isFirst) {
append(", ");
}
safeVisit(cgPart);
isFirst = false;
}
append("}");
return null;
}
@Override
public @Nullable String visitCGCollectionPart(@NonNull CGCollectionPart cgCollectionPart) {
safeVisit(cgCollectionPart.getFirst());
if (cgCollectionPart.isRange()) {
append(" .. ");
safeVisit(cgCollectionPart.getLast());
}
return null;
}
@Override
public @Nullable String visitCGConstant(@NonNull CGConstant cgConstant) {
append(cgConstant.getConstantValue().toString());
return null;
}
@Override
public @Nullable String visitCGConstantExp(@NonNull CGConstantExp cgConstantExp) {
CGValuedElement referredConstant = cgConstantExp.getReferredConstant();
if (referredConstant != null) {
referredConstant.accept(this);
}
return null;
}
@Override
public @Nullable String visitCGConstraint(@NonNull CGConstraint cgConstraint) {
appendName(cgConstraint);
append(": ");
safeVisit(cgConstraint.getBody());
return null;
}
@Override
public @Nullable String visitCGEcoreExp(@NonNull CGEcoreExp cgEcoreExp) {
String simpleName = "null";
EClassifier eClassifier = cgEcoreExp.getEClassifier();
if (eClassifier != null) {
Class<?> instanceClass = eClassifier.getInstanceClass();
if (instanceClass != null) {
simpleName = instanceClass.getSimpleName();
}
}
append("$ECORE(");
append(simpleName);
append(",");
safeVisit(cgEcoreExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGGuardExp(@NonNull CGGuardExp cgGuardExp) {
append("$GUARD(");
safeVisit(cgGuardExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGIfExp(@NonNull CGIfExp cgExp) {
append("if ");
safeVisit(cgExp.getCondition());
append(" then ");
safeVisit(cgExp.getThenExpression());
append(" else ");
safeVisit(cgExp.getElseExpression());
append(" endif");
return null;
}
@Override
public @Nullable String visitCGIndexExp(@NonNull CGIndexExp cgIndexExp) {
safeVisit(cgIndexExp.getSource());
append("[");
safeVisit(cgIndexExp.getIndex());
append("]");
return null;
}
@Override
public @Nullable String visitCGInvalid(@NonNull CGInvalid cgInvalid) {
String messageTemplate = cgInvalid.getMessageTemplate();
if (messageTemplate != null) {
append("$INVALID(" + messageTemplate + ")");
}
else {
append("invalid");
}
return null;
}
@Override
public @Nullable String visitCGIsEqualExp(@NonNull CGIsEqualExp cgIsEqualExp) {
append(cgIsEqualExp.isNotEquals() ? "$isNotEQUAL(" : "$isEQUAL(");
safeVisit(cgIsEqualExp.getSource());
append(",");
safeVisit(cgIsEqualExp.getArgument());
append(")");
return null;
}
@Override
public @Nullable String visitCGIsEqual2Exp(@NonNull CGIsEqual2Exp cgIsEqualExp) {
append("$isEQUAL2(");
safeVisit(cgIsEqualExp.getSource());
append(",");
safeVisit(cgIsEqualExp.getArgument());
append(")");
return null;
}
@Override
public @Nullable String visitCGIsInvalidExp(@NonNull CGIsInvalidExp cgIsInvalidExp) {
append("$isINVALID(");
safeVisit(cgIsInvalidExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGIsKindOfExp(@NonNull CGIsKindOfExp cgIsKindOfExp) {
append("$isKindOf(");
safeVisit(cgIsKindOfExp.getExecutorType());
append(",");
safeVisit(cgIsKindOfExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGIsUndefinedExp(@NonNull CGIsUndefinedExp cgIsUndefinedExp) {
append("$isUNDEFINED(");
safeVisit(cgIsUndefinedExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGIterationCallExp(@NonNull CGIterationCallExp ic) {
CGValuedElement source = ic.getSource();
safeVisit(source);
LoopExp iterationCallExp = (LoopExp) ic.getAst();
Iteration iter = iterationCallExp.getReferredIteration();
Type sourceType = source != null ? iterationCallExp.getOwnedSource().getType() : null;
append(PivotUtil.getNavigationOperator(false/*iterationCallExp.isIsSafe()*/, PivotUtil.isAggregate(sourceType)));
appendName(iter);
append("(");
String prefix = "";
List<CGIterator> cgIterators = ic.getIterators();
List<CGIterator> cgCoIterators = ic.getCoIterators();
for (int i = 0; i < cgIterators.size(); i++) {
CGValuedElement cgIterator = cgIterators.get(i);
append(prefix);
safeVisit(cgIterator);
if (i < cgCoIterators.size()) {
CGValuedElement cgCoIterator = cgCoIterators.get(i);
append(" with ");
safeVisit(cgCoIterator);
}
prefix = ", ";
}
if (ic instanceof CGLibraryIterateCallExp) {
append("; ");
safeVisit(((CGLibraryIterateCallExp)ic).getResult());
}
append(" | ");
safeVisit(ic.getBody());
append(")");
// appendAtPre(oc);
return null;
}
@Override
public @Nullable String visitCGIterator(@NonNull CGIterator cgElement) {
appendName(cgElement);
CGTypeId type = cgElement.getTypeId();
if (type != null) {
append(" : ");
appendElementType(cgElement);
}
CGValuedElement init = cgElement.getInit();
if (init != null) {
append(" = ");
init.accept(this);
}
return null;
}
@Override
public @Nullable String visitCGLetExp(@NonNull CGLetExp cgLetExp) {
append("let ");
safeVisit(cgLetExp.getInit());
append(" in (");
safeVisit(cgLetExp.getIn());
append(")");
return null;
}
@Override
public @Nullable String visitCGLibraryOperationCallExp(@NonNull CGLibraryOperationCallExp oc) {
OperationCallExp operationCallExp = (OperationCallExp) oc.getAst();
if (operationCallExp == null) {
String name;
LibraryOperation libraryOperation = oc.getLibraryOperation();
if (libraryOperation == CollectionExcludingOperation.INSTANCE) {
name = "excluding";
}
else {
name = libraryOperation.getClass().getSimpleName();
}
CGValuedElement cgThis = oc.getCgThis();
if (cgThis != null) {
safeVisit(cgThis);
}
append(".");
append(name);
append("(");
String prefix = "";
for (CGValuedElement argument : oc.getArguments()) {
append(prefix);
safeVisit(argument);
prefix = ", ";
}
append(")");
// appendAtPre(oc);
return null;
}
return visitCGOperationCallExp(oc);
}
@Override
public @Nullable String visitCGLocalVariable(@NonNull CGLocalVariable cgVariable) {
appendName(cgVariable);
CGTypeId type = cgVariable.getTypeId();
if (type != null) {
append(" : ");
appendElementType(cgVariable);
}
CGValuedElement initExpression = cgVariable.getInit();
if (initExpression != null) {
append(" = ");
safeVisit(initExpression);
}
return null;
}
@Override
public @Nullable String visitCGMapExp(@NonNull CGMapExp cgMapExp) {
append("Map{");
boolean isFirst = true;
for (CGMapPart cgPart : cgMapExp.getParts()) {
if (!isFirst) {
append(", ");
}
safeVisit(cgPart);
isFirst = false;
}
append("}");
return null;
}
@Override
public @Nullable String visitCGMapPart(@NonNull CGMapPart cgMapPart) {
safeVisit(cgMapPart.getKey());
append(" with ");
safeVisit(cgMapPart.getValue());
return null;
}
@Override
public @Nullable String visitCGModel(@NonNull CGModel cgModel) {
appendName(cgModel);
return null;
}
@Override
public @Nullable String visitCGNativeOperationCallExp(@NonNull CGNativeOperationCallExp oc) {
CGValuedElement cgThis = oc.getCgThis();
if (cgThis != null) {
safeVisit(cgThis);
append(".");
}
Method method = oc.getMethod();
append(method.getName());
append("(");
String prefix = "";
for (CGValuedElement argument : oc.getArguments()) {
append(prefix);
safeVisit(argument);
prefix = ", ";
}
append(")");
return null;
}
@Override
public @Nullable String visitCGOperation(@NonNull CGOperation cgOperation) {
appendQualifiedName(cgOperation.getContainingClass(), ".", cgOperation);
append("(");
boolean isFirst = true;
for (CGParameter cgParameter : cgOperation.getParameters()) {
if (!isFirst) {
append(",");
}
appendElementType(cgParameter);
isFirst = false;
}
append(") : ");
appendElementType(cgOperation);
return null;
}
@Override
public @Nullable String visitCGOperationCallExp(@NonNull CGOperationCallExp oc) {
CGValuedElement cgThis = oc.getCgThis();
safeVisit(cgThis);
OperationCallExp operationCallExp = (OperationCallExp) oc.getAst();
Operation oper = operationCallExp.getReferredOperation();
Type sourceType = operationCallExp.getOwnedSource() != null ? operationCallExp.getOwnedSource().getType() : null;
append(PivotUtil.getNavigationOperator(false/*operationCallExp.isIsSafe()*/, PivotUtil.isAggregate(sourceType)));
if (oper.isIsStatic()) {
appendName(oper.getOwningClass());
append("::");
}
appendName(oper);
append("(");
String prefix = "";
for (CGValuedElement argument : oc.getArguments()) {
append(prefix);
safeVisit(argument);
prefix = ", ";
}
append(")");
// appendAtPre(oc);
return null;
}
@Override
public @Nullable String visitCGOppositePropertyCallExp(@NonNull CGOppositePropertyCallExp pc) {
// source is null when the property call expression is an
// association class navigation qualifier
CGValuedElement source = pc.getSource();
safeVisit(source);
OppositePropertyCallExp propertyCallExp = (OppositePropertyCallExp) pc.getAst();
Property oppositeProperty = propertyCallExp.getReferredProperty();
Property property = oppositeProperty.getOpposite();
Type sourceType = source != null ? propertyCallExp.getOwnedSource().getType() : null;
append(PivotUtil.getNavigationOperator(false/*propertyCallExp.isIsSafe()*/, PivotUtil.isAggregate(sourceType)));
appendName(property);
/* appendAtPre(pc);
List<CGValuedElement> qualifiers = pc.getQualifier();
if (!qualifiers.isEmpty()) {
append("[");
String prefix = "";
for (OCLExpression qualifier : qualifiers) {
append(prefix);
safeVisit(qualifier);
prefix = ", ";
}
append("]");
} */
return null;
}
@Override
public @Nullable String visitCGPackage(@NonNull CGPackage cgPackage) {
appendQualifiedName(cgPackage);
return null;
}
@Override
public @Nullable String visitCGPropertyCallExp(@NonNull CGPropertyCallExp pc) {
// source is null when the property call expression is an
// association class navigation qualifier
CGValuedElement source = pc.getSource();
safeVisit(source);
PropertyCallExp propertyCallExp = (PropertyCallExp) pc.getAst();
if (propertyCallExp != null) {
Property property = propertyCallExp.getReferredProperty();
Type sourceType = source != null ? propertyCallExp.getOwnedSource().getType() : null;
append(PivotUtil.getNavigationOperator(false/*propertyCallExp.isIsSafe()*/, PivotUtil.isAggregate(sourceType)));
appendName(property);
}
else {
append("\"<.>\"");
appendName((CGNamedElement)null);
}
/* appendAtPre(pc);
List<CGValuedElement> qualifiers = pc.getQualifier();
if (!qualifiers.isEmpty()) {
append("[");
String prefix = "";
for (OCLExpression qualifier : qualifiers) {
append(prefix);
safeVisit(qualifier);
prefix = ", ";
}
append("]");
} */
return null;
}
// @Override
// public @Nullable String visitCGSelfParameter(@NonNull CGSelfParameter cgSelfParameter) {
// append(JavaConstants.THIS_NAME);
// return null;
// }
@Override
public @Nullable String visitCGShadowExp(@NonNull CGShadowExp cgShadowExp) {
appendName(((ShadowExp)cgShadowExp.getAst()).getType());
append("{");
boolean isFirst = true;
for (CGShadowPart cgPart : cgShadowExp.getParts()) {
if (!isFirst) {
append(", ");
}
safeVisit(cgPart);
isFirst = false;
}
append("}");
return null;
}
@Override
public @Nullable String visitCGShadowPart(@NonNull CGShadowPart cgShadowPart) {
appendName(((ShadowPart)cgShadowPart.getAst()).getReferredProperty());
append(" with ");
safeVisit(cgShadowPart.getInit());
return null;
}
@Override
public @Nullable String visitCGString(@NonNull CGString cgString) {
append("'");
append(cgString.getStringValue());
append("'");
return null;
}
@Override
public @Nullable String visitCGThrowExp(@NonNull CGThrowExp cgThrowExp) {
append("$THROW(");
safeVisit(cgThrowExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGTupleExp(@NonNull CGTupleExp cgTupleExp) {
append("Tuple{");
String prefix = "";
for (CGTuplePart part : cgTupleExp.getParts()) {
append(prefix);
safeVisit(part);
prefix = ", ";
}
append("}");
return null;
}
@Override
public @Nullable String visitCGTuplePart(@NonNull CGTuplePart cgTuplePart) {
appendName(cgTuplePart);
CGTypeId type = cgTuplePart.getTypeId();
if (type != null) {
append(" : ");
appendElementType(cgTuplePart);
}
CGValuedElement initExpression = cgTuplePart.getInit();
if (initExpression != null) {
append(" = ");
safeVisit(initExpression);
}
return null;
}
@Override
public @Nullable String visitCGUnboxExp(@NonNull CGUnboxExp cgUnboxExp) {
append("$UNBOX(");
safeVisit(cgUnboxExp.getSource());
append(")");
return null;
}
@Override
public @Nullable String visitCGValuedElement(@NonNull CGValuedElement cgElement) {
appendName(cgElement);
// CGTypeId type = cgElement.getTypeId();
// append(" : ");
// if (type != null) {
// appendElementType(cgElement);
// }
return null;
}
@Override
public @Nullable String visitCGVariable(@NonNull CGVariable cgElement) {
appendName(cgElement);
CGValuedElement init = cgElement.getInit();
if (init != null) {
append(" = ");
init.accept(this);
}
else {
CGTypeId type = cgElement.getTypeId();
if (type != null) {
append(" : ");
appendElementType(cgElement);
}
}
return null;
}
@Override
public @Nullable String visitCGVariableExp(@NonNull CGVariableExp cgVariableExp) {
appendName(cgVariableExp.getReferredVariable());
return null;
}
@Override
public @Nullable String visiting(@NonNull CGElement visitable) {
append(visitable.getClass().getName());
return null;
}
}