6909470: langtools stub generator should prune unnecessary imports
authorjjg
Mon, 11 Jan 2010 16:18:05 -0800
changeset 4703 800e1750ff18
parent 4702 bb3925c7b58a
child 4704 5206047418c2
6909470: langtools stub generator should prune unnecessary imports Reviewed-by: darcy
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<Name> names = new HashSet<Name>();
+        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<JCTree> defs = new ListBuffer<JCTree>();
+            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 {