public ArrayList<String> collectApiRefs(final CompilationUnitDeclaration cud) { final Set<String> apiRefs = new HashSet<String>(); class DependencyVisitor extends TypeRefVisitor { public DependencyVisitor() { super(cud); } @Override public boolean visit(Argument arg, BlockScope scope) { // Adapted from {@link Argument#traverse}. // Don't visit annotations. if (arg.type != null) { arg.type.traverse(this, scope); } return false; } @Override public boolean visit(Argument arg, ClassScope scope) { // Adapted from {@link Argument#traverse}. // Don't visit annotations. if (arg.type != null) { arg.type.traverse(this, scope); } return false; } @Override public boolean visit(Block block, BlockScope scope) { assert false : "Error in DepedencyVisitor; should never visit a block"; return false; } @Override public boolean visit(Clinit clinit, ClassScope scope) { return false; } @Override public boolean visit(ConstructorDeclaration ctor, ClassScope scope) { if (ctor.typeParameters != null) { int typeParametersLength = ctor.typeParameters.length; for (int i = 0; i < typeParametersLength; i++) { ctor.typeParameters[i].traverse(this, ctor.scope); } } traverse(ctor); return false; } @Override public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) { // Don't visit javadoc. // Don't visit annotations. if (fieldDeclaration.type != null) { fieldDeclaration.type.traverse(this, scope); } // Don't visit initialization. return false; } @Override public boolean visit(Initializer initializer, MethodScope scope) { return false; } @Override public boolean visit(MethodDeclaration meth, ClassScope scope) { if (meth.typeParameters != null) { int typeParametersLength = meth.typeParameters.length; for (int i = 0; i < typeParametersLength; i++) { meth.typeParameters[i].traverse(this, meth.scope); } } if (meth.returnType != null) { meth.returnType.traverse(this, meth.scope); } traverse(meth); return false; } @Override public boolean visit(TypeDeclaration typeDeclaration, ClassScope scope) { traverse(typeDeclaration); return false; } @Override public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) { traverse(typeDeclaration); return false; } @Override protected void onBinaryTypeRef( BinaryTypeBinding referencedType, CompilationUnitDeclaration unitOfReferrer, Expression expression) { if (!String.valueOf(referencedType.getFileName()).endsWith(".java")) { // ignore binary-only annotations return; } addReference(referencedType); } @Override protected void onTypeRef( SourceTypeBinding referencedType, CompilationUnitDeclaration unitOfReferrer) { addReference(referencedType); } private void addReference(ReferenceBinding referencedType) { String binaryName = CharOperation.toString(referencedType.compoundName); apiRefs.add(BinaryName.toSourceName(binaryName)); } /** Adapted from {@link MethodDeclaration#traverse}. */ private void traverse(AbstractMethodDeclaration meth) { // Don't visit javadoc. // Don't visit annotations. if (meth.arguments != null) { int argumentLength = meth.arguments.length; for (int i = 0; i < argumentLength; i++) { meth.arguments[i].traverse(this, meth.scope); } } if (meth.thrownExceptions != null) { int thrownExceptionsLength = meth.thrownExceptions.length; for (int i = 0; i < thrownExceptionsLength; i++) { meth.thrownExceptions[i].traverse(this, meth.scope); } } // Don't visit method bodies. } /** Adapted from {@link TypeDeclaration#traverse}. */ private void traverse(TypeDeclaration type) { // Don't visit javadoc. // Don't visit annotations. if (type.superclass != null) { type.superclass.traverse(this, type.scope); } if (type.superInterfaces != null) { int length = type.superInterfaces.length; for (int i = 0; i < length; i++) { type.superInterfaces[i].traverse(this, type.scope); } } if (type.typeParameters != null) { int length = type.typeParameters.length; for (int i = 0; i < length; i++) { type.typeParameters[i].traverse(this, type.scope); } } if (type.memberTypes != null) { int length = type.memberTypes.length; for (int i = 0; i < length; i++) { type.memberTypes[i].traverse(this, type.scope); } } if (type.fields != null) { int length = type.fields.length; for (int i = 0; i < length; i++) { FieldDeclaration field; if ((field = type.fields[i]).isStatic()) { field.traverse(this, type.staticInitializerScope); } else { field.traverse(this, type.initializerScope); } } } if (type.methods != null) { int length = type.methods.length; for (int i = 0; i < length; i++) { type.methods[i].traverse(this, type.scope); } } } } DependencyVisitor visitor = new DependencyVisitor(); cud.traverse(visitor, cud.scope); ArrayList<String> result = new ArrayList<String>(apiRefs); Collections.sort(result); return result; }
public char[][][] collect() throws JavaModelException { if (this.type != null) { // Collect the paths of the cus that are in the hierarchy of the given type this.result = new char[1][][]; this.resultIndex = 0; JavaProject javaProject = (JavaProject) this.type.getJavaProject(); this.locator.initialize(javaProject, 0); try { if (this.type.isBinary()) { BinaryTypeBinding binding = this.locator.cacheBinaryType(this.type, null); if (binding != null) collectSuperTypeNames(binding); } else { ICompilationUnit unit = this.type.getCompilationUnit(); SourceType sourceType = (SourceType) this.type; boolean isTopLevelOrMember = sourceType.getOuterMostLocalContext() == null; CompilationUnitDeclaration parsedUnit = buildBindings(unit, isTopLevelOrMember); if (parsedUnit != null) { TypeDeclaration typeDecl = new ASTNodeFinder(parsedUnit).findType(this.type); if (typeDecl != null && typeDecl.binding != null) collectSuperTypeNames(typeDecl.binding); } } } catch (AbortCompilation e) { // problem with classpath: report inacurrate matches return null; } if (this.result.length > this.resultIndex) System.arraycopy( this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex); return this.result; } // Collect the paths of the cus that declare a type which matches declaringQualification + // declaringSimpleName String[] paths = this.getPathsOfDeclaringType(); if (paths == null) return null; // Create bindings from source types and binary types and collect super type names of the type // declaration // that match the given declaring type Util.sort(paths); // sort by projects JavaProject previousProject = null; this.result = new char[1][][]; this.resultIndex = 0; for (int i = 0, length = paths.length; i < length; i++) { try { Openable openable = this.locator.handleFactory.createOpenable(paths[i], this.locator.scope); if (openable == null) continue; // outside classpath IJavaProject project = openable.getJavaProject(); if (!project.equals(previousProject)) { previousProject = (JavaProject) project; this.locator.initialize(previousProject, 0); } if (openable instanceof ICompilationUnit) { ICompilationUnit unit = (ICompilationUnit) openable; CompilationUnitDeclaration parsedUnit = buildBindings( unit, true /*only toplevel and member types are visible to the focus type*/); if (parsedUnit != null) parsedUnit.traverse(new TypeDeclarationVisitor(), parsedUnit.scope); } else if (openable instanceof IClassFile) { IClassFile classFile = (IClassFile) openable; BinaryTypeBinding binding = this.locator.cacheBinaryType(classFile.getType(), null); if (matches(binding)) collectSuperTypeNames(binding); } } catch (AbortCompilation e) { // ignore: continue with next element } catch (JavaModelException e) { // ignore: continue with next element } } if (this.result.length > this.resultIndex) System.arraycopy( this.result, 0, this.result = new char[this.resultIndex][][], 0, this.resultIndex); return this.result; }