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

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


   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.tools.sjavac.comp.dependencies;
  26 

  27 import java.util.HashMap;
  28 import java.util.Map;
  29 import java.util.Set;
  30 import java.util.stream.Collectors;
  31 




  32 import com.sun.source.util.TaskEvent;
  33 import com.sun.source.util.TaskListener;


  34 import com.sun.tools.javac.code.Symbol.PackageSymbol;
  35 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;

  36 import com.sun.tools.javac.util.DefinedBy;
  37 import com.sun.tools.javac.util.DefinedBy.Api;
  38 import com.sun.tools.sjavac.Util;


  39 
  40 public class DependencyCollector implements TaskListener {
  41 
  42     Map<PackageSymbol, Set<PackageSymbol>> collectedDependencies = new HashMap<>();
  43 
  44     @Override
  45     @DefinedBy(Api.COMPILER_TREE)
  46     public void started(TaskEvent e) {


  47     }
  48 
  49     @Override
  50     @DefinedBy(Api.COMPILER_TREE)
  51     public void finished(TaskEvent e) {
  52         if (e.getKind() == TaskEvent.Kind.ANALYZE) {
  53             JCCompilationUnit cu = (JCCompilationUnit) e.getCompilationUnit();

  54             PackageSymbol thisPkg = cu.packge;
  55             if (thisPkg == null) {
  56                 // Compilation unit in default package. See JDK-8048144.
  57                 return;
  58             }
  59             DependencyScanner ds = new DependencyScanner();
  60             cu.accept(ds);
  61             Set<PackageSymbol> pkgDeps = ds.getResult()
  62                                            .stream()
  63                                            .flatMap(dep -> dep.getPackages().stream())
  64                                            .collect(Collectors.toSet());
  65             collectedDependencies.merge(thisPkg, pkgDeps, Util::union);




















  66         }
  67     }
  68 
  69     public Set<PackageSymbol> getSourcePackages() {
  70         return collectedDependencies.keySet();












  71     }
  72 
  73     public Set<PackageSymbol> getDependenciesForPkg(PackageSymbol ps) {
  74         return collectedDependencies.get(ps);













  75     }
  76 }


   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.tools.sjavac.comp.dependencies;
  26 
  27 import java.util.Collection;
  28 import java.util.HashMap;
  29 import java.util.Map;
  30 import java.util.Set;
  31 import java.util.stream.Collectors;
  32 
  33 import javax.tools.JavaFileManager.Location;
  34 import javax.tools.JavaFileObject;
  35 import javax.tools.StandardLocation;
  36 
  37 import com.sun.source.util.TaskEvent;
  38 import com.sun.source.util.TaskListener;
  39 import com.sun.tools.javac.code.Symbol;
  40 import com.sun.tools.javac.code.Symbol.ClassSymbol;
  41 import com.sun.tools.javac.code.Symbol.PackageSymbol;
  42 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
  43 import com.sun.tools.javac.util.Context;
  44 import com.sun.tools.javac.util.DefinedBy;
  45 import com.sun.tools.javac.util.DefinedBy.Api;
  46 import com.sun.tools.sjavac.Log;
  47 import com.sun.tools.sjavac.comp.Dependencies;
  48 import com.sun.tools.sjavac.comp.JavaFileObjectWithLocation;
  49 
  50 public class DependencyCollector implements TaskListener {
  51 
  52     private Context context;
  53 
  54     // Compilation unit -> fully qualified name -> class symbol
  55     public final Map<JCCompilationUnit, Map<String, Set<ClassSymbol>>> collectedDependencies = new HashMap<>();
  56 
  57     public DependencyCollector(Context context) {
  58         this.context = context;
  59     }
  60 
  61     @Override
  62     @DefinedBy(Api.COMPILER_TREE)
  63     public void finished(TaskEvent e) {
  64         if (e.getKind() == TaskEvent.Kind.ANALYZE) {
  65             JCCompilationUnit cu = (JCCompilationUnit) e.getCompilationUnit();
  66             //com.sun.tools.sjavac.Log.info("Finished compilation unit: " + cu.sourcefile);
  67             PackageSymbol thisPkg = cu.packge;
  68             if (thisPkg == null) {
  69                 // Compilation unit in default package. See JDK-8048144.
  70                 return;
  71             }
  72             DependencyScanner ds = new DependencyScanner(context);
  73             cu.accept(ds);
  74 
  75             collectedDependencies.put(cu, ds.dependencies);
  76         }
  77 
  78         if (e.getKind() == TaskEvent.Kind.COMPILATION) {
  79             Dependencies deps = Dependencies.instance(context);
  80 
  81             // Collect dependencies
  82             for (JCCompilationUnit fromCu : collectedDependencies.keySet()) {
  83 
  84                // fqName -> set of type deps
  85                 Map<String, Set<ClassSymbol>> map = collectedDependencies.get(fromCu);
  86                 for (String fromFqName : map.keySet()) {
  87                     Set<ClassSymbol> toSymbols = map.get(fromFqName);
  88                     Set<ClassSymbol> toOutermostSymbols = collectOutermostClassSymbols(toSymbols);
  89 
  90                     for (ClassSymbol toTypeSymbol : toOutermostSymbols) {
  91 
  92                         // Ignore self-dependencies
  93                         if (fromFqName.equals(toTypeSymbol.flatname.toString()))
  94                             continue;
  95                         Location loc = getLocationOf(toTypeSymbol);
  96                         if (loc != StandardLocation.PLATFORM_CLASS_PATH)
  97                             deps.collect(loc, fromCu, fromFqName, toTypeSymbol);
  98                     }
  99                 }
 100             }
 101 
 102             // Collect pubapi of dependencies
 103             Collection<Map<String, Set<ClassSymbol>>> allDepMaps = collectedDependencies.values();
 104             for (Map<String, Set<ClassSymbol>> depMap : allDepMaps) {
 105                 for (String fromFqName : depMap.keySet()) {
 106                     Set<ClassSymbol> toSymbols = depMap.get(fromFqName);
 107                     Set<ClassSymbol> toOutermostSymbols = collectOutermostClassSymbols(toSymbols);
 108                     for (ClassSymbol ts : toOutermostSymbols) {
 109                         // Ignore self-dependencies
 110                         if (fromFqName.equals(ts.flatname.toString()))
 111                             continue;
 112                         if (getLocationOf(ts) != StandardLocation.PLATFORM_CLASS_PATH)
 113                             deps.visitPubapi(ts);
 114                     }
 115                 }
 116             }
 117 
 118         }
 119     }
 120 
 121     private Location getLocationOf(ClassSymbol cs) {
 122         JavaFileObject jfo = cs.outermostClass().classfile;
 123         if (jfo != null)
 124             return ((JavaFileObjectWithLocation<?>) jfo).getLocation();
 125         Log.warn("Could not determine location of " + cs.flatName());
 126         return null;
 127     }
 128 
 129     private Set<ClassSymbol> collectOutermostClassSymbols(Set<ClassSymbol> cs) {
 130         return cs.stream()
 131                  .map(Symbol::outermostClass)
 132                  .collect(Collectors.toSet());
 133     }
 134 }