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; + } + }