/** * Add <code>type</code> and all its declared nested type(s) to <code>types</code> * * @param type the container type * @param typeBindings upon return, contains all the nested types within <code>type</code> and the * type itself. */ protected void getTypeBindings(final ITypeBinding type, final List<ITypeBinding> typeBindings) { if (type == null) return; typeBindings.add(type); for (ITypeBinding nestedType : type.getDeclaredTypes()) { // typeBindings.add(nestedType); getTypeBindings(nestedType, typeBindings); } }
/** * @param binding must be correspond to a type, method or field declaration. * @return the compilation unit that contains the declaration of the given binding. */ public CompilationUnit getCompilationUnitForBinding(final IBinding binding) { assert binding.getKind() == IBinding.TYPE || binding.getKind() == IBinding.METHOD || binding.getKind() == IBinding.VARIABLE; CompilationUnit domUnit = searchLocallyForBinding(binding); if (domUnit != null) return domUnit; else { final IMember member = (IMember) binding.getJavaElement(); final ICompilationUnit unit; if (member != null) { unit = member.getCompilationUnit(); } else { final ITypeBinding typeBinding = getDeclaringClass(binding); // binary type don't have compilation unit. if (!typeBinding.isFromSource()) return null; if (_typeBinding2ModelCompUnit.get(typeBinding) != null) unit = _typeBinding2ModelCompUnit.get(typeBinding); else { final String qname = typeBinding.getQualifiedName(); unit = getICompilationUnitForTopLevelType(qname); } } if (unit == null) return null; final CompilationUnit astUnit = _modelCompUnit2astCompUnit.get(unit); if (astUnit != null) return astUnit; else { // Note: very expensive operation. we are re-compiling a file with binding information. final ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setResolveBindings(true); parser.setBindingsRecovery(true); parser.setSource(unit); parser.setFocalPosition(0); parser.setIgnoreMethodBodies(true); CompilationUnit resultUnit = (CompilationUnit) parser.createAST(null); _modelCompUnit2astCompUnit.put(unit, resultUnit); return resultUnit; } } }
private List<Declaration> getDeclarationsAnnotatedWith(final ITypeBinding annotationType) { final Map<ASTNode, List<Annotation>> astNode2Anno = getASTNodesWithAnnotations(); if (astNode2Anno.isEmpty()) return Collections.emptyList(); final List<Declaration> decls = new ArrayList<Declaration>(); for (Map.Entry<ASTNode, List<Annotation>> entry : astNode2Anno.entrySet()) { final ASTNode node = entry.getKey(); for (Annotation anno : entry.getValue()) { final IBinding resolvedTypeBinding = anno.resolveTypeBinding(); if (annotationType.isEqualTo(resolvedTypeBinding)) getDeclarations(node, decls); } } return decls; }
/** * @param binding must be correspond to a type, method or field declaration * @return the file that contains the declaration of given binding. */ public IFile getDeclaringFileForBinding(final IBinding binding) { assert binding.getKind() == IBinding.TYPE || binding.getKind() == IBinding.METHOD || binding.getKind() == IBinding.VARIABLE; // check to see whether it is in the current file. IFile file = searchLocallyForIFile(binding); if (file != null) return file; final IMember member = (IMember) binding.getJavaElement(); if (member != null) { final ICompilationUnit unit = member.getCompilationUnit(); return (IFile) unit.getResource(); } else { final ITypeBinding type = getDeclaringClass(binding); assert type.isTopLevel() : "type must be top-level type"; // $NON-NLS-1$ ICompilationUnit unit = _typeBinding2ModelCompUnit.get(type); if (unit != null) return (IFile) unit.getResource(); final String qname = type.getQualifiedName(); unit = getICompilationUnitForTopLevelType(qname); if (unit == null) return null; return (IFile) unit.getResource(); } }
/** * @param binding a type, method or field binding. * @return the top-level type binding that declares <code>binding</code> or itself if it is * already one. */ protected static ITypeBinding getDeclaringClass(final IBinding binding) { assert binding != null : "binding cannot be null"; // $NON-NLS-1$ ITypeBinding aTypeBinding = null; switch (binding.getKind()) { case IBinding.TYPE: aTypeBinding = (ITypeBinding) binding; break; case IBinding.METHOD: aTypeBinding = ((IMethodBinding) binding).getDeclaringClass(); break; case IBinding.VARIABLE: aTypeBinding = ((IVariableBinding) binding).getDeclaringClass(); break; default: throw new IllegalStateException( "unrecognized binding type " + binding.getKind()); // $NON-NLS-1$ } if (aTypeBinding == null) return null; while (!aTypeBinding.isTopLevel()) { aTypeBinding = aTypeBinding.getDeclaringClass(); } return aTypeBinding; }
public PackageDeclaration getPackage(String name) { if (name == null) throw new IllegalArgumentException("name cannot be null"); // $NON-NLS-1$ IPackageFragment[] pkgFrags = PackageUtil.getPackageFragments(name, this); // No packages found, null expected if (pkgFrags.length == 0) return null; try { // If there are no source or class files, we'll need to return // a special implementation of the package decl that expects // no declarations inside it boolean containsNoJavaResources = true; for (IPackageFragment pkg : pkgFrags) { if (pkg.containsJavaResources()) { containsNoJavaResources = false; break; } } if (containsNoJavaResources) return new PackageDeclarationImplNoBinding(pkgFrags); // We should be able to create a class or // source file from one of the packages. // If we find package-info, don't use it, but set // it aside in case it's all we can find. ICompilationUnit compUnit = null; IClassFile classFile = null; ICompilationUnit pkgInfoUnit = null; IClassFile pkgInfoClassFile = null; OUTER: for (IPackageFragment frag : pkgFrags) { if (frag.getKind() == IPackageFragmentRoot.K_SOURCE) { for (ICompilationUnit unit : frag.getCompilationUnits()) { if ("package-info.java".equals(unit.getElementName())) { // $NON-NLS-1$ pkgInfoUnit = unit; } else { compUnit = unit; break OUTER; } } } else { // K_BINARY for (IClassFile file : frag.getClassFiles()) { String cfName = file.getElementName(); if ("package-info.class".equals(cfName)) { // $NON-NLS-1$ pkgInfoClassFile = file; } else if (file.getElementName().indexOf("$") < 0) { // $NON-NLS-1$ classFile = file; break OUTER; } } } } IType type = null; if (compUnit != null) { try { IType[] types = compUnit.getAllTypes(); if (types.length > 0) { type = types[0]; } } catch (JavaModelException e) { } } if (type == null && classFile != null) { type = classFile.getType(); } // Given a type, we can construct a package declaration impl from it, // but we must hide the fact that it came from a real declaration, // as the client requested it without that context if (type != null) { TypeDeclarationImpl typeDecl = (TypeDeclarationImpl) getTypeDeclaration(type); ITypeBinding binding = typeDecl.getDeclarationBinding(); return new PackageDeclarationImpl(binding.getPackage(), typeDecl, this, true, pkgFrags); } // No classes or source files found. Do we have a package-info we can use? if (pkgInfoUnit != null || pkgInfoClassFile != null) { String key = getPackageBindingKey(name); IPackageBinding packageBinding = (IPackageBinding) getBindingFromKey(key, compUnit); if (null != packageBinding) { return new PackageDeclarationImpl(packageBinding, null, this, true, pkgFrags); } } } catch (JavaModelException e) { // Probably bad code; treat as if no types were found } // This package is empty: no types and no package-info. return new PackageDeclarationImplNoBinding(pkgFrags); }
public Collection<Declaration> getDeclarationsAnnotatedWith(AnnotationTypeDeclaration a) { final ITypeBinding annotationType = TypesUtil.getTypeBinding(a); if (annotationType == null || !annotationType.isAnnotation()) return Collections.emptyList(); return getDeclarationsAnnotatedWith(annotationType); }