use of org.eclipse.jdt.internal.compiler.lookup.MethodBinding in project che by eclipse.
the class Util method getUnresolvedJavaElement.
/**
* Return the java element corresponding to the given compiler binding.
*/
public static JavaElement getUnresolvedJavaElement(MethodBinding methodBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
JavaElement unresolvedJavaElement = getUnresolvedJavaElement(methodBinding.declaringClass, workingCopyOwner, bindingsToNodes);
if (unresolvedJavaElement == null || unresolvedJavaElement.getElementType() != IJavaElement.TYPE) {
return null;
}
IType declaringType = (IType) unresolvedJavaElement;
org.eclipse.jdt.internal.compiler.ast.ASTNode node = bindingsToNodes == null ? null : bindingsToNodes.get(methodBinding);
if (node != null && !declaringType.isBinary()) {
if (node instanceof AnnotationMethodDeclaration) {
// node is an AnnotationMethodDeclaration
AnnotationMethodDeclaration typeMemberDeclaration = (AnnotationMethodDeclaration) node;
// annotation type members don't have parameters
return (JavaElement) declaringType.getMethod(String.valueOf(typeMemberDeclaration.selector), CharOperation.NO_STRINGS);
} else {
// node is an MethodDeclaration
MethodDeclaration methodDeclaration = (MethodDeclaration) node;
Argument[] arguments = methodDeclaration.arguments;
String[] parameterSignatures;
if (arguments != null) {
parameterSignatures = new String[arguments.length];
for (int i = 0; i < arguments.length; i++) {
Argument argument = arguments[i];
TypeReference typeReference = argument.type;
int arrayDim = typeReference.dimensions();
String typeSig = Signature.createTypeSignature(CharOperation.concatWith(typeReference.getTypeName(), '.'), false);
if (arrayDim > 0) {
typeSig = Signature.createArraySignature(typeSig, arrayDim);
}
parameterSignatures[i] = typeSig;
}
} else {
parameterSignatures = CharOperation.NO_STRINGS;
}
return (JavaElement) declaringType.getMethod(String.valueOf(methodDeclaration.selector), parameterSignatures);
}
} else {
// case of method not in the created AST, or a binary method
org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = methodBinding.original();
String selector = original.isConstructor() ? declaringType.getElementName() : new String(original.selector);
boolean isBinary = declaringType.isBinary();
ReferenceBinding enclosingType = original.declaringClass.enclosingType();
// Static inner types' constructors don't get receivers (https://bugs.eclipse.org/bugs/show_bug.cgi?id=388137)
boolean isInnerBinaryTypeConstructor = isBinary && original.isConstructor() && !original.declaringClass.isStatic() && enclosingType != null;
TypeBinding[] parameters = original.parameters;
int length = parameters == null ? 0 : parameters.length;
int declaringIndex = isInnerBinaryTypeConstructor ? 1 : 0;
String[] parameterSignatures = new String[declaringIndex + length];
if (isInnerBinaryTypeConstructor)
parameterSignatures[0] = new String(enclosingType.genericTypeSignature()).replace('/', '.');
for (int i = 0; i < length; i++) {
char[] signature = parameters[i].genericTypeSignature();
if (isBinary) {
signature = CharOperation.replaceOnCopy(signature, '/', '.');
} else {
signature = toUnresolvedTypeSignature(signature);
}
parameterSignatures[declaringIndex + i] = new String(signature);
}
IMethod result = declaringType.getMethod(selector, parameterSignatures);
if (isBinary)
return (JavaElement) result;
if (// if perfect match (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=249567 )
result.exists())
return (JavaElement) result;
IMethod[] methods = null;
try {
methods = declaringType.getMethods();
} catch (JavaModelException e) {
// declaring type doesn't exist
return null;
}
IMethod[] candidates = Member.findMethods(result, methods);
if (candidates == null || candidates.length == 0)
return null;
return (JavaElement) candidates[0];
}
}
use of org.eclipse.jdt.internal.compiler.lookup.MethodBinding in project lombok by rzwitserloot.
the class PatchExtensionMethod method resolveType.
public static TypeBinding resolveType(TypeBinding resolvedType, MessageSend methodCall, BlockScope scope) {
List<Extension> extensions = new ArrayList<Extension>();
TypeDeclaration decl = scope.classScope().referenceContext;
EclipseNode owningType = null;
for (EclipseNode typeNode = getTypeNode(decl); typeNode != null; typeNode = upToType(typeNode)) {
Annotation ann = getAnnotation(ExtensionMethod.class, typeNode);
if (ann != null) {
extensions.addAll(0, getApplicableExtensionMethods(typeNode, ann, methodCall.receiver.resolvedType));
if (owningType == null)
owningType = typeNode;
}
}
boolean skip = false;
if (methodCall.receiver instanceof ThisReference && (((ThisReference) methodCall.receiver).bits & ASTNode.IsImplicitThis) != 0)
skip = true;
if (methodCall.receiver instanceof SuperReference)
skip = true;
if (methodCall.receiver instanceof NameReference) {
Binding binding = ((NameReference) methodCall.receiver).binding;
if (binding instanceof TypeBinding)
skip = true;
}
if (!skip)
for (Extension extension : extensions) {
if (!extension.suppressBaseMethods && !(methodCall.binding instanceof ProblemMethodBinding))
continue;
for (MethodBinding extensionMethod : extension.extensionMethods) {
if (!Arrays.equals(methodCall.selector, extensionMethod.selector))
continue;
MessageSend_postponedErrors.clear(methodCall);
if (methodCall.receiver instanceof ThisReference) {
methodCall.receiver.bits &= ~ASTNode.IsImplicitThis;
}
List<Expression> arguments = new ArrayList<Expression>();
arguments.add(methodCall.receiver);
if (methodCall.arguments != null)
arguments.addAll(Arrays.asList(methodCall.arguments));
List<TypeBinding> argumentTypes = new ArrayList<TypeBinding>();
for (Expression argument : arguments) {
if (argument.resolvedType != null)
argumentTypes.add(argument.resolvedType);
// TODO: Instead of just skipping nulls entirely, there is probably a 'unresolved type' placeholder. THAT is what we ought to be adding here!
}
Expression[] originalArgs = methodCall.arguments;
methodCall.arguments = arguments.toArray(new Expression[0]);
MethodBinding fixedBinding = scope.getMethod(extensionMethod.declaringClass, methodCall.selector, argumentTypes.toArray(new TypeBinding[0]), methodCall);
if (fixedBinding instanceof ProblemMethodBinding) {
methodCall.arguments = originalArgs;
if (fixedBinding.declaringClass != null) {
PostponedInvalidMethodError.invoke(scope.problemReporter(), methodCall, fixedBinding, scope);
}
} else {
for (int i = 0, iend = arguments.size(); i < iend; i++) {
Expression arg = arguments.get(i);
if (fixedBinding.parameters[i].isArrayType() != arg.resolvedType.isArrayType())
break;
if (arg instanceof MessageSend) {
((MessageSend) arg).valueCast = arg.resolvedType;
}
if (!fixedBinding.parameters[i].isBaseType() && arg.resolvedType.isBaseType()) {
int id = arg.resolvedType.id;
// magic see TypeIds
arg.implicitConversion = TypeIds.BOXING | (id + (id << 4));
} else if (fixedBinding.parameters[i].isBaseType() && !arg.resolvedType.isBaseType()) {
int id = fixedBinding.parameters[i].id;
// magic see TypeIds
arg.implicitConversion = TypeIds.UNBOXING | (id + (id << 4));
}
}
methodCall.receiver = createNameRef(extensionMethod.declaringClass, methodCall);
methodCall.actualReceiverType = extensionMethod.declaringClass;
methodCall.binding = fixedBinding;
methodCall.resolvedType = methodCall.binding.returnType;
}
return methodCall.resolvedType;
}
}
PostponedError error = MessageSend_postponedErrors.get(methodCall);
if (error != null)
error.fire();
MessageSend_postponedErrors.clear(methodCall);
return resolvedType;
}
use of org.eclipse.jdt.internal.compiler.lookup.MethodBinding in project lombok by rzwitserloot.
the class PatchExtensionMethod method getApplicableExtensionMethodsDefinedInProvider.
private static List<MethodBinding> getApplicableExtensionMethodsDefinedInProvider(EclipseNode typeNode, ReferenceBinding extensionMethodProviderBinding, TypeBinding receiverType) {
List<MethodBinding> extensionMethods = new ArrayList<MethodBinding>();
CompilationUnitScope cuScope = ((CompilationUnitDeclaration) typeNode.top().get()).scope;
for (MethodBinding method : extensionMethodProviderBinding.methods()) {
if (!method.isStatic())
continue;
if (!method.isPublic())
continue;
if (method.parameters == null || method.parameters.length == 0)
continue;
TypeBinding firstArgType = method.parameters[0];
if (receiverType.isProvablyDistinct(firstArgType) && !receiverType.isCompatibleWith(firstArgType.erasure()))
continue;
TypeBinding[] argumentTypes = Arrays.copyOfRange(method.parameters, 1, method.parameters.length);
if ((receiverType instanceof ReferenceBinding) && ((ReferenceBinding) receiverType).getExactMethod(method.selector, argumentTypes, cuScope) != null)
continue;
extensionMethods.add(method);
}
return extensionMethods;
}
use of org.eclipse.jdt.internal.compiler.lookup.MethodBinding in project lombok by rzwitserloot.
the class PatchExtensionMethodCompletionProposal method getJavaCompletionProposals.
public static IJavaCompletionProposal[] getJavaCompletionProposals(IJavaCompletionProposal[] javaCompletionProposals, CompletionProposalCollector completionProposalCollector) {
List<IJavaCompletionProposal> proposals = new ArrayList<IJavaCompletionProposal>(Arrays.asList(javaCompletionProposals));
if (canExtendCodeAssist(proposals)) {
IJavaCompletionProposal firstProposal = proposals.get(0);
int replacementOffset = getReplacementOffset(firstProposal);
for (Extension extension : getExtensionMethods(completionProposalCollector)) {
for (MethodBinding method : extension.extensionMethods) {
ExtensionMethodCompletionProposal newProposal = new ExtensionMethodCompletionProposal(replacementOffset);
copyNameLookupAndCompletionEngine(completionProposalCollector, firstProposal, newProposal);
ASTNode node = getAssistNode(completionProposalCollector);
newProposal.setMethodBinding(method, node);
createAndAddJavaCompletionProposal(completionProposalCollector, newProposal, proposals);
}
}
}
return proposals.toArray(new IJavaCompletionProposal[proposals.size()]);
}
use of org.eclipse.jdt.internal.compiler.lookup.MethodBinding in project che by eclipse.
the class Util method getUnresolvedJavaElement.
/**
* Return the java element corresponding to the given compiler binding.
*/
public static JavaElement getUnresolvedJavaElement(TypeBinding typeBinding, WorkingCopyOwner workingCopyOwner, BindingsToNodesMap bindingsToNodes) {
if (typeBinding == null)
return null;
switch(typeBinding.kind()) {
case Binding.ARRAY_TYPE:
typeBinding = ((org.eclipse.jdt.internal.compiler.lookup.ArrayBinding) typeBinding).leafComponentType();
return getUnresolvedJavaElement(typeBinding, workingCopyOwner, bindingsToNodes);
case Binding.BASE_TYPE:
case Binding.WILDCARD_TYPE:
case Binding.INTERSECTION_TYPE:
return null;
default:
if (typeBinding.isCapture())
return null;
}
ReferenceBinding referenceBinding;
if (typeBinding.isParameterizedType() || typeBinding.isRawType())
referenceBinding = (ReferenceBinding) typeBinding.erasure();
else
referenceBinding = (ReferenceBinding) typeBinding;
char[] fileName = referenceBinding.getFileName();
if (referenceBinding.isLocalType() || referenceBinding.isAnonymousType()) {
// local or anonymous type
if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(fileName)) {
int jarSeparator = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, fileName);
// pkgEnd is exclusive
int pkgEnd = CharOperation.lastIndexOf('/', fileName);
if (pkgEnd == -1)
pkgEnd = CharOperation.lastIndexOf(File.separatorChar, fileName);
if (// if in a jar and no slash, it is a default package -> pkgEnd should be equal to jarSeparator
jarSeparator != -1 && pkgEnd < jarSeparator)
pkgEnd = jarSeparator;
if (pkgEnd == -1)
return null;
IPackageFragment pkg = getPackageFragment(fileName, pkgEnd, jarSeparator);
char[] constantPoolName = referenceBinding.constantPoolName();
if (constantPoolName == null) {
ClassFile classFile = (ClassFile) getClassFile(fileName);
return classFile == null ? null : (JavaElement) classFile.getType();
}
pkgEnd = CharOperation.lastIndexOf('/', constantPoolName);
char[] classFileName = CharOperation.subarray(constantPoolName, pkgEnd + 1, constantPoolName.length);
ClassFile classFile = (ClassFile) pkg.getClassFile(new String(classFileName) + SuffixConstants.SUFFIX_STRING_class);
return (JavaElement) classFile.getType();
}
ICompilationUnit cu = getCompilationUnit(fileName, workingCopyOwner);
if (cu == null)
return null;
// must use getElementAt(...) as there is no back pointer to the defining method (scope is null after resolution has ended)
try {
int sourceStart = ((org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding) referenceBinding).sourceStart;
return (JavaElement) cu.getElementAt(sourceStart);
} catch (JavaModelException e) {
// does not exist
return null;
}
} else if (referenceBinding.isTypeVariable()) {
// type parameter
final String typeVariableName = new String(referenceBinding.sourceName());
org.eclipse.jdt.internal.compiler.lookup.Binding declaringElement = ((org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding) referenceBinding).declaringElement;
if (declaringElement instanceof MethodBinding) {
IMethod declaringMethod = (IMethod) getUnresolvedJavaElement((MethodBinding) declaringElement, workingCopyOwner, bindingsToNodes);
return (JavaElement) declaringMethod.getTypeParameter(typeVariableName);
} else {
IType declaringType = (IType) getUnresolvedJavaElement((TypeBinding) declaringElement, workingCopyOwner, bindingsToNodes);
return (JavaElement) declaringType.getTypeParameter(typeVariableName);
}
} else {
// case of a WilCardBinding that doesn't have a corresponding Java element
if (fileName == null)
return null;
// member or top level type
TypeBinding declaringTypeBinding = typeBinding.enclosingType();
if (declaringTypeBinding == null) {
// top level type
if (org.eclipse.jdt.internal.compiler.util.Util.isClassFileName(fileName)) {
ClassFile classFile = (ClassFile) getClassFile(fileName);
if (classFile == null)
return null;
return (JavaElement) classFile.getType();
}
ICompilationUnit cu = getCompilationUnit(fileName, workingCopyOwner);
if (cu == null)
return null;
return (JavaElement) cu.getType(new String(referenceBinding.sourceName()));
} else {
// member type
IType declaringType = (IType) getUnresolvedJavaElement(declaringTypeBinding, workingCopyOwner, bindingsToNodes);
if (declaringType == null)
return null;
return (JavaElement) declaringType.getType(new String(referenceBinding.sourceName()));
}
}
}
Aggregations