use of org.eclipse.jdt.internal.compiler.lookup.TypeBinding 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.TypeBinding in project lombok by rzwitserloot.
the class PatchExtensionMethod method getApplicableExtensionMethods.
static List<Extension> getApplicableExtensionMethods(EclipseNode typeNode, Annotation ann, TypeBinding receiverType) {
List<Extension> extensions = new ArrayList<Extension>();
if ((typeNode != null) && (ann != null) && (receiverType != null)) {
BlockScope blockScope = ((TypeDeclaration) typeNode.get()).initializerScope;
EclipseNode annotationNode = typeNode.getNodeFor(ann);
AnnotationValues<ExtensionMethod> annotation = createAnnotation(ExtensionMethod.class, annotationNode);
boolean suppressBaseMethods = false;
try {
suppressBaseMethods = annotation.getInstance().suppressBaseMethods();
} catch (AnnotationValueDecodeFail fail) {
fail.owner.setError(fail.getMessage(), fail.idx);
}
for (Object extensionMethodProvider : annotation.getActualExpressions("value")) {
if (extensionMethodProvider instanceof ClassLiteralAccess) {
TypeBinding binding = ((ClassLiteralAccess) extensionMethodProvider).type.resolveType(blockScope);
if (binding == null)
continue;
if (!binding.isClass() && !binding.isEnum())
continue;
Extension e = new Extension();
e.extensionMethods = getApplicableExtensionMethodsDefinedInProvider(typeNode, (ReferenceBinding) binding, receiverType);
e.suppressBaseMethods = suppressBaseMethods;
extensions.add(e);
}
}
}
return extensions;
}
use of org.eclipse.jdt.internal.compiler.lookup.TypeBinding 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.TypeBinding 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.TypeBinding in project lombok by rzwitserloot.
the class PatchExtensionMethodCompletionProposal method getExtensionMethods.
private static List<Extension> getExtensionMethods(CompletionProposalCollector completionProposalCollector) {
List<Extension> extensions = new ArrayList<Extension>();
ClassScope classScope = getClassScope(completionProposalCollector);
if (classScope != null) {
TypeDeclaration decl = classScope.referenceContext;
TypeBinding firstParameterType = getFirstParameterType(decl, completionProposalCollector);
for (EclipseNode typeNode = getTypeNode(decl); typeNode != null; typeNode = upToType(typeNode)) {
Annotation ann = getAnnotation(ExtensionMethod.class, typeNode);
extensions.addAll(0, getApplicableExtensionMethods(typeNode, ann, firstParameterType));
}
}
return extensions;
}
Aggregations