blob: 57b48271602d85c1ef090122a9fedc85e2a88f88 [file] [log] [blame]
/**
* 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;
}
}