src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/Dependencies.java
Print this page
rev 2819 : imported patch my-classpath-deps-00
*** 23,45 ****
* questions.
*/
package com.sun.tools.sjavac.comp;
! import javax.lang.model.element.Element;
! import java.util.Arrays;
! import java.util.Comparator;
import java.util.HashMap;
- import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
! import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Log;
! import com.sun.tools.javac.util.Name;
/** Utility class containing dependency information between packages
* and the pubapi for a package.
*
* <p><b>This is NOT part of any supported API.
--- 23,51 ----
* questions.
*/
package com.sun.tools.sjavac.comp;
! import java.util.Collection;
! import java.util.Collections;
import java.util.HashMap;
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.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.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,69 ****
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.
// 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;
public static Dependencies instance(Context context) {
Dependencies instance = context.get(dependenciesKey);
if (instance == null)
instance = new Dependencies(context);
--- 56,76 ----
public class Dependencies {
protected static final Context.Key<Dependencies> dependenciesKey = new Context.Key<>();
// The log to be used for error reporting.
protected Log log;
! // 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<ClassSymbol, PubApi> publicApiPerClass = new HashMap<>();
public static Dependencies instance(Context context) {
Dependencies instance = context.get(dependenciesKey);
if (instance == null)
instance = new Dependencies(context);
*** 71,181 ****
}
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
*/
! 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;
! }
! static class CompareNames implements Comparator<Name> {
! public int compare(Name a, Name b) {
! return a.toString().compareTo(b.toString());
! }
}
! /**
! * 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;
}
/**
! * Visit the api of a class and construct a pubapi string and
* store it into the pubapi_perclass map.
*/
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);
v.visit(e);
! if (sb.length()>0) {
! publicApiPerClass.put(n, sb);
}
! explicitPackages.add(p);
}
! /**
! * 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);
}
! theset.add(depPkg);
}
}
}
--- 78,177 ----
}
private Dependencies(Context context) {
context.put(dependenciesKey, this);
log = Log.instance(context);
}
/**
! * Convert the map from class names to their pubapi to a map
! * from package names to their pubapi.
*/
! public Map<String, PubApi> getPubapis(Collection<JavaFileObject> explicitJFOs, boolean explicits) {
! // 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)));
}
! return result;
}
/**
! * 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) {
!
! // Skip anonymous classes for now
! if (e == null)
! return;
!
! PubapiVisitor v = new PubapiVisitor();
v.visit(e);
! publicApiPerClass.put((ClassSymbol) e, v.getCollectedPubApi());
}
!
! 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);
}
! // 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);
}
! 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;
+ }
+
}