/** * Copyright (c) 2008 Borland Software Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alexander Shatalin (Borland) - initial API and implementation */ package org.eclipse.gmf.internal.xpand.migration; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EOperation; import org.eclipse.emf.ecore.EParameter; import org.eclipse.gmf.internal.xpand.BuiltinMetaModel; import org.eclipse.gmf.internal.xpand.expression.ExecutionContext; import org.eclipse.gmf.internal.xpand.expression.ast.DeclaredParameter; import org.eclipse.gmf.internal.xpand.xtend.ast.Extension; import org.eclipse.gmf.internal.xpand.xtend.ast.JavaExtensionStatement; public class OperationCallTrace extends ExpressionAnalyzeTrace { public enum Type { UNDESOLVED_PARAMETER_TYPE, UNDESOLVED_TARGET_TYPE, STATIC_EXTENSION_REF, OPERATION_REF, EXTENSION_REF, IMPLICIT_COLLECT_OPERATION_REF, IMPLICIT_COLLECT_EXTENSION_REF } private Type type; private EOperation operation; private EClassifier targetType; private List<EClassifier> paramTypes; private String nativeLibraryName; private boolean staticQvtoCall = true; /** * Migrating operation call as contextual only if there is another one * with same name and number of parameters in the _SAME_ file. * * No generic solution for externally added polymorphyc extensions for now */ public static boolean isStaticQvtoCall(ExecutionContext ctx, Extension extension) { if (extension.getFormalParameters().size() < 1) { return true; } Set<Extension> allExtensions = new HashSet<Extension>(ctx.getAllExtensions()); for (Iterator<Extension> it = allExtensions.iterator(); it.hasNext();) { Extension nextExtension = it.next(); if (!extension.getFileName().equals(nextExtension.getFileName()) || !extension.getName().equals(nextExtension.getName()) || extension.getParameterTypes().size() != nextExtension.getParameterTypes().size() || extension.isPrivate() ^ nextExtension.isPrivate()) { it.remove(); continue; } } return allExtensions.size() == 1; } public static String getNativeLibraryName(Extension extension) { if (extension instanceof JavaExtensionStatement) { return JavaExtensionDescriptor.getNativeLibraryName((JavaExtensionStatement) extension); } return null; } public static List<EClassifier> getParamTypes(EOperation op) { EList<EParameter> parameters = op.getEParameters(); List<EClassifier> result = new ArrayList<EClassifier>(); for (int i = 0; i < parameters.size(); i++) { result.add(BuiltinMetaModel.getTypedElementType(parameters.get(i))); } return result; } public static List<EClassifier> getParamTypes(Extension f, ExecutionContext ctx) { List<DeclaredParameter> formalParameters = f.getFormalParameters(); List<EClassifier> result = new ArrayList<EClassifier>(); for (int i = 0; i < formalParameters.size(); i++) { result.add(ctx.getTypeForName(formalParameters.get(i).getType().getValue())); } return result; } public OperationCallTrace(Type type) { this(null, null, null, type); } public OperationCallTrace(EClassifier result, List<EClassifier> paramTypes, String nativeLibraryName, Type type, boolean isStaticQvtoCall) { this(result, paramTypes, nativeLibraryName, type); this.staticQvtoCall = isStaticQvtoCall; } public OperationCallTrace(EClass result, List<EClassifier> paramTypes, EClassifier targetType, String nativeLibraryName, boolean isStaticQvtoCall) { this(result, paramTypes, nativeLibraryName, Type.IMPLICIT_COLLECT_EXTENSION_REF, isStaticQvtoCall); this.targetType = targetType; } public OperationCallTrace(EClassifier result, List<EClassifier> paramTypes, EClassifier targetType, EOperation operation, Type type) { this(result, paramTypes, null, type); this.targetType = targetType; this.operation = operation; } public OperationCallTrace(EClassifier result, List<EClassifier> paramTypes, EClassifier targetType, EOperation operation) { this(result, paramTypes, targetType, operation, OperationCallTrace.Type.OPERATION_REF); this.paramTypes = paramTypes; } private OperationCallTrace(EClassifier result, List<EClassifier> paramTypes, String nativeLibraryName, Type type) { super(result); this.paramTypes = paramTypes; this.type = type; this.nativeLibraryName = nativeLibraryName; } public Type getType() { return type; } /** * @return EOperation referenced by this OperationCall or null if getType() * != (OPERATION_REF || IMPLICIT_COLLECT_OPERATION_REF) */ public EOperation getEOperation() { return operation; } /** * @return EClassifier representing the type of OperationCall target or null * if getType() != (OPERATION_REF || IMPLICIT_COLLECT_OPERATION_REF * || IMPLICIT_COLLECT_EXTENSION_REF) */ public EClassifier getTargetType() { return targetType; } public List<EClassifier> getParamTypes() { return paramTypes; } public String getNativeLibraryName() { return nativeLibraryName; } /** * Reasonable is getType() == STATIC_EXTENSION_REF || EXTENSION_REF || * IMPLICIT_COLLECT_EXTENSION_REF */ public boolean isStaticQvtoCall() { return staticQvtoCall; } }