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