src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java
Print this page
rev 2819 : imported patch my-classpath-deps-00
@@ -23,23 +23,29 @@
* questions.
*/
package com.sun.tools.sjavac.comp;
-import javax.lang.model.element.Element;
-import java.util.Arrays;
-import java.util.Comparator;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.lang.model.element.Element;
+import javax.tools.JavaFileManager.Location;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.util.Assert;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Name;
+import com.sun.tools.sjavac.Util;
+import com.sun.tools.sjavac.pubapi.PubApi;
/** Utility class containing dependency information between packages
* and the pubapi for a package.
*
* <p><b>This is NOT part of any supported API.
@@ -50,20 +56,21 @@
public class Dependencies {
protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
// The log to be used for error reporting.
protected Log log;
- // Map from package name to packages that the package depends upon.
- protected Map<Name,Set<Name>> deps;
- // This is the set of all packages that are supplied
- // through the java files at the command line.
- protected Set<Name> explicitPackages;
- // Map from a package name to its public api.
+ // CompilationUnit -> Fully qualified type -> set of dependencies
+ protected Map<JCCompilationUnit, Map<String, Set<TypeSymbol>>> deps = new HashMap<>();
+
+ // CompilationUnit -> Fully qualified type -> set of dependencies
+ protected Map<JCCompilationUnit, Map<String, Set<TypeSymbol>>> cpDeps = new HashMap<>();
+
+ // Map from a class name to its public api.
// Will the Name encode the module in the future?
// If not, this will have to change to map from Module+Name to public api.
- protected Map<Name,StringBuffer> publicApiPerClass;
+ protected Map<ClassSymbol, PubApi> publicApiPerClass = new HashMap<>();
public static Dependencies instance(Context context) {
Dependencies instance = context.get(dependenciesKey);
if (instance == null)
instance = new Dependencies(context);
@@ -71,111 +78,100 @@
}
private Dependencies(Context context) {
context.put(dependenciesKey, this);
log = Log.instance(context);
- deps = new HashMap<>();
- explicitPackages = new HashSet<>();
- publicApiPerClass = new HashMap<>();
}
/**
- * Fetch the set of dependencies that are relevant to the compile
- * that has just been performed. I.e. we are only interested in
- * dependencies for classes that were explicitly compiled.
- * @return
+ * Convert the map from class names to their pubapi to a map
+ * from package names to their pubapi.
*/
- public Map<String,Set<String>> getDependencies() {
- Map<String,Set<String>> new_deps = new HashMap<>();
- if (explicitPackages == null) return new_deps;
- for (Name pkg : explicitPackages) {
- Set<Name> set = deps.get(pkg);
- if (set != null) {
- Set<String> new_set = new_deps.get(pkg.toString());
- if (new_set == null) {
- new_set = new HashSet<>();
- // Modules beware....
- new_deps.put(":"+pkg.toString(), new_set);
- }
- for (Name d : set) {
- new_set.add(":"+d.toString());
- }
- }
- }
- return new_deps;
- }
+ public Map<String, PubApi> getPubapis(Collection<JavaFileObject> explicitJFOs, boolean explicits) {
- static class CompareNames implements Comparator<Name> {
- public int compare(Name a, Name b) {
- return a.toString().compareTo(b.toString());
- }
+ // Maps ":java.lang" to a package level pub api (with only types on top level)
+ Map<String, PubApi> result = new HashMap<>();
+ for (ClassSymbol cs : publicApiPerClass.keySet()) {
+
+ boolean amongExplicits = explicitJFOs.contains(cs.sourcefile);
+ if (explicits != amongExplicits)
+ continue;
+ String pkg = ":" + cs.packge().fullname;
+ PubApi currentPubApi = result.getOrDefault(pkg, new PubApi());
+ result.put(pkg, PubApi.mergeTypes(currentPubApi, publicApiPerClass.get(cs)));
}
- /**
- * Convert the map from class names to their pubapi to a map
- * from package names to their pubapi (which is the sorted concatenation
- * of all the class pubapis)
- */
- public Map<String,String> getPubapis() {
- Map<String,String> publicApiPerPackage = new HashMap<>();
- if (publicApiPerClass == null) return publicApiPerPackage;
- Name[] keys = publicApiPerClass.keySet().toArray(new Name[0]);
- Arrays.sort(keys, new CompareNames());
- StringBuffer newPublicApi = new StringBuffer();
- int i=0;
- String prevPkg = "";
- for (Name k : keys) {
- String cn = k.toString();
- String pn = "";
- int dp = cn.lastIndexOf('.');
- if (dp != -1) {
- pn = cn.substring(0,dp);
- }
- if (!pn.equals(prevPkg)) {
- if (!prevPkg.equals("")) {
- // Add default module name ":"
- publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
- }
- newPublicApi = new StringBuffer();
- prevPkg = pn;
- }
- newPublicApi.append(publicApiPerClass.get(k));
- i++;
- }
- if (!prevPkg.equals(""))
- publicApiPerPackage.put(":"+prevPkg, newPublicApi.toString());
- return publicApiPerPackage;
+ return result;
}
/**
- * Visit the api of a class and construct a pubapi string and
+ * Visit the api of a class and construct a pubapi and
* store it into the pubapi_perclass map.
*/
+ @SuppressWarnings("deprecation")
public void visitPubapi(Element e) {
- Name n = ((ClassSymbol)e).fullname;
- Name p = ((ClassSymbol)e).packge().fullname;
- StringBuffer sb = publicApiPerClass.get(n);
- Assert.check(sb == null);
- sb = new StringBuffer();
- PubapiVisitor v = new PubapiVisitor(sb);
+
+ // Skip anonymous classes for now
+ if (e == null)
+ return;
+
+ PubapiVisitor v = new PubapiVisitor();
v.visit(e);
- if (sb.length()>0) {
- publicApiPerClass.put(n, sb);
+ publicApiPerClass.put((ClassSymbol) e, v.getCollectedPubApi());
}
- explicitPackages.add(p);
+
+ public void collect(Location loc, JCCompilationUnit cu, String from, TypeSymbol toSym) {
+
+ Map<JCCompilationUnit, Map<String, Set<TypeSymbol>>> depsMap;
+
+ // TODO: Just because it's not CLASS_PATH doesn't mean it's to-be-compiled path
+ depsMap = loc == StandardLocation.CLASS_PATH ? cpDeps : deps;
+
+ if (!depsMap.containsKey(cu))
+ depsMap.put(cu, new HashMap<>());
+ Map<String, Set<TypeSymbol>> map = depsMap.get(cu);
+ map.merge(from, Collections.singleton(toSym), Util::union);
}
- /**
- * Collect a dependency. curr_pkg is marked as depending on dep_pkg.
- */
- public void collect(Name currPkg, Name depPkg) {
- if (!currPkg.equals(depPkg)) {
- Set<Name> theset = deps.get(currPkg);
- if (theset==null) {
- theset = new HashSet<>();
- deps.put(currPkg, theset);
+ // Package -> Type [from] -> Set of Type [to]
+ public Map<String, Map<String, Set<String>>> getDependencies(Collection<JavaFileObject> explicits) {
+ return getTypeDependenciesHelper(explicits, deps);
+ }
+ public Map<String, Map<String, Set<String>>> getCpDependencies(Collection<JavaFileObject> explicits) {
+ return getTypeDependenciesHelper(explicits, cpDeps);
}
- theset.add(depPkg);
+ public Map<String, Map<String, Set<String>>> getTypeDependenciesHelper(Collection<JavaFileObject> explicits,
+ Map<JCCompilationUnit, Map<String, Set<TypeSymbol>>> depsMap) {
+ Map<String, Map<String, Set<String>>> result = new HashMap<>();
+ for (JCCompilationUnit cu : depsMap.keySet()) {
+
+ if (!explicits.contains(cu.sourcefile))
+ continue;
+
+ // Dependencies to add to package entry
+ Map<String, Set<TypeSymbol>> src = depsMap.getOrDefault(cu, Collections.emptyMap());
+
+ // Sjavac does currently not handle default packages.
+ if (cu.getPackage() == null)
+ continue;
+
+ String key = ":" + cu.getPackage().packge.fullname.toString();
+
+ // Find (or create) destination
+ Map<String, Set<String>> dst;
+ if (result.containsKey(key))
+ dst = result.get(key);
+ else
+ result.put(key, dst = new HashMap<>());
+
+ for (String fqFrom : src.keySet()) {
+ dst.put(fqFrom, src.get(fqFrom)
+ .stream()
+ .map(ts -> ts.type.tsym.flatName().toString())
+ .collect(Collectors.toSet()));
}
}
+ return result;
+ }
+
}