src/share/classes/com/sun/tools/sjavac/comp/Dependencies.java
Print this page
*** 24,35 ****
--- 24,39 ----
*/
package com.sun.tools.sjavac.comp;
import javax.lang.model.element.Element;
+ import javax.lang.model.element.TypeElement;
import java.util.Arrays;
+ import java.util.ArrayList;
import java.util.Comparator;
+ import java.util.List;
+ import java.util.LinkedList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
*** 51,68 ****
// 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);
--- 55,75 ----
// 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;
+ // Map from package name to non-sourcefile classes that the package depends upon.
+ protected Map<Name,Set<ClassSymbol>> classDeps;
// This is the set of all packages that are supplied
// through the java files at the command line.
protected Set<Name> explicitPackages;
! // This is the set of all classes found outside of the source, ie the classpath.
! protected Set<Name> classpathClasses;
!
! // Map from a class name to its public api.
! protected Map<Name,List<String>> publicApiPerClass;
public static Dependencies instance(Context context) {
Dependencies instance = context.get(dependenciesKey);
if (instance == null)
instance = new Dependencies(context);
*** 71,180 ****
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(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,266 ----
private Dependencies(Context context) {
context.put(dependenciesKey, this);
log = Log.instance(context);
deps = new HashMap<>();
+ classDeps = 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>> getSourcefileDependencies() {
Map<String,Set<String>> new_deps = new HashMap<>();
for (Name pkg : explicitPackages) {
Set<Name> set = deps.get(pkg);
if (set != null) {
! String pkg_name = pkg.toString();
! Set<String> new_set = new_deps.get(pkg_name);
if (new_set == null) {
new_set = new HashSet<>();
// Modules beware....
! new_deps.put(":"+pkg_name, new_set);
}
for (Name d : set) {
new_set.add(":"+d.toString());
}
}
}
return new_deps;
}
! /**
! * Fetch the set of classpath dependencies that our sources depend upon.
! * @return
! */
! public Map<String,Set<String>> getClasspathDependencies() {
! Map<String,Set<String>> new_deps = new HashMap<>();
+ for (Name pkg : classDeps.keySet()) {
+ if (explicitPackages.contains(pkg)) {
+ continue;
+ }
+ Set<ClassSymbol> set = classDeps.get(pkg);
+ String pkg_name = pkg.toString();
+ Set<String> new_set = new_deps.get(pkg_name);
+ if (new_set == null) {
+ new_set = new HashSet<>();
+ // Modules beware....
+ new_deps.put(":"+pkg_name, new_set);
+ }
+ for (ClassSymbol c : set) {
+ new_set.add(":. "+c.fullname);
+ }
+ }
+ return new_deps;
}
/**
* 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,List<String>> getPublicApis() {
! // The result map, to be returned.
! Map<String,List<String>> publicApiPerPackage = new HashMap<>();
! // Remember the Name for the sortable String version of the name.
! // I.e. where the dot (.) before the class name is replaced with bang (!).
! Map<String,Name> backToName = new HashMap<>();
! // Sort all the classes on their fullname that includes the package path.
! // Thus all classes belonging to the same package will be in consecutive order.
! Name[] names = publicApiPerClass.keySet().toArray(new Name[0]);
! List<String> fullnames = new ArrayList<>();
! for (Name n : names) {
! String tmp = n.toString();
! int p = tmp.lastIndexOf('.');
! String s = tmp.substring(0,p)+"!"+tmp.substring(p+1);
! fullnames.add(s);
! backToName.put(s, n);
! }
! String[] sorted_fullnames = fullnames.toArray(new String[0]);
! Arrays.sort(sorted_fullnames);
! // Now sorted_fullnames has a list of classes sorted, but with all classes inside
! // a package grouped together. This would not happen if we did not use !.
! String currPkg = "";
! List<String> currPublicApi = null;
!
! for (String n : sorted_fullnames) {
! int lastBang = n.lastIndexOf('!');
! assert(lastBang != -1);
! String pkgName = n.substring(0, lastBang);
! if (!pkgName.equals(currPkg)) {
! if (!currPkg.equals("")) {
// Add default module name ":"
! publicApiPerPackage.put(":"+currPkg, currPublicApi);
}
! currPublicApi = new LinkedList<>();
! currPkg = pkgName;
}
! currPublicApi.addAll(publicApiPerClass.get(backToName.get(n)));
! }
! if (currPkg != "" && currPublicApi != null) {
! publicApiPerPackage.put(":"+currPkg, currPublicApi);
}
return publicApiPerPackage;
}
/**
! * Visit the api of a source class and construct a pubapi string and
* store it into the pubapi_perclass map.
*/
! public void visitPubapiOfSource(TypeElement e) {
! visitPubapi(e);
Name p = ((ClassSymbol)e).packge().fullname;
explicitPackages.add(p);
}
/**
! * Visit the api of a classpath class and construct a pubapi string and
! * store it into the pubapi_perclass map.
! */
! public void visitPubapiOfClasspath(TypeElement e) {
! visitPubapi(e);
! }
!
! /**
! * Visit the api of a class and construct a list of api strings and
! * store it into the pubapi_perclass map.
! */
! private void visitPubapi(TypeElement e) {
! Name n = ((ClassSymbol)e).fullname;
! assert(publicApiPerClass.get(n) == null);
!
! PubapiVisitor v = new PubapiVisitor();
! v.construct(e);
! publicApiPerClass.put(n, v.api);
! }
!
! /**
! * Visit the api of a class and return the constructed pubapi string.
! */
! public static List<String> constructPubapi(TypeElement e, String class_loc_info) {
!
! PubapiVisitor v = new PubapiVisitor();
! if (class_loc_info != null) {
! v.classLocInfo(class_loc_info);
! }
! v.construct(e);
! return v.api;
! }
!
! /**
! * Collect a package dependency. currPkg is marked as depending on depPkg.
*/
! public void reportPackageDep(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);
}
}
+
+ /**
+ * Collect a classpath class dependency. currPkg is marked as depending on depCls.
+ */
+ public void reportClassDep(ClassSymbol depCls) {
+ String s = depCls.classfile != null ? depCls.classfile.toString() : "";
+ if (s.startsWith("RegularFileObject[") &&
+ s.endsWith(".java]")) {
+ // This was a sourcepath dependency, ignore it.
+ return;
+ }
+ Name pkg = depCls.packge().fullname;
+ Set<ClassSymbol> theset = classDeps.get(pkg);
+ if (theset==null) {
+ theset = new HashSet<>();
+ classDeps.put(pkg, theset);
+ }
+ theset.add(depCls);
+ }
+
}