author | serb |
Sat, 09 Jun 2018 13:33:35 -0700 | |
changeset 50647 | a98ff7c2103d |
parent 47216 | 71c04702a3d5 |
child 52650 | c16b6cc93272 |
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) { |
61 |
super(name); |
|
62 |
this.descriptor = null; |
|
63 |
this.location = null; |
|
64 |
this.exports = Collections.emptyMap(); |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
65 |
this.opens = Collections.emptyMap(); |
38524 | 66 |
this.isSystem = true; |
67 |
} |
|
36526 | 68 |
|
69 |
private Module(String name, |
|
70 |
URI location, |
|
71 |
ModuleDescriptor descriptor, |
|
25874 | 72 |
Map<String, Set<String>> exports, |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
73 |
Map<String, Set<String>> opens, |
38524 | 74 |
boolean isSystem, |
36526 | 75 |
ClassFileReader reader) { |
76 |
super(name, location, reader); |
|
77 |
this.descriptor = descriptor; |
|
78 |
this.location = location; |
|
25874 | 79 |
this.exports = Collections.unmodifiableMap(exports); |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
80 |
this.opens = Collections.unmodifiableMap(opens); |
38524 | 81 |
this.isSystem = isSystem; |
36526 | 82 |
} |
83 |
||
84 |
/** |
|
85 |
* Returns module name |
|
86 |
*/ |
|
87 |
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
|
88 |
return descriptor != null ? descriptor.name() : getName(); |
36526 | 89 |
} |
90 |
||
91 |
public boolean isNamed() { |
|
92 |
return true; |
|
25874 | 93 |
} |
94 |
||
36526 | 95 |
public boolean isAutomatic() { |
96 |
return descriptor.isAutomatic(); |
|
97 |
} |
|
98 |
||
99 |
public Module getModule() { |
|
100 |
return this; |
|
101 |
} |
|
102 |
||
103 |
public ModuleDescriptor descriptor() { |
|
104 |
return descriptor; |
|
105 |
} |
|
106 |
||
38524 | 107 |
public URI location() { |
108 |
return location; |
|
25874 | 109 |
} |
110 |
||
38524 | 111 |
public boolean isJDK() { |
112 |
String mn = name(); |
|
113 |
return isSystem && |
|
114 |
(mn.startsWith("java.") || mn.startsWith("jdk.") || mn.startsWith("javafx.")); |
|
115 |
} |
|
116 |
||
117 |
public boolean isSystem() { |
|
118 |
return isSystem; |
|
25874 | 119 |
} |
120 |
||
121 |
public Map<String, Set<String>> exports() { |
|
122 |
return exports; |
|
123 |
} |
|
124 |
||
125 |
public Set<String> packages() { |
|
38524 | 126 |
return descriptor.packages(); |
25874 | 127 |
} |
128 |
||
41860
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
129 |
public boolean isJDKUnsupported() { |
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
130 |
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
|
131 |
} |
906670ff49c7
8167057: jdeps option to list modules and internal APIs for @modules for test dev
mchung
parents:
38524
diff
changeset
|
132 |
|
25874 | 133 |
/** |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
134 |
* Converts this module to a normal module with the given dependences |
36526 | 135 |
* |
136 |
* @throws IllegalArgumentException if this module is not an automatic module |
|
25874 | 137 |
*/ |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
138 |
public Module toNormalModule(Map<String, Boolean> requires) { |
36526 | 139 |
if (!isAutomatic()) { |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
140 |
throw new IllegalArgumentException(name() + " not an automatic module"); |
25874 | 141 |
} |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
142 |
return new NormalModule(this, requires); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
143 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
144 |
|
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
145 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
146 |
* Tests if the package of the given name is exported. |
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 |
public boolean isExported(String pn) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
149 |
return exports.containsKey(pn) && exports.get(pn).isEmpty(); |
25874 | 150 |
} |
151 |
||
36526 | 152 |
/** |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
153 |
* 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
|
154 |
* in a qualified fashion. |
36526 | 155 |
*/ |
156 |
public boolean isExported(String pn, String target) { |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
157 |
return isExported(pn) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
158 |
|| exports.containsKey(pn) && exports.get(pn).contains(target); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
159 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
160 |
|
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
161 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
162 |
* Tests if the package of the given name is open. |
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 |
public boolean isOpen(String pn) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
165 |
return opens.containsKey(pn) && opens.get(pn).isEmpty(); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
166 |
} |
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 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
169 |
* 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
|
170 |
* in a qualified fashion. |
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 |
public boolean isOpen(String pn, String target) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
173 |
return isOpen(pn) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
174 |
|| opens.containsKey(pn) && opens.get(pn).contains(target); |
25874 | 175 |
} |
176 |
||
177 |
@Override |
|
178 |
public String toString() { |
|
179 |
return name(); |
|
180 |
} |
|
181 |
||
182 |
public final static class Builder { |
|
36526 | 183 |
final String name; |
38524 | 184 |
final ModuleDescriptor descriptor; |
185 |
final boolean isSystem; |
|
36526 | 186 |
ClassFileReader reader; |
187 |
URI location; |
|
25874 | 188 |
|
38524 | 189 |
public Builder(ModuleDescriptor md) { |
190 |
this(md, false); |
|
25874 | 191 |
} |
192 |
||
38524 | 193 |
public Builder(ModuleDescriptor md, boolean isSystem) { |
194 |
this.name = md.name(); |
|
195 |
this.descriptor = md; |
|
196 |
this.isSystem = isSystem; |
|
36526 | 197 |
} |
198 |
||
199 |
public Builder location(URI location) { |
|
200 |
this.location = location; |
|
201 |
return this; |
|
202 |
} |
|
203 |
||
204 |
public Builder classes(ClassFileReader reader) { |
|
25874 | 205 |
this.reader = reader; |
206 |
return this; |
|
207 |
} |
|
27579 | 208 |
|
25874 | 209 |
public Module build() { |
38524 | 210 |
if (descriptor.isAutomatic() && isSystem) { |
36526 | 211 |
throw new InternalError("JDK module: " + name + " can't be automatic module"); |
212 |
} |
|
213 |
||
38524 | 214 |
Map<String, Set<String>> exports = new HashMap<>(); |
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
215 |
Map<String, Set<String>> opens = new HashMap<>(); |
38524 | 216 |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
217 |
if (descriptor.isAutomatic()) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
218 |
// ModuleDescriptor::exports and opens returns an empty set |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
219 |
descriptor.packages().forEach(pn -> exports.put(pn, Collections.emptySet())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
220 |
descriptor.packages().forEach(pn -> opens.put(pn, Collections.emptySet())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
221 |
} else { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
222 |
descriptor.exports().stream() |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
223 |
.forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>()) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
224 |
.addAll(exp.targets())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
225 |
descriptor.opens().stream() |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
226 |
.forEach(exp -> opens.computeIfAbsent(exp.source(), _k -> new HashSet<>()) |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
227 |
.addAll(exp.targets())); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
228 |
} |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
229 |
return new Module(name, location, descriptor, exports, opens, isSystem, reader); |
36526 | 230 |
} |
231 |
} |
|
232 |
||
233 |
private static class UnnamedModule extends Module { |
|
234 |
private UnnamedModule() { |
|
235 |
super("unnamed", null, null, |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
236 |
Collections.emptyMap(), Collections.emptyMap(), |
36526 | 237 |
false, null); |
238 |
} |
|
239 |
||
240 |
@Override |
|
241 |
public String name() { |
|
242 |
return "unnamed"; |
|
243 |
} |
|
244 |
||
245 |
@Override |
|
246 |
public boolean isNamed() { |
|
247 |
return false; |
|
248 |
} |
|
249 |
||
250 |
@Override |
|
251 |
public boolean isAutomatic() { |
|
252 |
return false; |
|
253 |
} |
|
254 |
||
255 |
@Override |
|
256 |
public boolean isExported(String pn) { |
|
257 |
return true; |
|
258 |
} |
|
259 |
} |
|
260 |
||
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
261 |
/** |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
262 |
* A normal module has a module-info.class |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
263 |
*/ |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
264 |
private static class NormalModule extends Module { |
38524 | 265 |
private final ModuleDescriptor md; |
36526 | 266 |
|
267 |
/** |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
268 |
* Converts the given automatic module to a normal module. |
36526 | 269 |
* |
270 |
* Replace this module's dependences with the given requires and also |
|
271 |
* declare service providers, if specified in META-INF/services configuration file |
|
272 |
*/ |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
273 |
private NormalModule(Module m, Map<String, Boolean> requires) { |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
274 |
super(m.name(), m.location, m.descriptor, m.exports, m.opens, m.isSystem, m.reader()); |
38524 | 275 |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
276 |
ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(m.name()); |
38524 | 277 |
requires.keySet().forEach(mn -> { |
278 |
if (requires.get(mn).equals(Boolean.TRUE)) { |
|
42407
f3702cff2933
8169069: Module system implementation refresh (11/2016)
alanb
parents:
41998
diff
changeset
|
279 |
builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn); |
38524 | 280 |
} else { |
281 |
builder.requires(mn); |
|
282 |
} |
|
283 |
}); |
|
43767
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
284 |
// exports all packages |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
285 |
m.descriptor.packages().forEach(builder::exports); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
286 |
m.descriptor.uses().forEach(builder::uses); |
9cff98a149cb
8173393: Module system implementation refresh (2/2017)
alanb
parents:
42407
diff
changeset
|
287 |
m.descriptor.provides().forEach(builder::provides); |
38524 | 288 |
this.md = builder.build(); |
36526 | 289 |
} |
290 |
||
291 |
@Override |
|
38524 | 292 |
public ModuleDescriptor descriptor() { |
293 |
return md; |
|
25874 | 294 |
} |
295 |
} |
|
296 |
} |