src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/dependencies/DependencyCollector.java

Print this page
rev 2819 : imported patch my-classpath-deps-00

@@ -22,55 +22,113 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 package com.sun.tools.sjavac.comp.dependencies;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+
 import com.sun.source.util.TaskEvent;
 import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.PackageSymbol;
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.Context;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
-import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.Log;
+import com.sun.tools.sjavac.comp.Dependencies;
+import com.sun.tools.sjavac.comp.JavaFileObjectWithLocation;
 
 public class DependencyCollector implements TaskListener {
 
-    Map<PackageSymbol, Set<PackageSymbol>> collectedDependencies = new HashMap<>();
+    private Context context;
 
-    @Override
-    @DefinedBy(Api.COMPILER_TREE)
-    public void started(TaskEvent e) {
+    // Compilation unit -> fully qualified name -> class symbol
+    public final Map<JCCompilationUnit, Map<String, Set<ClassSymbol>>> collectedDependencies = new HashMap<>();
+
+    public DependencyCollector(Context context) {
+        this.context = context;
     }
 
     @Override
     @DefinedBy(Api.COMPILER_TREE)
     public void finished(TaskEvent e) {
         if (e.getKind() == TaskEvent.Kind.ANALYZE) {
             JCCompilationUnit cu = (JCCompilationUnit) e.getCompilationUnit();
+            //com.sun.tools.sjavac.Log.info("Finished compilation unit: " + cu.sourcefile);
             PackageSymbol thisPkg = cu.packge;
             if (thisPkg == null) {
                 // Compilation unit in default package. See JDK-8048144.
                 return;
             }
-            DependencyScanner ds = new DependencyScanner();
+            DependencyScanner ds = new DependencyScanner(context);
             cu.accept(ds);
-            Set<PackageSymbol> pkgDeps = ds.getResult()
-                                           .stream()
-                                           .flatMap(dep -> dep.getPackages().stream())
-                                           .collect(Collectors.toSet());
-            collectedDependencies.merge(thisPkg, pkgDeps, Util::union);
+
+            collectedDependencies.put(cu, ds.dependencies);
+        }
+
+        if (e.getKind() == TaskEvent.Kind.COMPILATION) {
+            Dependencies deps = Dependencies.instance(context);
+
+            // Collect dependencies
+            for (JCCompilationUnit fromCu : collectedDependencies.keySet()) {
+
+               // fqName -> set of type deps
+                Map<String, Set<ClassSymbol>> map = collectedDependencies.get(fromCu);
+                for (String fromFqName : map.keySet()) {
+                    Set<ClassSymbol> toSymbols = map.get(fromFqName);
+                    Set<ClassSymbol> toOutermostSymbols = collectOutermostClassSymbols(toSymbols);
+
+                    for (ClassSymbol toTypeSymbol : toOutermostSymbols) {
+
+                        // Ignore self-dependencies
+                        if (fromFqName.equals(toTypeSymbol.flatname.toString()))
+                            continue;
+                        Location loc = getLocationOf(toTypeSymbol);
+                        if (loc != StandardLocation.PLATFORM_CLASS_PATH)
+                            deps.collect(loc, fromCu, fromFqName, toTypeSymbol);
+                    }
+                }
+            }
+
+            // Collect pubapi of dependencies
+            Collection<Map<String, Set<ClassSymbol>>> allDepMaps = collectedDependencies.values();
+            for (Map<String, Set<ClassSymbol>> depMap : allDepMaps) {
+                for (String fromFqName : depMap.keySet()) {
+                    Set<ClassSymbol> toSymbols = depMap.get(fromFqName);
+                    Set<ClassSymbol> toOutermostSymbols = collectOutermostClassSymbols(toSymbols);
+                    for (ClassSymbol ts : toOutermostSymbols) {
+                        // Ignore self-dependencies
+                        if (fromFqName.equals(ts.flatname.toString()))
+                            continue;
+                        if (getLocationOf(ts) != StandardLocation.PLATFORM_CLASS_PATH)
+                            deps.visitPubapi(ts);
+                    }
         }
     }
 
-    public Set<PackageSymbol> getSourcePackages() {
-        return collectedDependencies.keySet();
+        }
     }
 
-    public Set<PackageSymbol> getDependenciesForPkg(PackageSymbol ps) {
-        return collectedDependencies.get(ps);
+    private Location getLocationOf(ClassSymbol cs) {
+        JavaFileObject jfo = cs.outermostClass().classfile;
+        if (jfo != null)
+            return ((JavaFileObjectWithLocation<?>) jfo).getLocation();
+        Log.warn("Could not determine location of " + cs.flatName());
+        return null;
+    }
+
+    private Set<ClassSymbol> collectOutermostClassSymbols(Set<ClassSymbol> cs) {
+        return cs.stream()
+                 .map(Symbol::outermostClass)
+                 .collect(Collectors.toSet());
     }
 }