Copyright (c) 2000, 2019 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Stephan Herrmann - Contribution for Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda
/******************************************************************************* * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for * Bug 342671 - ClassCastException: org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding cannot be cast to org.eclipse.jdt.internal.compiler.lookup.ArrayBinding * Bug 429813 - [1.8][dom ast] IMethodBinding#getJavaElement() should return IMethod for lambda *******************************************************************************/
package org.eclipse.jdt.core.dom; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.dom.MethodBinding.LambdaMethod; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; import org.eclipse.jdt.internal.compiler.ast.ImportReference; import org.eclipse.jdt.internal.compiler.ast.JavadocAllocationExpression; import org.eclipse.jdt.internal.compiler.ast.JavadocFieldReference; import org.eclipse.jdt.internal.compiler.ast.JavadocImplicitTypeReference; import org.eclipse.jdt.internal.compiler.ast.JavadocMessageSend; import org.eclipse.jdt.internal.compiler.ast.JavadocQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.JavadocSingleNameReference; import org.eclipse.jdt.internal.compiler.ast.JavadocSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.Literal; import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.ModuleReference; import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.Receiver; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; import org.eclipse.jdt.internal.compiler.lookup.ElementValuePair; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemPackageBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons; import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding; import org.eclipse.jdt.internal.compiler.lookup.TagBits; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.lookup.VoidTypeBinding; import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; import org.eclipse.jdt.internal.core.util.Util;
Internal class for resolving bindings using old ASTs.

IMPORTANT: The methods on this class are synchronized. This is required because there may be multiple clients in separate threads concurrently reading an AST and asking for bindings for its nodes. These requests all end up invoking instance methods on this class. There are various internal tables and caches which are built and maintained in the course of looking up bindings. To ensure that they remain coherent in the presence of multiple threads, the methods are synchronized on the DefaultBindingResolver instance.

/** * Internal class for resolving bindings using old ASTs. * <p> * IMPORTANT: The methods on this class are synchronized. This is required * because there may be multiple clients in separate threads concurrently * reading an AST and asking for bindings for its nodes. These requests all * end up invoking instance methods on this class. There are various internal * tables and caches which are built and maintained in the course of looking * up bindings. To ensure that they remain coherent in the presence of multiple * threads, the methods are synchronized on the DefaultBindingResolver instance. * </p> */
@SuppressWarnings({ "rawtypes", "unchecked" }) class DefaultBindingResolver extends BindingResolver { /* * Holds on binding tables that can be shared by several ASTs. */ static class BindingTables {
This map is used to get a binding from its binding key.
/** * This map is used to get a binding from its binding key. */
Map bindingKeysToBindings;
This map is used to keep the correspondence between new bindings and the compiler bindings to their internal counterpart. This is an identity map. We should only create one object for one binding.
/** * This map is used to keep the correspondence between new bindings and the * compiler bindings to their internal counterpart. * This is an identity map. We should only create one object for one binding. */
Map compilerBindingsToASTBindings;
This map is used to keep the correspondence between new annotation instances to their internal counterpart. This is an identity map. We should only create one object for one annotation.
/** * This map is used to keep the correspondence between new annotation instances to their internal counterpart. * This is an identity map. We should only create one object for one annotation. */
Map compilerAnnotationBindingsToASTBindings; BindingTables() { this.compilerBindingsToASTBindings = new ConcurrentHashMap(); this.compilerAnnotationBindingsToASTBindings = new ConcurrentHashMap(); this.bindingKeysToBindings = new ConcurrentHashMap(); } }
This map is used to retrieve the corresponding block scope for a ast node
/** * This map is used to retrieve the corresponding block scope for a ast node */
Map astNodesToBlockScope;
This map is used to get an ast node from its binding (new binding) or DOM
/** * This map is used to get an ast node from its binding (new binding) or DOM */
Map bindingsToAstNodes; /* * The shared binding tables accros ASTs. */ BindingTables bindingTables;
This map is used to retrieve an old ast node using the new ast node. This is not an identity map, as several nested DOM nodes may be associated with the same "larger" compiler AST node. E.g., an ArrayAllocationExpression "new MyType[1]" will appear as the right-hand value for the SimpleType "MyType", the ArrayType "MyType[1]", and the ArrayCreation "new MyType[1]".
/** * This map is used to retrieve an old ast node using the new ast node. This is not an * identity map, as several nested DOM nodes may be associated with the same "larger" * compiler AST node. * E.g., an ArrayAllocationExpression "new MyType[1]" will appear as the right-hand value * for the SimpleType "MyType", the ArrayType "MyType[1]", and the ArrayCreation "new MyType[1]". */
Map newAstToOldAst;
Compilation unit scope
/** * Compilation unit scope */
private CompilationUnitScope scope;
The working copy owner that defines the context in which this resolver is creating the bindings.
/** * The working copy owner that defines the context in which this resolver is creating the bindings. */
WorkingCopyOwner workingCopyOwner;
Toggle controlling whether DOM bindings should be created when missing internal compiler bindings..
/** * Toggle controlling whether DOM bindings should be created when missing internal compiler bindings.. */
boolean isRecoveringBindings;
Set to true if initialized from a java project
/** * Set to <code>true</code> if initialized from a java project */
boolean fromJavaProject;
Constructor for DefaultBindingResolver.
/** * Constructor for DefaultBindingResolver. */
DefaultBindingResolver(CompilationUnitScope scope, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) { this.newAstToOldAst = new HashMap(); this.astNodesToBlockScope = new HashMap(); this.bindingsToAstNodes = new HashMap(); this.bindingTables = bindingTables; this.scope = scope; this.workingCopyOwner = workingCopyOwner; this.isRecoveringBindings = isRecoveringBindings; this.fromJavaProject = fromJavaProject; } DefaultBindingResolver(LookupEnvironment lookupEnvironment, WorkingCopyOwner workingCopyOwner, BindingTables bindingTables, boolean isRecoveringBindings, boolean fromJavaProject) { this.newAstToOldAst = new HashMap(); this.astNodesToBlockScope = new HashMap(); this.bindingsToAstNodes = new HashMap(); this.bindingTables = bindingTables; this.scope = new CompilationUnitScope(new CompilationUnitDeclaration(null, null, -1), lookupEnvironment); this.workingCopyOwner = workingCopyOwner; this.isRecoveringBindings = isRecoveringBindings; this.fromJavaProject = fromJavaProject; } @Override synchronized ASTNode findDeclaringNode(IBinding binding) { if (binding == null) { return null; } if (binding instanceof IMethodBinding) { IMethodBinding methodBinding = (IMethodBinding) binding; return (ASTNode) this.bindingsToAstNodes.get(methodBinding.getMethodDeclaration()); } else if (binding instanceof ITypeBinding) { ITypeBinding typeBinding = (ITypeBinding) binding; return (ASTNode) this.bindingsToAstNodes.get(typeBinding.getTypeDeclaration()); } else if (binding instanceof IVariableBinding) { IVariableBinding variableBinding = (IVariableBinding) binding; return (ASTNode) this.bindingsToAstNodes.get(variableBinding.getVariableDeclaration()); } return (ASTNode) this.bindingsToAstNodes.get(binding); } @Override synchronized ASTNode findDeclaringNode(String bindingKey) { if (bindingKey == null) { return null; } Object binding = this.bindingTables.bindingKeysToBindings.get(bindingKey); if (binding == null) return null; return (ASTNode) this.bindingsToAstNodes.get(binding); } IBinding getBinding(org.eclipse.jdt.internal.compiler.lookup.Binding binding) { switch (binding.kind()) { case Binding.PACKAGE: return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding); case Binding.TYPE: case Binding.BASE_TYPE: case Binding.GENERIC_TYPE: case Binding.PARAMETERIZED_TYPE: case Binding.RAW_TYPE: return getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); case Binding.ARRAY_TYPE: case Binding.TYPE_PARAMETER: return new TypeBinding(this, (org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); case Binding.METHOD: return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding) binding); case Binding.MODULE: return getModuleBinding((org.eclipse.jdt.internal.compiler.lookup.ModuleBinding) binding); case Binding.FIELD: case Binding.LOCAL: return getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding); } return null; } Util.BindingsToNodesMap getBindingsToNodesMap() { return new Util.BindingsToNodesMap() { @Override public org.eclipse.jdt.internal.compiler.ast.ASTNode get(Binding binding) { return (org.eclipse.jdt.internal.compiler.ast.ASTNode) DefaultBindingResolver.this.newAstToOldAst.get(DefaultBindingResolver.this.bindingsToAstNodes.get(binding)); } }; } @Override synchronized org.eclipse.jdt.internal.compiler.ast.ASTNode getCorrespondingNode(ASTNode currentNode) { return (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(currentNode); } @Override synchronized IMethodBinding getMethodBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding) { return getMethodOrLambdaBinding(methodBinding, null, null); } private synchronized IMethodBinding getMethodOrLambdaBinding(org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding, org.eclipse.jdt.internal.compiler.lookup.MethodBinding descriptor, IBinding enclosingBinding) { if (methodBinding != null && !methodBinding.isValidBinding()) { org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding problemMethodBinding = (org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding) methodBinding; methodBinding = problemMethodBinding.closestMatch; } if (methodBinding != null) { if (!this.isRecoveringBindings && ((methodBinding.tagBits & TagBits.HasMissingType) != 0)) { return null; } IMethodBinding binding = (IMethodBinding) this.bindingTables.compilerBindingsToASTBindings.get(methodBinding); if (binding != null) { return binding; } if (descriptor != null && enclosingBinding != null) { binding = new MethodBinding.LambdaMethod(this, descriptor, methodBinding, enclosingBinding); } else { binding = new MethodBinding(this, methodBinding); } this.bindingTables.compilerBindingsToASTBindings.put(methodBinding, binding); return binding; } return null; } @Override synchronized IMemberValuePairBinding getMemberValuePairBinding(ElementValuePair valuePair) { if (valuePair == null || valuePair.binding == null) return null; IMemberValuePairBinding binding = (IMemberValuePairBinding) this.bindingTables.compilerBindingsToASTBindings.get(valuePair); if (binding != null) return binding; binding = new MemberValuePairBinding(valuePair, this); this.bindingTables.compilerBindingsToASTBindings.put(valuePair, binding); return binding; }
See Also:
  • getModuleBinding.getModuleBinding(ModuleBinding)
/** * @see org.eclipse.jdt.core.dom.BindingResolver#getModuleBinding(org.eclipse.jdt.internal.compiler.lookup.ModuleBinding) */
@Override synchronized IModuleBinding getModuleBinding(org.eclipse.jdt.internal.compiler.lookup.ModuleBinding moduleBinding) { if (moduleBinding != null) { IModuleBinding binding = (IModuleBinding) this.bindingTables.compilerBindingsToASTBindings.get(moduleBinding); if (binding == null) { binding = new ModuleBinding(this, moduleBinding); this.bindingTables.compilerBindingsToASTBindings.put(moduleBinding, binding); } return binding; } return null; } @Override synchronized IPackageBinding getPackageBinding(org.eclipse.jdt.internal.compiler.lookup.PackageBinding packageBinding) { if (packageBinding == null || packageBinding instanceof ProblemPackageBinding) { return null; } IPackageBinding binding = (IPackageBinding) this.bindingTables.compilerBindingsToASTBindings.get(packageBinding); if (binding != null) { return binding; } binding = packageBinding instanceof ProblemPackageBinding ? new RecoveredPackageBinding(packageBinding, this) : new PackageBinding(packageBinding, this); this.bindingTables.compilerBindingsToASTBindings.put(packageBinding, binding); return binding; } private int getTypeCount(ParameterizedQualifiedTypeReference typeReference) { TypeReference[][] typeArguments = typeReference.typeArguments; int value = 0; org.eclipse.jdt.internal.compiler.ast.Annotation[][] typeAnnotations = typeReference.annotations; int length = typeReference.tokens.length; for (int i = 0; i < length; ++i) { if (value != 0 || (typeArguments != null && typeArguments[i] != null) || (typeAnnotations != null && typeAnnotations[i] != null )) { value++; } } return value; } @Override synchronized ITypeBinding getTypeBinding(VariableDeclaration variableDeclaration) { ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableDeclaration); if (binding != null) { return binding; } binding = new RecoveredTypeBinding(this, variableDeclaration); this.bindingTables.compilerBindingsToASTBindings.put(variableDeclaration, binding); return binding; } @Override synchronized ITypeBinding getTypeBinding(Type type) { ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(type); if (binding != null) { return binding; } binding = new RecoveredTypeBinding(this, type); this.bindingTables.compilerBindingsToASTBindings.put(type, binding); return binding; } @Override synchronized ITypeBinding getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding) { return internalGetTypeBinding(referenceBinding, null); } private synchronized ITypeBinding internalGetTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding referenceBinding, IBinding declaringMember) { // may also create an TypeBinding.AnonymousTypeBinding if (referenceBinding == null) { return null; } else if (!referenceBinding.isValidBinding()) { switch(referenceBinding.problemId()) { case ProblemReasons.NotVisible : case ProblemReasons.NonStaticReferenceInStaticContext : if (referenceBinding instanceof ProblemReferenceBinding) { ProblemReferenceBinding problemReferenceBinding = (ProblemReferenceBinding) referenceBinding; org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding2 = problemReferenceBinding.closestMatch(); ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(binding2); if (binding != null) { return binding; } binding = TypeBinding.createTypeBinding(this, binding2, declaringMember); this.bindingTables.compilerBindingsToASTBindings.put(binding2, binding); return binding; } break; case ProblemReasons.NotFound : if (!this.isRecoveringBindings) { return null; } ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(referenceBinding); if (binding != null) { return binding; } if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0) { binding = TypeBinding.createTypeBinding(this, referenceBinding, declaringMember); } else { binding = new RecoveredTypeBinding(this, referenceBinding); } this.bindingTables.compilerBindingsToASTBindings.put(referenceBinding, binding); return binding; } return null; } else { if ((referenceBinding.tagBits & TagBits.HasMissingType) != 0 && !this.isRecoveringBindings) { return null; } ITypeBinding binding = (ITypeBinding) this.bindingTables.compilerBindingsToASTBindings.get(referenceBinding); if (binding != null) { return binding; } binding = TypeBinding.createTypeBinding(this, referenceBinding, declaringMember); this.bindingTables.compilerBindingsToASTBindings.put(referenceBinding, binding); return binding; } } @Override synchronized ITypeBinding getTypeBinding(RecoveredTypeBinding recoveredTypeBinding, int dimensions) { if (recoveredTypeBinding== null) { return null; } return new RecoveredTypeBinding(this, recoveredTypeBinding, dimensions); } synchronized IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding variableBinding, VariableDeclaration variableDeclaration) { if (this.isRecoveringBindings) { if (variableBinding != null) { if (variableBinding.isValidBinding()) { IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding); if (binding != null) { return binding; } if (variableBinding.type != null) { binding = new VariableBinding(this, variableBinding); } else { binding = new RecoveredVariableBinding(this, variableDeclaration); } this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding); return binding; } else { /* * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449 */ if (variableBinding instanceof ProblemFieldBinding) { ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) variableBinding; switch(problemFieldBinding.problemId()) { case ProblemReasons.NotVisible : case ProblemReasons.NonStaticReferenceInStaticContext : case ProblemReasons.NonStaticReferenceInConstructorInvocation : ReferenceBinding declaringClass = problemFieldBinding.declaringClass; FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/); if (exactBinding != null) { IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding); if (variableBinding2 != null) { return variableBinding2; } variableBinding2 = new VariableBinding(this, exactBinding); this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2); return variableBinding2; } break; } } } } return null; } return this.getVariableBinding(variableBinding); } @Override public WorkingCopyOwner getWorkingCopyOwner() { return this.workingCopyOwner; } @Override synchronized IVariableBinding getVariableBinding(org.eclipse.jdt.internal.compiler.lookup.VariableBinding variableBinding) { if (variableBinding != null) { if (variableBinding.isValidBinding()) { org.eclipse.jdt.internal.compiler.lookup.TypeBinding variableType = variableBinding.type; if (variableType != null) { if (!this.isRecoveringBindings && ((variableType.tagBits & TagBits.HasMissingType) != 0)) { return null; } IVariableBinding binding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(variableBinding); if (binding != null) { return binding; } binding = new VariableBinding(this, variableBinding); this.bindingTables.compilerBindingsToASTBindings.put(variableBinding, binding); return binding; } } else { /* * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449 */ if (variableBinding instanceof ProblemFieldBinding) { ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) variableBinding; switch(problemFieldBinding.problemId()) { case ProblemReasons.NotVisible : case ProblemReasons.NonStaticReferenceInStaticContext : case ProblemReasons.NonStaticReferenceInConstructorInvocation : ReferenceBinding declaringClass = problemFieldBinding.declaringClass; FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/); if (exactBinding != null) { IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding); if (variableBinding2 != null) { return variableBinding2; } variableBinding2 = new VariableBinding(this, exactBinding); this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2); return variableBinding2; } break; } } } } return null; } static class AnnotationIdentityBinding { org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance; AnnotationIdentityBinding(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance) { this.internalInstance = internalInstance; } @Override public boolean equals(Object o) { return o instanceof AnnotationIdentityBinding && this.internalInstance == ((AnnotationIdentityBinding)o).internalInstance; } @Override public int hashCode() { return this.internalInstance.hashCode(); } } @Override synchronized IAnnotationBinding getAnnotationInstance(org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding internalInstance) { if (internalInstance == null) return null; ReferenceBinding annotationType = internalInstance.getAnnotationType(); if (!this.isRecoveringBindings) { if (annotationType == null || ((annotationType.tagBits & TagBits.HasMissingType) != 0)) { return null; } } Object key = new AnnotationIdentityBinding(internalInstance); IAnnotationBinding newDomInstance = new AnnotationBinding(internalInstance, this); IAnnotationBinding domInstance = (IAnnotationBinding) ((ConcurrentHashMap)this.bindingTables.compilerAnnotationBindingsToASTBindings).putIfAbsent(key, newDomInstance); return domInstance != null ? domInstance : newDomInstance; } @Override boolean isResolvedTypeInferredFromExpectedType(MethodInvocation methodInvocation) { Object oldNode = this.newAstToOldAst.get(methodInvocation); if (oldNode instanceof MessageSend) { MessageSend messageSend = (MessageSend) oldNode; org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = messageSend.binding; if (methodBinding instanceof ParameterizedGenericMethodBinding) { ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) methodBinding; return genericMethodBinding.inferredReturnType; } } return false; } @Override boolean isResolvedTypeInferredFromExpectedType(SuperMethodInvocation superMethodInvocation) { Object oldNode = this.newAstToOldAst.get(superMethodInvocation); if (oldNode instanceof MessageSend) { MessageSend messageSend = (MessageSend) oldNode; org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding = messageSend.binding; if (methodBinding instanceof ParameterizedGenericMethodBinding) { ParameterizedGenericMethodBinding genericMethodBinding = (ParameterizedGenericMethodBinding) methodBinding; return genericMethodBinding.inferredReturnType; } } return false; } @Override boolean isResolvedTypeInferredFromExpectedType(ClassInstanceCreation classInstanceCreation) { Object oldNode = this.newAstToOldAst.get(classInstanceCreation); if (oldNode instanceof AllocationExpression) { AllocationExpression allocationExpression = (AllocationExpression) oldNode; return allocationExpression.inferredReturnType; } return false; } @Override LookupEnvironment lookupEnvironment() { return this.scope.environment(); }
See Also:
  • recordScope.recordScope(ASTNode, BlockScope)
/** * @see org.eclipse.jdt.core.dom.BindingResolver#recordScope(ASTNode, BlockScope) */
@Override synchronized void recordScope(ASTNode astNode, BlockScope blockScope) { this.astNodesToBlockScope.put(astNode, blockScope); } @Override boolean resolveBoxing(Expression expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression && ((org.eclipse.jdt.internal.compiler.ast.Expression) node).isTrulyExpression()) { org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node; return (compilerExpression.implicitConversion & TypeIds.BOXING) != 0; } return false; } @Override boolean resolveUnboxing(Expression expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression) { org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node; return (compilerExpression.implicitConversion & TypeIds.UNBOXING) != 0; } return false; } @Override Object resolveConstantExpressionValue(Expression expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node instanceof org.eclipse.jdt.internal.compiler.ast.Expression && ((org.eclipse.jdt.internal.compiler.ast.Expression) node).isTrulyExpression()) { org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) node; Constant constant = compilerExpression.constant; if (constant != null && constant != Constant.NotAConstant) { switch (constant.typeID()) { case TypeIds.T_int : return Integer.valueOf(constant.intValue()); case TypeIds.T_byte : return Byte.valueOf(constant.byteValue()); case TypeIds.T_short : return Short.valueOf(constant.shortValue()); case TypeIds.T_char : return Character.valueOf(constant.charValue()); case TypeIds.T_float : return new Float(constant.floatValue()); case TypeIds.T_double : return new Double(constant.doubleValue()); case TypeIds.T_boolean : return constant.booleanValue() ? Boolean.TRUE : Boolean.FALSE; case TypeIds.T_long : return Long.valueOf(constant.longValue()); case TypeIds.T_JavaLangString : return constant.stringValue(); } return null; } } return null; } @Override synchronized IMethodBinding resolveConstructor(ClassInstanceCreation expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node != null && (node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousLocalTypeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; return getMethodBinding(anonymousLocalTypeDeclaration.allocation.binding); } else if (node instanceof AllocationExpression) { return getMethodBinding(((AllocationExpression)node).binding); } return null; } @Override synchronized IMethodBinding resolveConstructor(ConstructorInvocation expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node instanceof ExplicitConstructorCall) { ExplicitConstructorCall explicitConstructorCall = (ExplicitConstructorCall) node; return getMethodBinding(explicitConstructorCall.binding); } return null; } @Override IMethodBinding resolveConstructor(EnumConstantDeclaration enumConstantDeclaration) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(enumConstantDeclaration); if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) { org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node; if (fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT && fieldDeclaration.initialization != null) { AllocationExpression allocationExpression = (AllocationExpression) fieldDeclaration.initialization; return getMethodBinding(allocationExpression.binding); } } return null; } @Override synchronized IMethodBinding resolveConstructor(SuperConstructorInvocation expression) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (node instanceof ExplicitConstructorCall) { ExplicitConstructorCall explicitConstructorCall = (ExplicitConstructorCall) node; return getMethodBinding(explicitConstructorCall.binding); } return null; } @Override synchronized ITypeBinding resolveExpressionType(Expression expression) { try { switch(expression.getNodeType()) { case ASTNode.CLASS_INSTANCE_CREATION : org.eclipse.jdt.internal.compiler.ast.ASTNode astNode = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(expression); if (astNode instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { // anonymous type case org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) astNode; ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding); if (typeBinding != null) { return typeBinding; } } else if (astNode instanceof AllocationExpression) { // should be an AllocationExpression AllocationExpression allocationExpression = (AllocationExpression) astNode; return this.getTypeBinding(allocationExpression.resolvedType); } break; case ASTNode.SIMPLE_NAME : case ASTNode.QUALIFIED_NAME : return resolveTypeBindingForName((Name) expression); case ASTNode.ARRAY_INITIALIZER : case ASTNode.ARRAY_CREATION : case ASTNode.ASSIGNMENT : case ASTNode.POSTFIX_EXPRESSION : case ASTNode.PREFIX_EXPRESSION : case ASTNode.CAST_EXPRESSION : case ASTNode.TYPE_LITERAL : case ASTNode.INFIX_EXPRESSION : case ASTNode.INSTANCEOF_EXPRESSION : case ASTNode.LAMBDA_EXPRESSION: case ASTNode.CREATION_REFERENCE: case ASTNode.EXPRESSION_METHOD_REFERENCE: case ASTNode.TYPE_METHOD_REFERENCE: case ASTNode.SUPER_METHOD_REFERENCE : case ASTNode.FIELD_ACCESS : case ASTNode.SUPER_FIELD_ACCESS : case ASTNode.ARRAY_ACCESS : case ASTNode.METHOD_INVOCATION : case ASTNode.SUPER_METHOD_INVOCATION : case ASTNode.CONDITIONAL_EXPRESSION : case ASTNode.SWITCH_EXPRESSION : case ASTNode.MARKER_ANNOTATION : case ASTNode.NORMAL_ANNOTATION : case ASTNode.SINGLE_MEMBER_ANNOTATION : org.eclipse.jdt.internal.compiler.ast.Expression compilerExpression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(expression); if (compilerExpression != null) { return this.getTypeBinding(compilerExpression.resolvedType); } break; case ASTNode.TEXT_BLOCK : case ASTNode.STRING_LITERAL : if (this.scope != null) { return this.getTypeBinding(this.scope.getJavaLangString()); } break; case ASTNode.BOOLEAN_LITERAL : case ASTNode.NULL_LITERAL : case ASTNode.CHARACTER_LITERAL : case ASTNode.NUMBER_LITERAL : Literal literal = (Literal) this.newAstToOldAst.get(expression); if (literal != null) { return this.getTypeBinding(literal.literalType(null)); } break; case ASTNode.THIS_EXPRESSION : ThisReference thisReference = (ThisReference) this.newAstToOldAst.get(expression); BlockScope blockScope = (BlockScope) this.astNodesToBlockScope.get(expression); if (blockScope != null) { return this.getTypeBinding(thisReference.resolveType(blockScope)); } break; case ASTNode.PARENTHESIZED_EXPRESSION : ParenthesizedExpression parenthesizedExpression = (ParenthesizedExpression) expression; return resolveExpressionType(parenthesizedExpression.getExpression()); case ASTNode.VARIABLE_DECLARATION_EXPRESSION : VariableDeclarationExpression variableDeclarationExpression = (VariableDeclarationExpression) expression; Type type = variableDeclarationExpression.getType(); if (type != null) { return type.resolveBinding(); } break; } } catch (AbortCompilation e) { // handle missing types } return null; } @Override synchronized IVariableBinding resolveField(FieldAccess fieldAccess) { Object oldNode = this.newAstToOldAst.get(fieldAccess); if (oldNode instanceof FieldReference) { FieldReference fieldReference = (FieldReference) oldNode; return this.getVariableBinding(fieldReference.binding); } return null; } @Override synchronized IVariableBinding resolveField(SuperFieldAccess fieldAccess) { Object oldNode = this.newAstToOldAst.get(fieldAccess); if (oldNode instanceof FieldReference) { FieldReference fieldReference = (FieldReference) oldNode; return this.getVariableBinding(fieldReference.binding); } return null; } @Override synchronized IBinding resolveImport(ImportDeclaration importDeclaration) { if (this.scope == null) return null; try { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(importDeclaration); if (node instanceof ImportReference) { ImportReference importReference = (ImportReference) node; final boolean isStatic = importReference.isStatic(); if ((importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0) { Binding binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length), true, isStatic); if (binding != null) { if (isStatic) { if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); return typeBinding == null ? null : typeBinding; } } else { if ((binding.kind() & Binding.PACKAGE) != 0) { IPackageBinding packageBinding = getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding); if (packageBinding == null) { return null; } return packageBinding; } else { // if it is not a package, it has to be a type ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); if (typeBinding == null) { return null; } return typeBinding; } } } } else { Binding binding = this.scope.getImport(importReference.tokens, false, isStatic); if (binding != null) { if (isStatic) { if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); return typeBinding == null ? null : typeBinding; } else if (binding instanceof FieldBinding) { IVariableBinding variableBinding = this.getVariableBinding((FieldBinding) binding); return variableBinding == null ? null : variableBinding; } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) { // it is a type return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding); } } else { if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { ITypeBinding typeBinding = this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding) binding); return typeBinding == null ? null : typeBinding; } } } } } } catch(AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299 } return null; } @Override IMethodBinding resolveMember(AnnotationTypeMemberDeclaration declaration) { Object oldNode = this.newAstToOldAst.get(declaration); if (oldNode instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode; IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding); if (methodBinding == null) { return null; } this.bindingsToAstNodes.put(methodBinding, declaration); String key = methodBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, methodBinding); } return methodBinding; } return null; } private IVariableBinding[] getSyntheticOuterLocalVariables(org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression) { IVariableBinding[] syntheticOuterLocals = new IVariableBinding[lambdaExpression.outerLocalVariables.length]; int i = 0; for (SyntheticArgumentBinding sab : lambdaExpression.outerLocalVariables) { syntheticOuterLocals[i++] = getVariableBinding(sab); } return syntheticOuterLocals; } @Override synchronized IMethodBinding resolveMethod(LambdaExpression lambda) { Object oldNode = this.newAstToOldAst.get(lambda); if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.LambdaExpression) { org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) oldNode; IMethodBinding methodBinding = null; if (lambdaExpression.descriptor != null) { IBinding declaringMember = getDeclaringMember(lambdaExpression, lambdaExpression.enclosingScope); if (declaringMember != null) methodBinding = getMethodOrLambdaBinding(lambdaExpression.getMethodBinding(), lambdaExpression.descriptor, declaringMember); } if (methodBinding == null) { return null; } if (methodBinding instanceof LambdaMethod) { ((LambdaMethod) methodBinding).setSyntheticOuterLocals(getSyntheticOuterLocalVariables(lambdaExpression)); } this.bindingsToAstNodes.put(methodBinding, lambda); String key = methodBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, methodBinding); } return methodBinding; } return null; } private IBinding getDeclaringMember(org.eclipse.jdt.internal.compiler.ast.ASTNode node, Scope currentScope) { MethodScope methodScope = currentScope != null ? currentScope.methodScope() : null; if (methodScope != null) { if (methodScope.isInsideInitializer()) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration enclosingType = methodScope.referenceType(); if (enclosingType.fields != null) { for (int i = 0; i < enclosingType.fields.length; i++) { FieldDeclaration field = enclosingType.fields[i]; if (field.declarationSourceStart <= node.sourceStart && node.sourceEnd <= field.declarationSourceEnd) { if (field instanceof org.eclipse.jdt.internal.compiler.ast.Initializer) return getMethodBinding(((org.eclipse.jdt.internal.compiler.ast.Initializer) field).getMethodBinding()); else return getVariableBinding(field.binding); } } } } else { if (methodScope.isLambdaScope()) { org.eclipse.jdt.internal.compiler.ast.LambdaExpression lambdaExpression = (org.eclipse.jdt.internal.compiler.ast.LambdaExpression) methodScope.referenceContext; IMethodBinding methodBinding = null; if (lambdaExpression.descriptor != null) { IBinding declaringMember = getDeclaringMember(lambdaExpression, lambdaExpression.enclosingScope); if (declaringMember != null) methodBinding = getMethodOrLambdaBinding(lambdaExpression.getMethodBinding(), lambdaExpression.descriptor, declaringMember); } if (methodBinding == null) { return null; } String key = methodBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, methodBinding); } return methodBinding; } else { return getMethodBinding(methodScope.referenceMethodBinding()); } } } return null; } @Override synchronized IMethodBinding resolveMethod(MethodDeclaration method) { Object oldNode = this.newAstToOldAst.get(method); if (oldNode instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) oldNode; IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding); if (methodBinding == null) { return null; } this.bindingsToAstNodes.put(methodBinding, method); String key = methodBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, methodBinding); } return methodBinding; } return null; } @Override synchronized IMethodBinding resolveMethod(MethodInvocation method) { Object oldNode = this.newAstToOldAst.get(method); if (oldNode instanceof MessageSend) { MessageSend messageSend = (MessageSend) oldNode; return getMethodBinding(messageSend.binding); } return null; } @Override synchronized IMethodBinding resolveMethod(MethodReference methodReference) { Object oldNode = this.newAstToOldAst.get(methodReference); if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) { org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) oldNode; if (referenceExpression.receiverType != null && referenceExpression.receiverType.isArrayType()) return null; IMethodBinding methodBinding = getMethodBinding(referenceExpression.getMethodBinding()); if (methodBinding == null) { return null; } return methodBinding; } return null; } @Override synchronized IMethodBinding resolveMethod(SuperMethodInvocation method) { Object oldNode = this.newAstToOldAst.get(method); if (oldNode instanceof MessageSend) { MessageSend messageSend = (MessageSend) oldNode; return getMethodBinding(messageSend.binding); } return null; } synchronized ITypeBinding resolveTypeBindingForName(Name name) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(name); int index = name.index; if (node instanceof QualifiedNameReference) { QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node; final char[][] tokens = qualifiedNameReference.tokens; if (tokens.length == index) { return this.getTypeBinding(qualifiedNameReference.resolvedType); } int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based if (index < indexOfFirstFieldBinding) { // an extra lookup is required BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name); Binding binding = null; try { if (internalScope == null) { if (this.scope == null) return null; binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index)); } else { binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index)); } } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299 } if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { return null; } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } } else if (index == indexOfFirstFieldBinding) { if (qualifiedNameReference.isTypeReference()) { return this.getTypeBinding(qualifiedNameReference.resolvedType); } else { // in this case we want to get the next field declaring's class if (qualifiedNameReference.otherBindings == null) { return null; } FieldBinding fieldBinding = qualifiedNameReference.otherBindings[0]; if (fieldBinding == null) return null; org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass; if (type == null) { // array length scenario // use type from first binding (no capture needed for array type) switch (qualifiedNameReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.RestrictiveFlagMASK) { case Binding.FIELD: type = ((FieldBinding) qualifiedNameReference.binding).type; break; case Binding.LOCAL: type = ((LocalVariableBinding) qualifiedNameReference.binding).type; break; } } return this.getTypeBinding(type); } } else { /* This is the case for a name which is part of a qualified name that * cannot be resolved. See PR 13063. */ if (qualifiedNameReference.otherBindings == null) return null; final int otherBindingsLength = qualifiedNameReference.otherBindings.length; if (otherBindingsLength == (index - indexOfFirstFieldBinding)) { return this.getTypeBinding(qualifiedNameReference.resolvedType); } FieldBinding fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding]; if (fieldBinding == null) return null; org.eclipse.jdt.internal.compiler.lookup.TypeBinding type = fieldBinding.declaringClass; if (type == null) { // array length scenario // use type from previous binding (no capture needed for array type) fieldBinding = qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1]; if (fieldBinding == null) return null; type = fieldBinding.type; } return this.getTypeBinding(type); } } else if (node instanceof QualifiedTypeReference) { QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) node; if (qualifiedTypeReference.resolvedType == null) { return null; } if (index == qualifiedTypeReference.tokens.length) { if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) { JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node; if (typeRef.packageBinding != null) { return null; } } return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType()); } else { if (index >= 0) { BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name); Binding binding = null; try { if (internalScope == null) { if (this.scope == null) return null; binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index)); } else { binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index)); } } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { return null; } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } else { return null; } } } } else if (node instanceof ImportReference) { if ((node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.inModule) != 0) return null; ImportReference importReference = (ImportReference) node; int importReferenceLength = importReference.tokens.length; if (index >= 0) { Binding binding = null; if (this.scope == null) return null; if (importReferenceLength == index) { try { binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0, importReference.isStatic()); } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } } else { try { binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic()); } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } } if (binding != null) { if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } return null; } } } else if (node instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node; IMethodBinding method = getMethodBinding(methodDeclaration.binding); if (method == null) return null; return method.getReturnType(); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding); if (typeBinding != null) { return typeBinding; } } if (node instanceof JavadocSingleNameReference) { JavadocSingleNameReference singleNameReference = (JavadocSingleNameReference) node; LocalVariableBinding localVariable = (LocalVariableBinding)singleNameReference.binding; if (localVariable != null) { return this.getTypeBinding(localVariable.type); } } if (node instanceof SingleNameReference) { SingleNameReference singleNameReference = (SingleNameReference) node; return this.getTypeBinding(singleNameReference.resolvedType); } else if (node instanceof QualifiedSuperReference) { QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) node; return this.getTypeBinding(qualifiedSuperReference.qualification.resolvedType); } else if (node instanceof Receiver) { org.eclipse.jdt.internal.compiler.lookup.TypeBinding receiver = ((Receiver) node).type.resolvedType; return this.getTypeBinding(receiver); } else if (node instanceof LocalDeclaration) { IVariableBinding variable = this.getVariableBinding(((LocalDeclaration)node).binding); if (variable == null) return null; return variable.getType(); } else if (node instanceof JavadocFieldReference) { JavadocFieldReference fieldRef = (JavadocFieldReference) node; if (fieldRef.methodBinding != null) { return getMethodBinding(fieldRef.methodBinding).getReturnType(); } return getTypeBinding(fieldRef.resolvedType); } else if (node instanceof FieldReference) { return getTypeBinding(((FieldReference) node).resolvedType); } else if (node instanceof SingleTypeReference) { SingleTypeReference singleTypeReference = (SingleTypeReference) node; org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = singleTypeReference.resolvedType; if (binding != null) { return this.getTypeBinding(binding.leafComponentType()); } } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) { org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node; IVariableBinding field = this.getVariableBinding(fieldDeclaration.binding); if (field == null) return null; return field.getType(); } else if (node instanceof MessageSend) { MessageSend messageSend = (MessageSend) node; IMethodBinding method = getMethodBinding(messageSend.binding); if (method == null) return null; return method.getReturnType(); } else if (node instanceof AllocationExpression) { AllocationExpression allocation = (AllocationExpression) node; return getTypeBinding(allocation.resolvedType); } else if (node instanceof JavadocImplicitTypeReference) { JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node; return getTypeBinding(implicitRef.resolvedType); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) { org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node; return this.getTypeBinding(typeParameter.binding); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) { org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node; IMethodBinding method = getMethodBinding(memberValuePair.binding); if (method == null) return null; return method.getReturnType(); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) { org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node; IMethodBinding method = getMethodBinding(referenceExpression.getMethodBinding()); if (method == null) return null; return method.getReturnType(); } return null; } @Override synchronized IBinding resolveName(Name name) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(name); int index = name.index; if (node instanceof QualifiedNameReference) { QualifiedNameReference qualifiedNameReference = (QualifiedNameReference) node; final char[][] tokens = qualifiedNameReference.tokens; int indexOfFirstFieldBinding = qualifiedNameReference.indexOfFirstFieldBinding; // one-based if (index < indexOfFirstFieldBinding) { // an extra lookup is required BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name); Binding binding = null; try { if (internalScope == null) { if (this.scope == null) return null; binding = this.scope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index)); } else { binding = internalScope.getTypeOrPackage(CharOperation.subarray(tokens, 0, index)); } } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299 } if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding); } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } } else if (index == indexOfFirstFieldBinding) { if (qualifiedNameReference.isTypeReference()) { return this.getTypeBinding(qualifiedNameReference.resolvedType); } else { Binding binding = qualifiedNameReference.binding; if (binding != null) { if (binding.isValidBinding()) { return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding); } else if (binding instanceof ProblemFieldBinding) { ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding; switch(problemFieldBinding.problemId()) { case ProblemReasons.NotVisible : case ProblemReasons.NonStaticReferenceInStaticContext : ReferenceBinding declaringClass = problemFieldBinding.declaringClass; if (declaringClass != null) { FieldBinding exactBinding = declaringClass.getField(tokens[tokens.length - 1], true /*resolve*/); if (exactBinding != null) { if (exactBinding.type != null) { IVariableBinding variableBinding = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding); if (variableBinding != null) { return variableBinding; } variableBinding = new VariableBinding(this, exactBinding); this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding); return variableBinding; } } } break; } } } } } else { /* This is the case for a name which is part of a qualified name that * cannot be resolved. See PR 13063. */ if (qualifiedNameReference.otherBindings == null || (index - indexOfFirstFieldBinding - 1) < 0) { return null; } else { return this.getVariableBinding(qualifiedNameReference.otherBindings[index - indexOfFirstFieldBinding - 1]); } } } else if (node instanceof QualifiedTypeReference) { QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference) node; if (qualifiedTypeReference.resolvedType == null) { return null; } if (index == qualifiedTypeReference.tokens.length) { if (!qualifiedTypeReference.resolvedType.isValidBinding() && qualifiedTypeReference instanceof JavadocQualifiedTypeReference) { JavadocQualifiedTypeReference typeRef = (JavadocQualifiedTypeReference) node; if (typeRef.packageBinding != null) { return getPackageBinding(typeRef.packageBinding); } } return this.getTypeBinding(qualifiedTypeReference.resolvedType.leafComponentType()); } else { if (index >= 0) { BlockScope internalScope = (BlockScope) this.astNodesToBlockScope.get(name); Binding binding = null; try { if (internalScope == null) { if (this.scope == null) return null; binding = this.scope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index)); } else { binding = internalScope.getTypeOrPackage(CharOperation.subarray(qualifiedTypeReference.tokens, 0, index)); } } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding); } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } else { return null; } } } } else if (node instanceof ImportReference) { ImportReference importReference = (ImportReference) node; int importReferenceLength = importReference.tokens.length; boolean inModule = (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.inModule) != 0; if (index >= 0) { Binding binding = null; if (this.scope == null) return null; if (importReferenceLength == index && !inModule) { try { binding = this.scope.getImport(CharOperation.subarray(importReference.tokens, 0, index), (importReference.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.OnDemand) != 0, importReference.isStatic()); } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } } else { try { binding = this.scope.getImport(inModule ? importReference.tokens : CharOperation.subarray(importReference.tokens, 0, index), true, importReference.isStatic()); } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 } } if (binding != null) { if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { return getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding)binding); } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.TypeBinding) { // it is a type return this.getTypeBinding((org.eclipse.jdt.internal.compiler.lookup.TypeBinding)binding); } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.FieldBinding) { // it is a type return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.FieldBinding)binding); } else if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.MethodBinding) { // it is a type return getMethodBinding((org.eclipse.jdt.internal.compiler.lookup.MethodBinding)binding); } else { return null; } } } } else if (node instanceof CompilationUnitDeclaration) { CompilationUnitDeclaration compilationUnitDeclaration = (CompilationUnitDeclaration) node; org.eclipse.jdt.internal.compiler.ast.TypeDeclaration[] types = compilationUnitDeclaration.types; if (types == null || types.length == 0) { return null; } org.eclipse.jdt.internal.compiler.ast.TypeDeclaration type = types[0]; if (type != null) { ITypeBinding typeBinding = this.getTypeBinding(type.binding); if (typeBinding != null) { return typeBinding.getPackage(); } } } else if (node instanceof AbstractMethodDeclaration) { AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node; IMethodBinding methodBinding = getMethodBinding(methodDeclaration.binding); if (methodBinding != null) { return methodBinding; } } else if (node instanceof ModuleReference) { ModuleReference moduleReference = (ModuleReference) node; IModuleBinding moduleBinding = getModuleBinding(moduleReference.binding); if (moduleBinding != null) { return moduleBinding; } } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration) { org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration = (org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration) node; IModuleBinding moduleBinding = getModuleBinding(moduleDeclaration.binding); if (moduleBinding != null) { return moduleBinding; } } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding); if (typeBinding != null) { return typeBinding; } } if (node instanceof SingleNameReference) { SingleNameReference singleNameReference = (SingleNameReference) node; if (singleNameReference.isTypeReference()) { return this.getTypeBinding(singleNameReference.resolvedType); } else { // this is a variable or a field Binding binding = singleNameReference.binding; if (binding != null) { if (binding.isValidBinding()) { return this.getVariableBinding((org.eclipse.jdt.internal.compiler.lookup.VariableBinding) binding); } else { /* * http://dev.eclipse.org/bugs/show_bug.cgi?id=24449 */ if (binding instanceof ProblemFieldBinding) { ProblemFieldBinding problemFieldBinding = (ProblemFieldBinding) binding; switch(problemFieldBinding.problemId()) { case ProblemReasons.NotVisible : case ProblemReasons.NonStaticReferenceInStaticContext : case ProblemReasons.NonStaticReferenceInConstructorInvocation : ReferenceBinding declaringClass = problemFieldBinding.declaringClass; FieldBinding exactBinding = declaringClass.getField(problemFieldBinding.name, true /*resolve*/); if (exactBinding != null) { if (exactBinding.type != null) { IVariableBinding variableBinding2 = (IVariableBinding) this.bindingTables.compilerBindingsToASTBindings.get(exactBinding); if (variableBinding2 != null) { return variableBinding2; } variableBinding2 = new VariableBinding(this, exactBinding); this.bindingTables.compilerBindingsToASTBindings.put(exactBinding, variableBinding2); return variableBinding2; } } break; } } } } } } else if (node instanceof QualifiedSuperReference) { QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) node; return this.getTypeBinding(qualifiedSuperReference.qualification.resolvedType); } else if (node instanceof LocalDeclaration) { return name.getAST().apiLevel() >= AST.JLS10_INTERNAL && name instanceof SimpleName && ((SimpleName) name).isVar() ? resolveTypeBindingForName(name) : this.getVariableBinding(((LocalDeclaration)node).binding); } else if (node instanceof JavadocFieldReference) { JavadocFieldReference fieldRef = (JavadocFieldReference) node; if (fieldRef.methodBinding != null) { return getMethodBinding(fieldRef.methodBinding); } return getVariableBinding(fieldRef.binding); } else if (node instanceof FieldReference) { return getVariableBinding(((FieldReference) node).binding); } else if (node instanceof SingleTypeReference) { if (node instanceof JavadocSingleTypeReference) { JavadocSingleTypeReference typeRef = (JavadocSingleTypeReference) node; if (typeRef.packageBinding != null) { return getPackageBinding(typeRef.packageBinding); } } SingleTypeReference singleTypeReference = (SingleTypeReference) node; org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = singleTypeReference.resolvedType; if (binding == null) { return null; } return this.getTypeBinding(binding.leafComponentType()); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) { org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node; return this.getVariableBinding(fieldDeclaration.binding); } else if (node instanceof MessageSend) { MessageSend messageSend = (MessageSend) node; return getMethodBinding(messageSend.binding); } else if (node instanceof AllocationExpression) { AllocationExpression allocation = (AllocationExpression) node; return getMethodBinding(allocation.binding); } else if (node instanceof JavadocImplicitTypeReference) { JavadocImplicitTypeReference implicitRef = (JavadocImplicitTypeReference) node; return getTypeBinding(implicitRef.resolvedType); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) { org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node; return this.getTypeBinding(typeParameter.binding); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.MemberValuePair) { org.eclipse.jdt.internal.compiler.ast.MemberValuePair memberValuePair = (org.eclipse.jdt.internal.compiler.ast.MemberValuePair) node; return getMethodBinding(memberValuePair.binding); } else if (node instanceof org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) { org.eclipse.jdt.internal.compiler.ast.ReferenceExpression referenceExpression = (org.eclipse.jdt.internal.compiler.ast.ReferenceExpression) node; return getMethodBinding(referenceExpression.getMethodBinding()); } return null; } @Override synchronized IPackageBinding resolvePackage(PackageDeclaration pkg) { if (this.scope == null) return null; try { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(pkg); if (node instanceof ImportReference) { ImportReference importReference = (ImportReference) node; Binding binding = this.scope.getOnlyPackage(CharOperation.subarray(importReference.tokens, 0, importReference.tokens.length)); if ((binding != null) && (binding.isValidBinding())) { if (binding instanceof ReferenceBinding) { // this only happens if a type name has the same name as its package ReferenceBinding referenceBinding = (ReferenceBinding) binding; binding = referenceBinding.fPackage; } if (binding instanceof org.eclipse.jdt.internal.compiler.lookup.PackageBinding) { IPackageBinding packageBinding = getPackageBinding((org.eclipse.jdt.internal.compiler.lookup.PackageBinding) binding); if (packageBinding == null) { return null; } this.bindingsToAstNodes.put(packageBinding, pkg); String key = packageBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, packageBinding); } return packageBinding; } } } } catch (AbortCompilation e) { // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=53357 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299 } return null; } @Override synchronized IBinding resolveReference(MemberRef ref) { org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(ref); if (expression instanceof TypeReference) { return getTypeBinding(expression.resolvedType); } else if (expression instanceof JavadocFieldReference) { JavadocFieldReference fieldRef = (JavadocFieldReference) expression; if (fieldRef.methodBinding != null) { return getMethodBinding(fieldRef.methodBinding); } return getVariableBinding(fieldRef.binding); } return null; } @Override synchronized IMemberValuePairBinding resolveMemberValuePair(org.eclipse.jdt.core.dom.MemberValuePair memberValuePair) { MemberValuePair valuePair = (MemberValuePair) this.newAstToOldAst.get(memberValuePair); if (valuePair != null) { return getMemberValuePairBinding(valuePair.compilerElementPair); } return null; }
See Also:
  • resolveModule.resolveModule(ModuleDeclaration)
Since:3.14
/** * @see BindingResolver#resolveModule(ModuleDeclaration) * @since 3.14 */
@Override IModuleBinding resolveModule(ModuleDeclaration module) { Object oldNode = this.newAstToOldAst.get(module); if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration) { org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration moduleDeclaration = (org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration) oldNode; IModuleBinding moduleBinding = getModuleBinding(moduleDeclaration.binding); if (moduleBinding == null) { return null; } this.bindingsToAstNodes.put(moduleBinding, module); String key = moduleBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, moduleBinding); } return moduleBinding; } return null; } @Override synchronized IBinding resolveReference(MethodRef ref) { org.eclipse.jdt.internal.compiler.ast.Expression expression = (org.eclipse.jdt.internal.compiler.ast.Expression) this.newAstToOldAst.get(ref); if (expression instanceof JavadocMessageSend) { return getMethodBinding(((JavadocMessageSend)expression).binding); } else if (expression instanceof JavadocAllocationExpression) { return getMethodBinding(((JavadocAllocationExpression)expression).binding); } return null; } @Override ITypeBinding resolveType(AnnotationTypeDeclaration type) { final Object node = this.newAstToOldAst.get(type); if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding); if (typeBinding == null) { return null; } this.bindingsToAstNodes.put(typeBinding, type); String key = typeBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, typeBinding); } return typeBinding; } return null; } @Override synchronized ITypeBinding resolveType(AnonymousClassDeclaration type) { org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type); if (node != null && (node.bits & org.eclipse.jdt.internal.compiler.ast.ASTNode.IsAnonymousType) != 0) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration anonymousLocalTypeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; IBinding declaringMember = getDeclaringMember(anonymousLocalTypeDeclaration, anonymousLocalTypeDeclaration.scope); ITypeBinding typeBinding = internalGetTypeBinding(anonymousLocalTypeDeclaration.binding, declaringMember); if (typeBinding == null) { return null; } this.bindingsToAstNodes.put(typeBinding, type); String key = typeBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, typeBinding); } return typeBinding; } return null; } @Override ITypeBinding resolveType(EnumDeclaration type) { final Object node = this.newAstToOldAst.get(type); if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; ITypeBinding typeBinding = this.getTypeBinding(typeDeclaration.binding); if (typeBinding == null) { return null; } this.bindingsToAstNodes.put(typeBinding, type); String key = typeBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, typeBinding); } return typeBinding; } return null; } @Override synchronized ITypeBinding resolveType(Type type) { // retrieve the old ast node org.eclipse.jdt.internal.compiler.ast.ASTNode node = (org.eclipse.jdt.internal.compiler.ast.ASTNode) this.newAstToOldAst.get(type); org.eclipse.jdt.internal.compiler.lookup.TypeBinding binding = null; if (type.getAST().apiLevel() >= AST.JLS10_INTERNAL && type.isVar()) { return resolveTypeBindingForName(((SimpleType) type).getName()); } if (node != null) { if (node instanceof Receiver) { node = ((Receiver) node).type; } if (node instanceof ParameterizedQualifiedTypeReference) { ParameterizedQualifiedTypeReference typeReference = (ParameterizedQualifiedTypeReference) node; org.eclipse.jdt.internal.compiler.lookup.TypeBinding typeBinding = typeReference.resolvedType; // This unlikely case is possible when for some reason binding resolution has been stopped, like duplicate type declaration (bug 376440) if (typeBinding == null) return null; if (type.isArrayType()) { if (this.scope == null) { return null; } ArrayType arrayType = (ArrayType) type; ArrayBinding arrayBinding = (ArrayBinding) typeBinding; int dimensions = arrayType.getDimensions(); boolean isVarargs = typeReference.isVarargs(); if (dimensions == arrayBinding.dimensions) return getTypeBinding(arrayBinding); // reuse. return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, dimensions, getTypeAnnotations(dimensions, arrayBinding, isVarargs))); } if (typeBinding.isArrayType()) { // 'typeBinding' can still be an array type because 'node' may be "larger" than 'type' (see comment of newAstToOldAst). typeBinding = ((ArrayBinding) typeBinding).leafComponentType; } int index; if (type.isQualifiedType()) { index = ((QualifiedType) type).index; } else if (type.isParameterizedType()) { index = ((ParameterizedType) type).index; } else { index = 1; } final int numberOfTypeArgumentsNotNull = getTypeCount(typeReference); if (index != numberOfTypeArgumentsNotNull) { int i = numberOfTypeArgumentsNotNull; while (i != index) { typeBinding = typeBinding.enclosingType(); i --; } binding = typeBinding; } else { binding = typeBinding; } } else if (node instanceof TypeReference) { if (type instanceof SimpleType && node instanceof QualifiedTypeReference) { return resolveTypeBindingForName(((SimpleType)type).getName()); } else if (type instanceof QualifiedType) { return resolveTypeBindingForName(((QualifiedType)type).getName()); } else if (type instanceof NameQualifiedType){ return resolveTypeBindingForName(((NameQualifiedType)type).getName()); } TypeReference typeReference = (TypeReference) node; binding = typeReference.resolvedType; } else if (node instanceof SingleNameReference && ((SingleNameReference)node).isTypeReference()) { binding = (((SingleNameReference)node).resolvedType); } else if (node instanceof QualifiedNameReference && ((QualifiedNameReference)node).isTypeReference()) { binding = (((QualifiedNameReference)node).resolvedType); } else if (node instanceof ArrayAllocationExpression) { binding = ((ArrayAllocationExpression) node).resolvedType; } if (binding != null) { if (type.isArrayType()) { ArrayType arrayType = (ArrayType) type; if (this.scope == null) { return null; } ArrayBinding arrayBinding = (ArrayBinding) binding; int dimensions = arrayType.getDimensions(); boolean isVarargs = node instanceof TypeReference && ((TypeReference) node).isVarargs(); if (dimensions == arrayBinding.dimensions) return getTypeBinding(arrayBinding); // reuse return getTypeBinding(this.scope.createArrayType(arrayBinding.leafComponentType, dimensions, getTypeAnnotations(dimensions, arrayBinding, isVarargs))); } else if (binding.isArrayType()) { // 'binding' can still be an array type because 'node' may be "larger" than 'type' (see comment of newAstToOldAst). ArrayBinding arrayBinding = (ArrayBinding) binding; return getTypeBinding(arrayBinding.leafComponentType); } return getTypeBinding(binding); } } else if (type.isPrimitiveType()) { /* Handle the void primitive type returned by getReturnType for a method declaration * that is a constructor declaration. It prevents null from being returned */ if (((PrimitiveType) type).getPrimitiveTypeCode() == PrimitiveType.VOID) { return this.getTypeBinding(org.eclipse.jdt.internal.compiler.lookup.TypeBinding.VOID); } } return null; } private org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] getTypeAnnotations(int dimensions, ArrayBinding arrayBinding, boolean isVarargs) { org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding [] oldies = arrayBinding.getTypeAnnotations(); org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] newbies = Binding.NO_ANNOTATIONS; // Skip past extended dimensions encoded ahead of base dimensions. Dimension for variable argument array comes after the base dimensions. int extendedDimensions = arrayBinding.dimensions - dimensions - (isVarargs ? 1 : 0); int i, length; for (i = 0, length = oldies == null ? 0 : oldies.length; i < length && extendedDimensions > 0 ; i++) { if (oldies[i] == null) extendedDimensions--; } int cells = 0; for (int j = i; j < length && dimensions > 0 ; j++) { if (oldies[j] == null) dimensions--; cells ++; } if (cells > 0) System.arraycopy(oldies, i, newbies = new org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[cells], 0, cells); return newbies; } @Override synchronized ITypeBinding resolveType(TypeDeclaration type) { final Object node = this.newAstToOldAst.get(type); if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) { org.eclipse.jdt.internal.compiler.ast.TypeDeclaration typeDeclaration = (org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) node; IBinding declaringMember = getDeclaringMember(typeDeclaration, typeDeclaration.scope); ITypeBinding typeBinding = internalGetTypeBinding(typeDeclaration.binding, declaringMember); if (typeBinding == null) { return null; } this.bindingsToAstNodes.put(typeBinding, type); String key = typeBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, typeBinding); } return typeBinding; } return null; } @Override synchronized ITypeBinding resolveTypeParameter(TypeParameter typeParameter) { final Object node = this.newAstToOldAst.get(typeParameter); if (node instanceof org.eclipse.jdt.internal.compiler.ast.TypeParameter) { org.eclipse.jdt.internal.compiler.ast.TypeParameter typeParameter2 = (org.eclipse.jdt.internal.compiler.ast.TypeParameter) node; ITypeBinding typeBinding = this.getTypeBinding(typeParameter2.binding); if (typeBinding == null) { return null; } this.bindingsToAstNodes.put(typeBinding, typeParameter); String key = typeBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, typeBinding); } return typeBinding; } return null; } @Override synchronized IVariableBinding resolveVariable(EnumConstantDeclaration enumConstant) { final Object node = this.newAstToOldAst.get(enumConstant); if (node instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) { org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) node; IVariableBinding variableBinding = this.getVariableBinding(fieldDeclaration.binding); if (variableBinding == null) { return null; } this.bindingsToAstNodes.put(variableBinding, enumConstant); String key = variableBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, variableBinding); } return variableBinding; } return null; } @Override synchronized IVariableBinding resolveVariable(VariableDeclaration variable) { final Object node = this.newAstToOldAst.get(variable); if (node instanceof AbstractVariableDeclaration) { AbstractVariableDeclaration abstractVariableDeclaration = (AbstractVariableDeclaration) node; IVariableBinding variableBinding = null; if (abstractVariableDeclaration instanceof org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) { org.eclipse.jdt.internal.compiler.ast.FieldDeclaration fieldDeclaration = (org.eclipse.jdt.internal.compiler.ast.FieldDeclaration) abstractVariableDeclaration; variableBinding = this.getVariableBinding(fieldDeclaration.binding, variable); } else { variableBinding = this.getVariableBinding(((LocalDeclaration) abstractVariableDeclaration).binding, variable); } if (variableBinding == null) { return null; } this.bindingsToAstNodes.put(variableBinding, variable); String key = variableBinding.getKey(); if (key != null) { this.bindingTables.bindingKeysToBindings.put(key, variableBinding); } return variableBinding; } return null; } @Override synchronized ITypeBinding resolveWellKnownType(String name) { if (this.scope == null) return null; ITypeBinding typeBinding = null; try { if (("boolean".equals(name))//$NON-NLS-1$ || ("char".equals(name))//$NON-NLS-1$ || ("byte".equals(name))//$NON-NLS-1$ || ("short".equals(name))//$NON-NLS-1$ || ("int".equals(name))//$NON-NLS-1$ || ("long".equals(name))//$NON-NLS-1$ || ("float".equals(name))//$NON-NLS-1$ || ("double".equals(name))//$NON-NLS-1$ || ("void".equals(name))) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(Scope.getBaseType(name.toCharArray())); } else if ("java.lang.Object".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaLangObject()); } else if ("java.lang.String".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaLangString()); } else if ("java.lang.StringBuffer".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_STRINGBUFFER, 3)); } else if ("java.lang.Throwable".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaLangThrowable()); } else if ("java.lang.Exception".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_EXCEPTION, 3)); } else if ("java.lang.RuntimeException".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_RUNTIMEEXCEPTION, 3)); } else if ("java.lang.Error".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_ERROR, 3)); } else if ("java.lang.Class".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaLangClass()); } else if ("java.lang.Cloneable".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaLangCloneable()); } else if ("java.io.Serializable".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getJavaIoSerializable()); } else if ("java.lang.Boolean".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BOOLEAN, 3)); } else if ("java.lang.Byte".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_BYTE, 3)); } else if ("java.lang.Character".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_CHARACTER, 3)); } else if ("java.lang.Double".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_DOUBLE, 3)); } else if ("java.lang.Float".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_FLOAT, 3)); } else if ("java.lang.Integer".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_INTEGER, 3)); } else if ("java.lang.Long".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_LONG, 3)); } else if ("java.lang.Short".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_SHORT, 3)); } else if ("java.lang.Void".equals(name)) {//$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_VOID, 3)); } else if ("java.lang.AssertionError".equals(name)) { //$NON-NLS-1$ typeBinding = this.getTypeBinding(this.scope.getType(TypeConstants.JAVA_LANG_ASSERTIONERROR, 3)); } } catch (AbortCompilation e) { // ignore missing types } if (typeBinding != null && !typeBinding.isRecovered()) { return typeBinding; } return null; } @Override synchronized IAnnotationBinding resolveAnnotation(final Annotation domASTNode) { Object oldNode = this.newAstToOldAst.get(domASTNode); if (oldNode instanceof org.eclipse.jdt.internal.compiler.ast.Annotation) { org.eclipse.jdt.internal.compiler.ast.Annotation internalAstNode = (org.eclipse.jdt.internal.compiler.ast.Annotation) oldNode; IAnnotationBinding domAnnotation = getAnnotationInstance(internalAstNode.getCompilerAnnotation()); if (domAnnotation == null) return null; this.bindingsToAstNodes.put(domAnnotation, domASTNode); return domAnnotation; } return null; } @Override public CompilationUnitScope scope() { return this.scope; } @Override synchronized void store(ASTNode node, org.eclipse.jdt.internal.compiler.ast.ASTNode oldASTNode) { this.newAstToOldAst.put(node, oldASTNode); } @Override synchronized void updateKey(ASTNode node, ASTNode newNode) { Object astNode = this.newAstToOldAst.remove(node); if (astNode != null) { this.newAstToOldAst.put(newNode, astNode); } } @Override ITypeBinding resolveArrayType(ITypeBinding typeBinding, int dimensions) { if (typeBinding instanceof RecoveredTypeBinding) throw new IllegalArgumentException("Cannot be called on a recovered type binding"); //$NON-NLS-1$ ITypeBinding leafComponentType = typeBinding; int actualDimensions = dimensions; if (typeBinding.isArray()) { leafComponentType = typeBinding.getElementType(); actualDimensions += typeBinding.getDimensions(); } if (!(leafComponentType instanceof TypeBinding)) return null; org.eclipse.jdt.internal.compiler.lookup.TypeBinding leafTypeBinding = ((TypeBinding) leafComponentType).binding; if (leafTypeBinding instanceof VoidTypeBinding) { throw new IllegalArgumentException(); } if (typeBinding.isArray()) { return this.getTypeBinding(lookupEnvironment().createArrayType( leafTypeBinding, actualDimensions, insertAnnotations((((TypeBinding) typeBinding).binding).getTypeAnnotations(), dimensions))); } else { return this.getTypeBinding(lookupEnvironment().createArrayType( leafTypeBinding, actualDimensions)); } } private org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] insertAnnotations( org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] annots, int dimensions) { if (dimensions == 0 || annots == null || annots.length == 0) { return annots; } int index = 0; if (dimensions < 0) { for (int i = 0; i < annots.length; i++) { index++; if (annots[i] == null) { if(++dimensions == 0) break; } } if (dimensions < 0) dimensions = 0; // Just means there were no annotations } org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[] newAnnots = new org.eclipse.jdt.internal.compiler.lookup.AnnotationBinding[annots.length - index + dimensions]; System.arraycopy(annots, index, newAnnots, dimensions, annots.length - index); return newAnnots; } }