author | mchung |
Wed, 21 Nov 2018 22:34:01 -0800 | |
changeset 52650 | c16b6cc93272 |
parent 47216 | 71c04702a3d5 |
child 52988 | 7c8f8949a07d |
permissions | -rw-r--r-- |
25874 | 1 |
/* |
2 |
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. |
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
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 |
*/ |
|
34752
9c262a013456
8145342: Some copyright notices are inconsistently and ill formatted
vasya
parents:
30846
diff
changeset
|
25 |
|
25874 | 26 |
package com.sun.tools.jdeps; |
27 |
||
36526 | 28 |
import java.lang.module.ModuleDescriptor; |
29 |
import java.net.URI; |
|
25874 | 30 |
import java.util.Collections; |
31 |
import java.util.HashMap; |
|
32 |
import java.util.HashSet; |
|
33 |
import java.util.Map; |
|
34 |
import java.util.Set; |
|
35 |
||
36 |
/** |
|
38524 | 37 |
* Jdeps internal representation of module for dependency analysis. |
25874 | 38 |
*/ |
36526 | 39 |
class Module extends Archive { |
38524 | 40 |
static final Module UNNAMED_MODULE = new UnnamedModule(); |
41 |
static final String JDK_UNSUPPORTED = "jdk.unsupported"; |
|
42 |
||
43 |
static final boolean DEBUG = Boolean.getBoolean("jdeps.debug"); |
|
36526 | 44 |
static void trace(String fmt, Object... args) { |
38524 | 45 |
trace(DEBUG, fmt, args); |
46 |
} |
|
47 |
||
48 |
static void trace(boolean traceOn, String fmt, Object... args) { |
|
36526 | 49 |
if (traceOn) { |
50 |
System.err.format(fmt, args); |
|
51 |
} |
|
52 |
} |
|
25874 | 53 |
|
38524 | 54 |
private final ModuleDescriptor descriptor; |
55 |
private final Map<String, Set<String>> exports; |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
56 |
private final Map<String, Set<String>> opens; |
38524 | 57 |
private final boolean isSystem; |
58 |
private final URI location; |
|
36526 | 59 |
|
38524 | 60 |
protected Module(String name) { |
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
61 |
this(name, null, false); |
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
62 |
} |
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
63 |
|
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
64 |
protected Module(String name, ModuleDescriptor descriptor, boolean isSystem) { |
38524 | 65 |
super(name); |
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
66 |
this.descriptor = descriptor; |
38524 | 67 |
this.location = null; |
68 |
this.exports = Collections.emptyMap(); |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
69 |
this.opens = Collections.emptyMap(); |
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
70 |
this.isSystem = isSystem; |
38524 | 71 |
} |
36526 | 72 |
|
73 |
private Module(String name, |
|
74 |
URI location, |
|
75 |
ModuleDescriptor descriptor, |
|
25874 | 76 |
Map<String, Set<String>> exports, |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
77 |
Map<String, Set<String>> opens, |
38524 | 78 |
boolean isSystem, |
36526 | 79 |
ClassFileReader reader) { |
80 |
super(name, location, reader); |
|
81 |
this.descriptor = descriptor; |
|
82 |
this.location = location; |
|
25874 | 83 |
this.exports = Collections.unmodifiableMap(exports); |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
84 |
this.opens = Collections.unmodifiableMap(opens); |
38524 | 85 |
this.isSystem = isSystem; |
36526 | 86 |
} |
87 |
||
88 |
/** |
|
89 |
* Returns module name |
|
90 |
*/ |
|
91 |
public String name() { |
|
41998
feae61dc2280
8169606: jdeps --list-reduced-deps should not show java.base as all modules require it
mchung
parents:
41860
diff
changeset
|
92 |
return descriptor != null ? descriptor.name() : getName(); |
36526 | 93 |
} |
94 |
||
95 |
public boolean isNamed() { |
|
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
96 |
return descriptor != null; |
25874 | 97 |
} |
98 |
||
36526 | 99 |
public boolean isAutomatic() { |
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
100 |
return descriptor != null && descriptor.isAutomatic(); |
36526 | 101 |
} |
102 |
||
103 |
public Module getModule() { |
|
104 |
return this; |
|
105 |
} |
|
106 |
||
107 |
public ModuleDescriptor descriptor() { |
|
108 |
return descriptor; |
|
109 |
} |
|
110 |
||
38524 | 111 |
public URI location() { |
112 |
return location; |
|
25874 | 113 |
} |
114 |
||
38524 | 115 |
public boolean isJDK() { |
116 |
String mn = name(); |
|
117 |
return isSystem && |
|
118 |
(mn.startsWith("java.") || mn.startsWith("jdk.") || mn.startsWith("javafx.")); |
|
119 |
} |
|
120 |
||
121 |
public boolean isSystem() { |
|
122 |
return isSystem; |
|
25874 | 123 |
} |
124 |
||
125 |
public Map<String, Set<String>> exports() { |
|
126 |
return exports; |
|
127 |
} |
|
128 |
||
129 |
public Set<String> packages() { |
|
38524 | 130 |
return descriptor.packages(); |
25874 | 131 |
} |
132 |
||
41860
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
133 |
public boolean isJDKUnsupported() { |
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
134 |
return JDK_UNSUPPORTED.equals(this.name()); |
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
135 |
} |
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
136 |
|
25874 | 137 |
/** |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
138 |
* Converts this module to a normal module with the given dependences |
36526 | 139 |
* |
140 |
* @throws IllegalArgumentException if this module is not an automatic module |
|
25874 | 141 |
*/ |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
142 |
public Module toNormalModule(Map<String, Boolean> requires) { |
36526 | 143 |
if (!isAutomatic()) { |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
144 |
throw new IllegalArgumentException(name() + " not an automatic module"); |
25874 | 145 |
} |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
146 |
return new NormalModule(this, requires); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
147 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
148 |
|
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
149 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
150 |
* Tests if the package of the given name is exported. |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
151 |
*/ |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
152 |
public boolean isExported(String pn) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
153 |
return exports.containsKey(pn) && exports.get(pn).isEmpty(); |
25874 | 154 |
} |
155 |
||
36526 | 156 |
/** |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
157 |
* Tests if the package of the given name is exported to the target |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
158 |
* in a qualified fashion. |
36526 | 159 |
*/ |
160 |
public boolean isExported(String pn, String target) { |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
161 |
return isExported(pn) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
162 |
|| exports.containsKey(pn) && exports.get(pn).contains(target); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
163 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
164 |
|
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
165 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
166 |
* Tests if the package of the given name is open. |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
167 |
*/ |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
168 |
public boolean isOpen(String pn) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
169 |
return opens.containsKey(pn) && opens.get(pn).isEmpty(); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
170 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
171 |
|
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
172 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
173 |
* Tests if the package of the given name is open to the target |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
174 |
* in a qualified fashion. |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
175 |
*/ |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
176 |
public boolean isOpen(String pn, String target) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
177 |
return isOpen(pn) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
178 |
|| opens.containsKey(pn) && opens.get(pn).contains(target); |
25874 | 179 |
} |
180 |
||
181 |
@Override |
|
182 |
public String toString() { |
|
183 |
return name(); |
|
184 |
} |
|
185 |
||
186 |
public final static class Builder { |
|
36526 | 187 |
final String name; |
38524 | 188 |
final ModuleDescriptor descriptor; |
189 |
final boolean isSystem; |
|
36526 | 190 |
ClassFileReader reader; |
191 |
URI location; |
|
25874 | 192 |
|
38524 | 193 |
public Builder(ModuleDescriptor md) { |
194 |
this(md, false); |
|
25874 | 195 |
} |
196 |
||
38524 | 197 |
public Builder(ModuleDescriptor md, boolean isSystem) { |
198 |
this.name = md.name(); |
|
199 |
this.descriptor = md; |
|
200 |
this.isSystem = isSystem; |
|
36526 | 201 |
} |
202 |
||
203 |
public Builder location(URI location) { |
|
204 |
this.location = location; |
|
205 |
return this; |
|
206 |
} |
|
207 |
||
208 |
public Builder classes(ClassFileReader reader) { |
|
25874 | 209 |
this.reader = reader; |
210 |
return this; |
|
211 |
} |
|
27579 | 212 |
|
25874 | 213 |
public Module build() { |
38524 | 214 |
if (descriptor.isAutomatic() && isSystem) { |
36526 | 215 |
throw new InternalError("JDK module: " + name + " can't be automatic module"); |
216 |
} |
|
217 |
||
38524 | 218 |
Map<String, Set<String>> exports = new HashMap<>(); |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
219 |
Map<String, Set<String>> opens = new HashMap<>(); |
38524 | 220 |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
221 |
if (descriptor.isAutomatic()) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
222 |
// ModuleDescriptor::exports and opens returns an empty set |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
223 |
descriptor.packages().forEach(pn -> exports.put(pn, Collections.emptySet())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
224 |
descriptor.packages().forEach(pn -> opens.put(pn, Collections.emptySet())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
225 |
} else { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
226 |
descriptor.exports().stream() |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
227 |
.forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>()) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
228 |
.addAll(exp.targets())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
229 |
descriptor.opens().stream() |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
230 |
.forEach(exp -> opens.computeIfAbsent(exp.source(), _k -> new HashSet<>()) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
231 |
.addAll(exp.targets())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
232 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
233 |
return new Module(name, location, descriptor, exports, opens, isSystem, reader); |
36526 | 234 |
} |
235 |
} |
|
236 |
||
237 |
private static class UnnamedModule extends Module { |
|
238 |
private UnnamedModule() { |
|
52650
c16b6cc93272
8213909: jdeps --print-module-deps should report missing dependences
mchung
parents:
47216
diff
changeset
|
239 |
super("unnamed", null, false); |
36526 | 240 |
} |
241 |
||
242 |
@Override |
|
243 |
public String name() { |
|
244 |
return "unnamed"; |
|
245 |
} |
|
246 |
||
247 |
@Override |
|
248 |
public boolean isExported(String pn) { |
|
249 |
return true; |
|
250 |
} |
|
251 |
} |
|
252 |
||
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
253 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
254 |
* A normal module has a module-info.class |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
255 |
*/ |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
256 |
private static class NormalModule extends Module { |
38524 | 257 |
private final ModuleDescriptor md; |
36526 | 258 |
|
259 |
/** |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
260 |
* Converts the given automatic module to a normal module. |
36526 | 261 |
* |
262 |
* Replace this module's dependences with the given requires and also |
|
263 |
* declare service providers, if specified in META-INF/services configuration file |
|
264 |
*/ |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
265 |
private NormalModule(Module m, Map<String, Boolean> requires) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
266 |
super(m.name(), m.location, m.descriptor, m.exports, m.opens, m.isSystem, m.reader()); |
38524 | 267 |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
268 |
ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(m.name()); |
38524 | 269 |
requires.keySet().forEach(mn -> { |
270 |
if (requires.get(mn).equals(Boolean.TRUE)) { |
|
42407
f3702cff2933
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41998
diff
changeset
|
271 |
builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn); |
38524 | 272 |
} else { |
273 |
builder.requires(mn); |
|
274 |
} |
|
275 |
}); |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
276 |
// exports all packages |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
277 |
m.descriptor.packages().forEach(builder::exports); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
278 |
m.descriptor.uses().forEach(builder::uses); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
279 |
m.descriptor.provides().forEach(builder::provides); |
38524 | 280 |
this.md = builder.build(); |
36526 | 281 |
} |
282 |
||
283 |
@Override |
|
38524 | 284 |
public ModuleDescriptor descriptor() { |
285 |
return md; |
|
25874 | 286 |
} |
287 |
} |
|
288 |
} |