mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8236842: Surprising 'multiple elements' behaviour from getTypeElement when cross-compiling with --release
Reviewed-by: vromero
This commit is contained in:
parent
64feeab70a
commit
d05df7c17a
4 changed files with 522 additions and 61 deletions
|
@ -147,7 +147,7 @@
|
||||||
* <p> Otherwise, resolution succeeds, and the result of resolution is the
|
* <p> Otherwise, resolution succeeds, and the result of resolution is the
|
||||||
* readability graph.
|
* readability graph.
|
||||||
*
|
*
|
||||||
* <h3> Root modules </h3>
|
* <h3><a id="root-modules"></a> Root modules </h3>
|
||||||
*
|
*
|
||||||
* <p> The set of root modules at compile-time is usually the set of modules
|
* <p> The set of root modules at compile-time is usually the set of modules
|
||||||
* being compiled. At run-time, the set of root modules is usually the
|
* being compiled. At run-time, the set of root modules is usually the
|
||||||
|
|
|
@ -51,11 +51,30 @@ import javax.lang.model.element.*;
|
||||||
public interface Elements {
|
public interface Elements {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a package given its fully qualified name if the package is unique in the environment.
|
* Returns a package given its fully qualified name if the package is uniquely
|
||||||
* If running with modules, all modules in the modules graph are searched for matching packages.
|
* determinable in the environment.
|
||||||
*
|
*
|
||||||
* @param name fully qualified package name, or an empty string for an unnamed package
|
* If running with modules, packages of the given name are searched in a
|
||||||
* @return the specified package, or {@code null} if it cannot be uniquely found
|
* two-stage process:
|
||||||
|
* <ul>
|
||||||
|
* <li>find non-empty packages with the given name returned by
|
||||||
|
* {@link #getPackageElement(ModuleElement, CharSequence)},
|
||||||
|
* where the provided ModuleSymbol is any
|
||||||
|
* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,
|
||||||
|
* </li>
|
||||||
|
* <li>if the above yields an empty list, search
|
||||||
|
* {@link #getAllModuleElements() all modules} for observable
|
||||||
|
* packages with the given name
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* If this process leads to a list with a single element,
|
||||||
|
* the single element is returned, otherwise null is returned.
|
||||||
|
*
|
||||||
|
* @param name fully qualified package name,
|
||||||
|
* or an empty string for an unnamed package
|
||||||
|
* @return the specified package,
|
||||||
|
* or {@code null} if no package can be uniquely determined.
|
||||||
*/
|
*/
|
||||||
PackageElement getPackageElement(CharSequence name);
|
PackageElement getPackageElement(CharSequence name);
|
||||||
|
|
||||||
|
@ -119,12 +138,29 @@ public interface Elements {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a type element given its canonical name if the type element is unique in the environment.
|
* Returns a type element given its canonical name if the type element is uniquely
|
||||||
* If running with modules, all modules in the modules graph are searched for matching
|
* determinable in the environment.
|
||||||
* type elements.
|
|
||||||
*
|
*
|
||||||
* @param name the canonical name
|
* If running with modules, type elements of the given name are
|
||||||
* @return the named type element, or {@code null} if it cannot be uniquely found
|
* searched in a two-stage process:
|
||||||
|
* <ul>
|
||||||
|
* <li>find type elements with the given name returned by
|
||||||
|
* {@link #getTypeElement(ModuleElement, CharSequence)},
|
||||||
|
* where the provided ModuleSymbol is any
|
||||||
|
* <a href="../../../../../java.base/java/lang/module/package-summary.html#root-modules">root module</a>,
|
||||||
|
* </li>
|
||||||
|
* <li>if the above yields an empty list, search
|
||||||
|
* {@link #getAllModuleElements() all modules} for observable
|
||||||
|
* type elements with the given name
|
||||||
|
* </li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* If this process leads to a list with a single element,
|
||||||
|
* the single element is returned, otherwise null is returned.
|
||||||
|
*
|
||||||
|
* @param name the canonical name
|
||||||
|
* @return the named type element,
|
||||||
|
* or {@code null} if no type element can be uniquely determined.
|
||||||
*/
|
*/
|
||||||
TypeElement getTypeElement(CharSequence name);
|
TypeElement getTypeElement(CharSequence name);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
package com.sun.tools.javac.model;
|
package com.sun.tools.javac.model;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -198,43 +199,48 @@ public class JavacElements implements Elements {
|
||||||
|
|
||||||
return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> {
|
return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> {
|
||||||
Set<S> found = new LinkedHashSet<>();
|
Set<S> found = new LinkedHashSet<>();
|
||||||
|
Set<ModuleSymbol> allModules = new HashSet<>(modules.allModules());
|
||||||
|
|
||||||
for (ModuleSymbol msym : modules.allModules()) {
|
allModules.removeAll(modules.getRootModules());
|
||||||
S sym = nameToSymbol(msym, nameStr, clazz);
|
|
||||||
|
|
||||||
if (sym == null)
|
for (Set<ModuleSymbol> modules : Arrays.asList(modules.getRootModules(), allModules)) {
|
||||||
continue;
|
for (ModuleSymbol msym : modules) {
|
||||||
|
S sym = nameToSymbol(msym, nameStr, clazz);
|
||||||
|
|
||||||
if (clazz == ClassSymbol.class) {
|
if (sym == null)
|
||||||
// Always include classes
|
continue;
|
||||||
found.add(sym);
|
|
||||||
} else if (clazz == PackageSymbol.class) {
|
if (clazz == ClassSymbol.class) {
|
||||||
// In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages.
|
// Always include classes
|
||||||
// For example, if a module contains classes or package info in package p.q.r, it will also appear
|
|
||||||
// to have additional packages p.q and p, even though these packages have no content other
|
|
||||||
// than the subpackage. We don't want those empty packages showing up in searches for p or p.q.
|
|
||||||
if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) {
|
|
||||||
found.add(sym);
|
found.add(sym);
|
||||||
|
} else if (clazz == PackageSymbol.class) {
|
||||||
|
// In module mode, ignore the "spurious" empty packages that "enclose" module-specific packages.
|
||||||
|
// For example, if a module contains classes or package info in package p.q.r, it will also appear
|
||||||
|
// to have additional packages p.q and p, even though these packages have no content other
|
||||||
|
// than the subpackage. We don't want those empty packages showing up in searches for p or p.q.
|
||||||
|
if (!sym.members().isEmpty() || ((PackageSymbol) sym).package_info != null) {
|
||||||
|
found.add(sym);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (found.size() == 1) {
|
if (found.size() == 1) {
|
||||||
return Optional.of(found.iterator().next());
|
return Optional.of(found.iterator().next());
|
||||||
} else if (found.size() > 1) {
|
} else if (found.size() > 1) {
|
||||||
//more than one element found, produce a note:
|
//more than one element found, produce a note:
|
||||||
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
||||||
String moduleNames = found.stream()
|
String moduleNames = found.stream()
|
||||||
.map(s -> s.packge().modle)
|
.map(s -> s.packge().modle)
|
||||||
.map(m -> m.toString())
|
.map(m -> m.toString())
|
||||||
.collect(Collectors.joining(", "));
|
.collect(Collectors.joining(", "));
|
||||||
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
|
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
//not found, try another option
|
||||||
}
|
}
|
||||||
return Optional.empty();
|
|
||||||
} else {
|
|
||||||
//not found:
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
|
return Optional.empty();
|
||||||
}).orElse(null);
|
}).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
* @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119 8189747
|
* @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119 8189747 8236842
|
||||||
* @summary Verify that annotation processing works.
|
* @summary Verify that annotation processing works.
|
||||||
* @library /tools/lib
|
* @library /tools/lib
|
||||||
* @modules
|
* @modules
|
||||||
|
@ -46,6 +46,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -53,7 +54,6 @@ import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.processing.AbstractProcessor;
|
import javax.annotation.processing.AbstractProcessor;
|
||||||
|
@ -80,11 +80,8 @@ import javax.tools.Diagnostic.Kind;
|
||||||
import javax.tools.FileObject;
|
import javax.tools.FileObject;
|
||||||
import javax.tools.JavaCompiler;
|
import javax.tools.JavaCompiler;
|
||||||
import javax.tools.JavaCompiler.CompilationTask;
|
import javax.tools.JavaCompiler.CompilationTask;
|
||||||
import javax.tools.JavaFileManager;
|
|
||||||
import javax.tools.JavaFileManager.Location;
|
|
||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.StandardJavaFileManager;
|
import javax.tools.StandardJavaFileManager;
|
||||||
import javax.tools.StandardLocation;
|
|
||||||
import javax.tools.ToolProvider;
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
import toolbox.JavacTask;
|
import toolbox.JavacTask;
|
||||||
|
@ -1299,6 +1296,440 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUnboundLookupNew(Path base) throws Exception {
|
||||||
|
Path moduleSrc = base.resolve("module-src");
|
||||||
|
Path m1 = moduleSrc.resolve("m1x");
|
||||||
|
Path m2 = moduleSrc.resolve("m2x");
|
||||||
|
Path m3 = moduleSrc.resolve("m3x");
|
||||||
|
Path m4 = moduleSrc.resolve("m4x");
|
||||||
|
|
||||||
|
Path src = base.resolve("src");
|
||||||
|
|
||||||
|
Path classes = base.resolve("classes");
|
||||||
|
Path srcClasses = base.resolve("src-classes");
|
||||||
|
|
||||||
|
Files.createDirectories(classes);
|
||||||
|
Files.createDirectories(srcClasses);
|
||||||
|
Files.createDirectories(moduleSrc);
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports api; }",
|
||||||
|
"package test; public class Test { }",
|
||||||
|
"package api; public class API {}");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; }",
|
||||||
|
"package test; public class Test { }",
|
||||||
|
"package api.impl; public class Impl { }");
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString())
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(moduleSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test,+api",
|
||||||
|
"-XDrawDiagnostics")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList("- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: api found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: api found in module: m1x"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"-XDrawDiagnostics",
|
||||||
|
"-XDshould-stop.at=FLOW")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run(Task.Expect.FAIL)
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList(
|
||||||
|
"Test.java:1:1: compiler.err.package.in.other.module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"1 error");
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; requires m3x; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m3,
|
||||||
|
"module m3x { }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString())
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(moduleSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"-XDrawDiagnostics")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList(
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m2x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m2x"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; requires m3x; }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m3,
|
||||||
|
"module m3x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m4,
|
||||||
|
"module m4x { }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
{
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"-XDrawDiagnostics",
|
||||||
|
"-XDshould-stop.at=FLOW")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run(Task.Expect.FAIL)
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<Set<String>> expected = Arrays.asList(
|
||||||
|
variants("module-info.java:1:1: compiler.err.package.clash.from.requires: m2x, test, m1x, m3x"),
|
||||||
|
variants("- compiler.note.proc.messager: test.Test found in module: m1x"),
|
||||||
|
variants("- compiler.note.proc.messager: test found in module: m1x"),
|
||||||
|
variants("- compiler.note.proc.messager: test.Test found in module: m1x"),
|
||||||
|
variants("- compiler.note.proc.messager: test found in module: m1x"),
|
||||||
|
variants("1 error"));
|
||||||
|
|
||||||
|
assertErrorsWithVariants(expected, log);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=-test.Test",
|
||||||
|
"-AlookupPackage=-test",
|
||||||
|
"-XDrawDiagnostics",
|
||||||
|
"-XDshould-stop.at=FLOW")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2, m4))
|
||||||
|
.run(Task.Expect.FAIL)
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList(
|
||||||
|
"module-info.java:1:1: compiler.err.package.clash.from.requires: m2x, test, m1x, m3x",
|
||||||
|
"- compiler.note.multiple.elements: getTypeElement, test.Test, m1x, m4x",
|
||||||
|
"- compiler.note.multiple.elements: getPackageElement, test, m1x, m4x",
|
||||||
|
"1 error");
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(src,
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString())
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(moduleSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"--source-path", src.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"-XDrawDiagnostics")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList(
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(src,
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString())
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(moduleSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
|
"--source-path", src.toString(),
|
||||||
|
"--add-reads=m2x=ALL-UNNAMED",
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"-XDrawDiagnostics")
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(m2))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList(
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tb.cleanDirectory(classes);
|
||||||
|
tb.cleanDirectory(srcClasses);
|
||||||
|
tb.cleanDirectory(moduleSrc);
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m1,
|
||||||
|
"module m1x { exports test; }",
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(m2,
|
||||||
|
"module m2x { requires m1x; }");
|
||||||
|
|
||||||
|
tb.writeJavaFiles(src,
|
||||||
|
"package test; public class Test { }");
|
||||||
|
|
||||||
|
new JavacTask(tb)
|
||||||
|
.options("--module-source-path", moduleSrc.toString())
|
||||||
|
.outdir(classes)
|
||||||
|
.files(findJavaFiles(moduleSrc))
|
||||||
|
.run()
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> log = new JavacTask(tb)
|
||||||
|
.options("--module-path", classes.toString(),
|
||||||
|
"--source-path", src.toString(),
|
||||||
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
"-processor", UnboundLookupNew.class.getName(),
|
||||||
|
"-AlookupClass=+test.Test",
|
||||||
|
"-AlookupPackage=+test",
|
||||||
|
"--add-modules=m2x",
|
||||||
|
"-XDshould-stop.at=ATTR",
|
||||||
|
"-XDrawDiagnostics")
|
||||||
|
.outdir(srcClasses)
|
||||||
|
.files(findJavaFiles(src))
|
||||||
|
.run(Task.Expect.FAIL)
|
||||||
|
.writeAll()
|
||||||
|
.getOutputLines(OutputKind.DIRECT);
|
||||||
|
|
||||||
|
List<String> expected = Arrays.asList("Test.java:1:1: compiler.err.package.in.other.module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: unnamed module",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"- compiler.note.proc.messager: test.Test found in module: unnamed module",
|
||||||
|
"- compiler.note.proc.messager: test found in module: m1x",
|
||||||
|
"1 error"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!expected.equals(log)) {
|
||||||
|
throw new AssertionError("Expected output not found: " + log);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> variants(String... expected) {
|
||||||
|
return new HashSet<>(Arrays.asList(expected));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertErrorsWithVariants(List<Set<String>> expectedVariants, List<String> actual) {
|
||||||
|
assertEquals(expectedVariants.size(), actual.size());
|
||||||
|
Iterator<Set<String>> expIt = expectedVariants.iterator();
|
||||||
|
Iterator<String> actIt = actual.iterator();
|
||||||
|
|
||||||
|
while (expIt.hasNext() && actIt.hasNext()) {
|
||||||
|
Set<String> exp = expIt.next();
|
||||||
|
String act = actIt.next();
|
||||||
|
|
||||||
|
if (!exp.contains(act)) {
|
||||||
|
throw new AssertionError("Expected: " + exp + ", actual: " + act);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SupportedAnnotationTypes("*")
|
||||||
|
@SupportedOptions({"lookupClass", "lookupPackage"})
|
||||||
|
public static final class UnboundLookupNew extends AbstractProcessor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
|
||||||
|
performLookup("lookupClass", processingEnv.getElementUtils()::getTypeElement);
|
||||||
|
performLookup("lookupPackage", processingEnv.getElementUtils()::getPackageElement);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performLookup(String optionName, Function<String, Element> name2Element) {
|
||||||
|
String[] lookupList = processingEnv.getOptions().get(optionName).split(",");
|
||||||
|
for (String lookup : lookupList) {
|
||||||
|
boolean shouldExists = lookup.charAt(0) == '+';
|
||||||
|
String name = lookup.substring(1);
|
||||||
|
Element type = name2Element.apply(name);
|
||||||
|
|
||||||
|
if (shouldExists) {
|
||||||
|
if (type == null) {
|
||||||
|
throw new AssertionError("Did not find the expected type.");
|
||||||
|
} else {
|
||||||
|
processingEnv.getMessager().printMessage(Kind.NOTE, name + " found in module: " + processingEnv.getElementUtils().getModuleOf(type));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (type != null) {
|
||||||
|
throw new AssertionError("Found the unexpected type.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SourceVersion getSupportedSourceVersion() {
|
||||||
|
return SourceVersion.latest();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUnboundLookup(Path base) throws Exception {
|
public void testUnboundLookup(Path base) throws Exception {
|
||||||
Path src = base.resolve("src");
|
Path src = base.resolve("src");
|
||||||
|
@ -1333,7 +1764,7 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
"package nested.pack; public class Impl { }");
|
"package nested.pack; public class Impl { }");
|
||||||
|
|
||||||
//from source:
|
//from source:
|
||||||
String log = new JavacTask(tb)
|
new JavacTask(tb)
|
||||||
.options("--module-source-path", moduleSrc.toString(),
|
.options("--module-source-path", moduleSrc.toString(),
|
||||||
"--source-path", src.toString(),
|
"--source-path", src.toString(),
|
||||||
"-processorpath", System.getProperty("test.class.path"),
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
|
@ -1345,20 +1776,6 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
.writeAll()
|
.writeAll()
|
||||||
.getOutput(OutputKind.DIRECT);
|
.getOutput(OutputKind.DIRECT);
|
||||||
|
|
||||||
String moduleImplConflictString =
|
|
||||||
"- compiler.note.multiple.elements: getTypeElement, impl.conflict.module.Impl, m2x, m1x";
|
|
||||||
String srcConflictString =
|
|
||||||
"- compiler.note.multiple.elements: getTypeElement, impl.conflict.src.Impl, m1x, unnamed module";
|
|
||||||
|
|
||||||
if (!log.contains(moduleImplConflictString) ||
|
|
||||||
!log.contains(srcConflictString)) {
|
|
||||||
throw new AssertionError("Expected output not found: " + log);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log.split(Pattern.quote(moduleImplConflictString)).length > 2) {
|
|
||||||
throw new AssertionError("Too many warnings in: " + log);
|
|
||||||
}
|
|
||||||
|
|
||||||
new JavacTask(tb)
|
new JavacTask(tb)
|
||||||
.options("--source-path", src.toString())
|
.options("--source-path", src.toString())
|
||||||
.outdir(cpClasses)
|
.outdir(cpClasses)
|
||||||
|
@ -1373,7 +1790,8 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
"--add-modules", "m1x,m2x",
|
"--add-modules", "m1x,m2x",
|
||||||
"-processorpath", System.getProperty("test.class.path"),
|
"-processorpath", System.getProperty("test.class.path"),
|
||||||
"-processor", UnboundLookup.class.getName(),
|
"-processor", UnboundLookup.class.getName(),
|
||||||
"-proc:only")
|
"-proc:only",
|
||||||
|
"-Aunnamedmodule")
|
||||||
.classes("java.lang.Object")
|
.classes("java.lang.Object")
|
||||||
.run()
|
.run()
|
||||||
.writeAll();
|
.writeAll();
|
||||||
|
@ -1405,6 +1823,7 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SupportedAnnotationTypes("*")
|
@SupportedAnnotationTypes("*")
|
||||||
|
@SupportedOptions("unnamedmodule")
|
||||||
public static final class UnboundLookup extends AbstractProcessor {
|
public static final class UnboundLookup extends AbstractProcessor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1422,8 +1841,8 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||||
assertTypeElementNotFound("impl.conflict.module.Impl");
|
assertTypeElementNotFound("impl.conflict.module.Impl");
|
||||||
assertTypeElementNotFound("impl.conflict.module.Impl"); //check that the warning/note is produced only once
|
assertTypeElementNotFound("impl.conflict.module.Impl"); //check that the warning/note is produced only once
|
||||||
assertPackageElementNotFound("impl.conflict.module");
|
assertPackageElementNotFound("impl.conflict.module");
|
||||||
assertTypeElementNotFound("impl.conflict.src.Impl");
|
assertTypeElementExists("impl.conflict.src.Impl", processingEnv.getOptions().containsKey("unnamedmodule") ? "" : "m1x");
|
||||||
assertPackageElementNotFound("impl.conflict.src");
|
assertPackageElementExists("impl.conflict.src", processingEnv.getOptions().containsKey("unnamedmodule") ? "" : "m1x");
|
||||||
assertTypeElementNotFound("impl.conflict.clazz.pkg");
|
assertTypeElementNotFound("impl.conflict.clazz.pkg");
|
||||||
assertPackageElementNotFound("unique"); //do not return packages without members in module mode
|
assertPackageElementNotFound("unique"); //do not return packages without members in module mode
|
||||||
assertTypeElementNotFound("nested"); //cannot distinguish between m1x and m2x
|
assertTypeElementNotFound("nested"); //cannot distinguish between m1x and m2x
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue