Skip to content

Commit d05df7c

Browse files
committed
8236842: Surprising 'multiple elements' behaviour from getTypeElement when cross-compiling with --release
Reviewed-by: vromero
1 parent 64feeab commit d05df7c

File tree

4 files changed

+524
-63
lines changed

4 files changed

+524
-63
lines changed

src/java.base/share/classes/java/lang/module/package-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@
147147
* <p> Otherwise, resolution succeeds, and the result of resolution is the
148148
* readability graph.
149149
*
150-
* <h3> Root modules </h3>
150+
* <h3><a id="root-modules"></a> Root modules </h3>
151151
*
152152
* <p> The set of root modules at compile-time is usually the set of modules
153153
* being compiled. At run-time, the set of root modules is usually the

src/java.compiler/share/classes/javax/lang/model/util/Elements.java

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,30 @@
5151
public interface Elements {
5252

5353
/**
54-
* Returns a package given its fully qualified name if the package is unique in the environment.
55-
* If running with modules, all modules in the modules graph are searched for matching packages.
56-
*
57-
* @param name fully qualified package name, or an empty string for an unnamed package
58-
* @return the specified package, or {@code null} if it cannot be uniquely found
54+
* Returns a package given its fully qualified name if the package is uniquely
55+
* determinable in the environment.
56+
*
57+
* If running with modules, packages of the given name are searched in a
58+
* two-stage process:
59+
* <ul>
60+
* <li>find non-empty packages with the given name returned by
61+
* {@link #getPackageElement(ModuleElement, CharSequence)},
62+
* where the provided ModuleSymbol is any
63+
* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,
64+
* </li>
65+
* <li>if the above yields an empty list, search
66+
* {@link #getAllModuleElements() all modules} for observable
67+
* packages with the given name
68+
* </li>
69+
* </ul>
70+
*
71+
* If this process leads to a list with a single element,
72+
* the single element is returned, otherwise null is returned.
73+
*
74+
* @param name fully qualified package name,
75+
* or an empty string for an unnamed package
76+
* @return the specified package,
77+
* or {@code null} if no package can be uniquely determined.
5978
*/
6079
PackageElement getPackageElement(CharSequence name);
6180

@@ -119,12 +138,29 @@ default Set<? extends PackageElement> getAllPackageElements(CharSequence name) {
119138
}
120139

121140
/**
122-
* Returns a type element given its canonical name if the type element is unique in the environment.
123-
* If running with modules, all modules in the modules graph are searched for matching
124-
* type elements.
125-
*
126-
* @param name the canonical name
127-
* @return the named type element, or {@code null} if it cannot be uniquely found
141+
* Returns a type element given its canonical name if the type element is uniquely
142+
* determinable in the environment.
143+
*
144+
* If running with modules, type elements of the given name are
145+
* searched in a two-stage process:
146+
* <ul>
147+
* <li>find type elements with the given name returned by
148+
* {@link #getTypeElement(ModuleElement, CharSequence)},
149+
* where the provided ModuleSymbol is any
150+
* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,
151+
* </li>
152+
* <li>if the above yields an empty list, search
153+
* {@link #getAllModuleElements() all modules} for observable
154+
* type elements with the given name
155+
* </li>
156+
* </ul>
157+
*
158+
* If this process leads to a list with a single element,
159+
* the single element is returned, otherwise null is returned.
160+
*
161+
* @param name the canonical name
162+
* @return the named type element,
163+
* or {@code null} if no type element can be uniquely determined.
128164
*/
129165
TypeElement getTypeElement(CharSequence name);
130166

src/jdk.compiler/share/classes/com/sun/tools/javac/model/JavacElements.java

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
package com.sun.tools.javac.model;
2727

28+
import java.util.Arrays;
2829
import java.util.Collections;
2930
import java.util.HashMap;
3031
import java.util.HashSet;
@@ -198,43 +199,48 @@ private <S extends Symbol> S unboundNameToSymbol(String methodName,
198199

199200
return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> {
200201
Set<S> found = new LinkedHashSet<>();
202+
Set<ModuleSymbol> allModules = new HashSet<>(modules.allModules());
201203

202-
for (ModuleSymbol msym : modules.allModules()) {
203-
S sym = nameToSymbol(msym, nameStr, clazz);
204+
allModules.removeAll(modules.getRootModules());
204205

205-
if (sym == null)
206-
continue;
206+
for (Set<ModuleSymbol> modules : Arrays.asList(modules.getRootModules(), allModules)) {
207+
for (ModuleSymbol msym : modules) {
208+
S sym = nameToSymbol(msym, nameStr, clazz);
209+
210+
if (sym == null)
211+
continue;
207212

208-
if (clazz == ClassSymbol.class) {
209-
// Always include classes
210-
found.add(sym);
211-
} else if (clazz == PackageSymbol.class) {
212-
// In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages.
213-
// For example, if a module contains classes or package info in package p.q.r, it will also appear
214-
// to have additional packages p.q and p, even though these packages have no content other
215-
// than the subpackage. We don't want those empty packages showing up in searches for p or p.q.
216-
if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) {
213+
if (clazz == ClassSymbol.class) {
214+
// Always include classes
217215
found.add(sym);
216+
} else if (clazz == PackageSymbol.class) {
217+
// In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages.
218+
// For example, if a module contains classes or package info in package p.q.r, it will also appear
219+
// to have additional packages p.q and p, even though these packages have no content other
220+
// than the subpackage. We don't want those empty packages showing up in searches for p or p.q.
221+
if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) {
222+
found.add(sym);
223+
}
218224
}
219225
}
220-
}
221226

222-
if (found.size() == 1) {
223-
return Optional.of(found.iterator().next());
224-
} else if (found.size() > 1) {
225-
//more than one element found, produce a note:
226-
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
227-
String moduleNames = found.stream()
228-
.map(s -> s.packge().modle)
229-
.map(m -> m.toString())
230-
.collect(Collectors.joining(", "));
231-
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
227+
if (found.size() == 1) {
228+
return Optional.of(found.iterator().next());
229+
} else if (found.size() > 1) {
230+
//more than one element found, produce a note:
231+
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
232+
String moduleNames = found.stream()
233+
.map(s -> s.packge().modle)
234+
.map(m -> m.toString())
235+
.collect(Collectors.joining(", "));
236+
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
237+
}
238+
return Optional.empty();
239+
} else {
240+
//not found, try another option
232241
}
233-
return Optional.empty();
234-
} else {
235-
//not found:
236-
return Optional.empty();
237242
}
243+
return Optional.empty();
238244
}).orElse(null);
239245
}
240246

0 commit comments

Comments
 (0)