public IBinding[] getDeclarationsInScope(SimpleName selector, int flags) { try { // special case for switch on enum if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) { ITypeBinding binding = ((SwitchStatement) selector.getParent().getParent()) .getExpression() .resolveTypeBinding(); if (binding != null && binding.isEnum()) { return getEnumContants(binding); } } ITypeBinding parentTypeBinding = Bindings.getBindingOfParentType(selector); if (parentTypeBinding != null) { ITypeBinding binding = getQualifier(selector); DefaultBindingRequestor requestor = new DefaultBindingRequestor(parentTypeBinding, flags); if (binding == null) { addLocalDeclarations(selector, flags, requestor); addTypeDeclarations(parentTypeBinding, flags, requestor); } else { addInherited(binding, flags, requestor); } List<IBinding> result = requestor.getResult(); return result.toArray(new IBinding[result.size()]); } return NO_BINDING; } finally { clearLists(); } }
public boolean isDeclaredInScope(IBinding declaration, SimpleName selector, int flags) { try { // special case for switch on enum if (selector.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) { ITypeBinding binding = ((SwitchStatement) selector.getParent().getParent()) .getExpression() .resolveTypeBinding(); if (binding != null && binding.isEnum()) { return hasEnumContants(declaration, binding.getTypeDeclaration()); } } ITypeBinding parentTypeBinding = Bindings.getBindingOfParentTypeContext(selector); if (parentTypeBinding != null) { ITypeBinding binding = getQualifier(selector); SearchRequestor requestor = new SearchRequestor(declaration, parentTypeBinding, flags); if (binding == null) { addLocalDeclarations(selector, flags, requestor); if (requestor.found()) return requestor.isVisible(); addTypeDeclarations(parentTypeBinding, flags, requestor); if (requestor.found()) return requestor.isVisible(); } else { addInherited(binding, flags, requestor); if (requestor.found()) return requestor.isVisible(); } } return false; } finally { clearLists(); } }
/** * Collects all elements available in a type: its hierarchy and its outer scopes. * * @param binding The type binding * @param flags Flags defining the elements to report * @param requestor the requestor to which all results are reported * @return return <code>true</code> if the requestor has reported the binding as found and no * further results are required */ private boolean addTypeDeclarations( ITypeBinding binding, int flags, IBindingRequestor requestor) { if (hasFlag(TYPES, flags) && !binding.isAnonymous()) { if (requestor.acceptBinding(binding)) return true; ITypeBinding[] typeParameters = binding.getTypeParameters(); for (int i = 0; i < typeParameters.length; i++) { if (requestor.acceptBinding(typeParameters[i])) return true; } } addInherited(binding, flags, requestor); // add inherited if (binding.isLocal()) { addOuterDeclarationsForLocalType(binding, flags, requestor); } else { ITypeBinding declaringClass = binding.getDeclaringClass(); if (declaringClass != null) { if (addTypeDeclarations(declaringClass, flags, requestor)) // Recursively add inherited return true; } else if (hasFlag(TYPES, flags)) { if (fRoot.findDeclaringNode(binding) != null) { List<AbstractTypeDeclaration> types = fRoot.types(); for (int i = 0; i < types.size(); i++) { if (requestor.acceptBinding(types.get(i).resolveBinding())) return true; } } } } return false; }
private static String getSignature(IBinding binding) { if (binding != null) { switch (binding.getKind()) { case IBinding.METHOD: StringBuffer buf = new StringBuffer(); buf.append('M'); buf.append(binding.getName()).append('('); ITypeBinding[] parameters = ((IMethodBinding) binding).getParameterTypes(); for (int i = 0; i < parameters.length; i++) { if (i > 0) { buf.append(','); } ITypeBinding paramType = parameters[i].getErasure(); buf.append(paramType.getQualifiedName()); } buf.append(')'); return buf.toString(); case IBinding.VARIABLE: return 'V' + binding.getName(); case IBinding.TYPE: return 'T' + binding.getName(); } } return null; }
private static boolean isTypeInScope( ITypeBinding declaring, ITypeBinding context, boolean includeHierarchy) { ITypeBinding curr = context.getTypeDeclaration(); while (curr != null && curr != declaring) { if (includeHierarchy && isInSuperTypeHierarchy(declaring, curr)) { return true; } curr = curr.getDeclaringClass(); } return curr == declaring; }
@Override protected void initialize(ITypeBinding binding) { Assert.isTrue(binding.isGenericType()); super.initialize(binding); TypeEnvironment environment = getEnvironment(); ITypeBinding[] typeParameters = binding.getTypeParameters(); fTypeParameters = new TypeVariable[typeParameters.length]; for (int i = 0; i < typeParameters.length; i++) { fTypeParameters[i] = (TypeVariable) environment.create(typeParameters[i]); } }
private static ITypeBinding getDeclaringType(IBinding binding) { switch (binding.getKind()) { case IBinding.VARIABLE: return ((IVariableBinding) binding).getDeclaringClass(); case IBinding.METHOD: return ((IMethodBinding) binding).getDeclaringClass(); case IBinding.TYPE: ITypeBinding typeBinding = (ITypeBinding) binding; if (typeBinding.getDeclaringClass() != null) { return typeBinding; } return typeBinding; } return null; }
private static ITypeBinding getQualifier(SimpleName selector) { ASTNode parent = selector.getParent(); switch (parent.getNodeType()) { case ASTNode.METHOD_INVOCATION: MethodInvocation decl = (MethodInvocation) parent; if (selector == decl.getName()) { return getBinding(decl.getExpression()); } return null; case ASTNode.QUALIFIED_NAME: QualifiedName qualifiedName = (QualifiedName) parent; if (selector == qualifiedName.getName()) { return getBinding(qualifiedName.getQualifier()); } return null; case ASTNode.FIELD_ACCESS: FieldAccess fieldAccess = (FieldAccess) parent; if (selector == fieldAccess.getName()) { return getBinding(fieldAccess.getExpression()); } return null; case ASTNode.SUPER_FIELD_ACCESS: { ITypeBinding curr = Bindings.getBindingOfParentType(parent); return curr.getSuperclass(); } case ASTNode.SUPER_METHOD_INVOCATION: { SuperMethodInvocation superInv = (SuperMethodInvocation) parent; if (selector == superInv.getName()) { ITypeBinding curr = Bindings.getBindingOfParentType(parent); return curr.getSuperclass(); } return null; } default: if (parent instanceof Type) { // bug 67644: in 'a.new X()', all member types of A are visible as location of X. ASTNode normalizedNode = ASTNodes.getNormalizedNode(parent); if (normalizedNode.getLocationInParent() == ClassInstanceCreation.TYPE_PROPERTY) { ClassInstanceCreation creation = (ClassInstanceCreation) normalizedNode.getParent(); return getBinding(creation.getExpression()); } } return null; } }
private boolean hasEnumContants(IBinding declaration, ITypeBinding binding) { IVariableBinding[] declaredFields = binding.getDeclaredFields(); for (int i = 0; i < declaredFields.length; i++) { IVariableBinding curr = declaredFields[i]; if (curr == declaration) return true; } return false; }
@Override public boolean visit(SwitchCase node) { // switch on enum allows to use enum constants without qualification if (hasFlag(VARIABLES, fFlags) && !node.isDefault() && isInside(node.getExpression())) { SwitchStatement switchStatement = (SwitchStatement) node.getParent(); ITypeBinding binding = switchStatement.getExpression().resolveTypeBinding(); if (binding != null && binding.isEnum()) { IVariableBinding[] declaredFields = binding.getDeclaredFields(); for (int i = 0; i < declaredFields.length; i++) { IVariableBinding curr = declaredFields[i]; if (curr.isEnumConstant()) { fBreak = fRequestor.acceptBinding(curr); if (fBreak) return false; } } } } return false; }
private IVariableBinding[] getEnumContants(ITypeBinding binding) { IVariableBinding[] declaredFields = binding.getDeclaredFields(); ArrayList<IVariableBinding> res = new ArrayList<IVariableBinding>(declaredFields.length); for (int i = 0; i < declaredFields.length; i++) { IVariableBinding curr = declaredFields[i]; if (curr.isEnumConstant()) { res.add(curr); } } return res.toArray(new IVariableBinding[res.size()]); }
/* * This method is different from Binding.isSuperType as type declarations are compared */ private static boolean isInSuperTypeHierarchy( ITypeBinding possibleSuperTypeDecl, ITypeBinding type) { if (type == possibleSuperTypeDecl) { return true; } ITypeBinding superClass = type.getSuperclass(); if (superClass != null) { if (isInSuperTypeHierarchy(possibleSuperTypeDecl, superClass.getTypeDeclaration())) { return true; } } if (possibleSuperTypeDecl.isInterface()) { ITypeBinding[] superInterfaces = type.getInterfaces(); for (int i = 0; i < superInterfaces.length; i++) { if (isInSuperTypeHierarchy( possibleSuperTypeDecl, superInterfaces[i].getTypeDeclaration())) { return true; } } } return false; }
/** * Evaluates if the declaration is visible in a certain context. * * @param binding The binding of the declaration to examine * @param context The context to test in * @return Returns */ public static boolean isVisible(IBinding binding, ITypeBinding context) { if (binding.getKind() == IBinding.VARIABLE && !((IVariableBinding) binding).isField()) { return true; // all local variables found are visible } ITypeBinding declaring = getDeclaringType(binding); if (declaring == null) { return false; } declaring = declaring.getTypeDeclaration(); int modifiers = binding.getModifiers(); if (Modifier.isPublic(modifiers) || declaring.isInterface()) { return true; } else if (Modifier.isProtected(modifiers) || !Modifier.isPrivate(modifiers)) { if (declaring.getPackage() == context.getPackage()) { return true; } return isTypeInScope(declaring, context, Modifier.isProtected(modifiers)); } // private visibility return isTypeInScope(declaring, context, false); }
/** * Collects all elements available in a type and its hierarchy * * @param binding The type binding * @param flags Flags defining the elements to report * @param requestor the requestor to which all results are reported * @return return <code>true</code> if the requestor has reported the binding as found and no * further results are required */ private boolean addInherited(ITypeBinding binding, int flags, IBindingRequestor requestor) { if (!fTypesVisited.add(binding)) { return false; } if (hasFlag(VARIABLES, flags)) { IVariableBinding[] variableBindings = binding.getDeclaredFields(); for (int i = 0; i < variableBindings.length; i++) { if (requestor.acceptBinding(variableBindings[i])) return true; } } if (hasFlag(METHODS, flags)) { IMethodBinding[] methodBindings = binding.getDeclaredMethods(); for (int i = 0; i < methodBindings.length; i++) { IMethodBinding curr = methodBindings[i]; if (!curr.isSynthetic() && !curr.isConstructor()) { if (requestor.acceptBinding(curr)) return true; } } } if (hasFlag(TYPES, flags)) { ITypeBinding[] typeBindings = binding.getDeclaredTypes(); for (int i = 0; i < typeBindings.length; i++) { ITypeBinding curr = typeBindings[i]; if (requestor.acceptBinding(curr)) return true; } } ITypeBinding superClass = binding.getSuperclass(); if (superClass != null) { if (addInherited(superClass, flags, requestor)) // recursive return true; } else if (binding.isArray()) { if (addInherited( fRoot.getAST().resolveWellKnownType("java.lang.Object"), flags, requestor)) // $NON-NLS-1$ return true; } ITypeBinding[] interfaces = binding.getInterfaces(); // includes looking for methods: abstract, unimplemented methods for (int i = 0; i < interfaces.length; i++) { if (addInherited(interfaces[i], flags, requestor)) // recursive return true; } return false; }