# HG changeset patch # User jjg # Date 1263255485 28800 # Node ID 800e1750ff18fd0281063cde06707c1519b67d84 # Parent bb3925c7b58ab1d908b9d9b8d673307911602137 6909470: langtools stub generator should prune unnecessary imports Reviewed-by: darcy diff -r bb3925c7b58a -r 800e1750ff18 langtools/make/tools/GenStubs/GenStubs.java --- a/langtools/make/tools/GenStubs/GenStubs.java Mon Jan 11 14:17:01 2010 -0800 +++ b/langtools/make/tools/GenStubs/GenStubs.java Mon Jan 11 16:18:05 2010 -0800 @@ -22,6 +22,7 @@ * CA 95054 USA or visit www.sun.com if you need additional information or * have any questions. */ + import java.io.*; import java.util.*; import javax.tools.JavaFileObject; @@ -41,15 +42,22 @@ import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; +import com.sun.tools.javac.tree.JCTree.JCFieldAccess; +import com.sun.tools.javac.tree.JCTree.JCIdent; +import com.sun.tools.javac.tree.JCTree.JCImport; import com.sun.tools.javac.tree.JCTree.JCLiteral; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCModifiers; -import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.tree.Pretty; +import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.TreeTranslator; +import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.ListBuffer; +import com.sun.tools.javac.util.Name; +import javax.tools.JavaFileManager; /** * Generate stub source files by removing implementation details from input files. @@ -161,6 +169,7 @@ void makeStub(StandardJavaFileManager fm, CompilationUnitTree tree) throws IOException { CompilationUnitTree tree2 = new StubMaker().translate(tree); + CompilationUnitTree tree3 = new ImportCleaner(fm).removeRedundantImports(tree2); String className = fm.inferBinaryName(StandardLocation.SOURCE_PATH, tree.getSourceFile()); JavaFileObject fo = fm.getJavaFileForOutput(StandardLocation.SOURCE_OUTPUT, @@ -168,7 +177,7 @@ // System.err.println("Writing " + className + " to " + fo.getName()); Writer out = fo.openWriter(); try { - new Pretty(out, true).printExpr((JCTree) tree2); + new Pretty(out, true).printExpr((JCTree) tree3); } finally { out.close(); } @@ -272,6 +281,53 @@ } } + class ImportCleaner extends TreeScanner { + private Set names = new HashSet(); + private TreeMaker m; + + ImportCleaner(JavaFileManager fm) { + // ImportCleaner itself doesn't require a filemanager, but instantiating + // a TreeMaker does, indirectly (via ClassReader, sigh) + Context c = new Context(); + c.put(JavaFileManager.class, fm); + m = TreeMaker.instance(c); + } + + CompilationUnitTree removeRedundantImports(CompilationUnitTree t) { + JCCompilationUnit tree = (JCCompilationUnit) t; + tree.accept(this); + ListBuffer defs = new ListBuffer(); + for (JCTree def: tree.defs) { + if (def.getTag() == JCTree.IMPORT) { + JCImport imp = (JCImport) def; + if (imp.qualid.getTag() == JCTree.SELECT) { + JCFieldAccess qualid = (JCFieldAccess) imp.qualid; + if (!qualid.name.toString().equals("*") + && !names.contains(qualid.name)) { + continue; + } + } + } + defs.add(def); + } + return m.TopLevel(tree.packageAnnotations, tree.pid, defs.toList()); + } + + @Override + public void visitImport(JCImport tree) { } // ignore names found in imports + + @Override + public void visitIdent(JCIdent tree) { + names.add(tree.name); + } + + @Override + public void visitSelect(JCFieldAccess tree) { + super.visitSelect(tree); + names.add(tree.name); + } + } + //---------- Ant Invocation ------------------------------------------------ public static class Ant extends MatchingTask {