8236842: Surprising 'multiple elements' behaviour from getTypeElement when cross-compiling with --release
Reviewed-by: vromero
This commit is contained in:
parent
64feeab70a
commit
d05df7c17a
@ -147,7 +147,7 @@
|
||||
* <p> Otherwise, resolution succeeds, and the result of resolution is the
|
||||
* 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
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* Returns a package given its fully qualified name if the package is unique in the environment.
|
||||
* If running with modules, all modules in the modules graph are searched for matching packages.
|
||||
* Returns a package given its fully qualified name if the package is uniquely
|
||||
* determinable in the environment.
|
||||
*
|
||||
* @param name fully qualified package name, or an empty string for an unnamed package
|
||||
* @return the specified package, or {@code null} if it cannot be uniquely found
|
||||
* If running with modules, packages of the given name are searched in a
|
||||
* 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);
|
||||
|
||||
@ -119,12 +138,29 @@ public interface Elements {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a type element given its canonical name if the type element is unique in the environment.
|
||||
* If running with modules, all modules in the modules graph are searched for matching
|
||||
* type elements.
|
||||
* Returns a type element given its canonical name if the type element is uniquely
|
||||
* determinable in the environment.
|
||||
*
|
||||
* @param name the canonical name
|
||||
* @return the named type element, or {@code null} if it cannot be uniquely found
|
||||
* If running with modules, type elements of the given name are
|
||||
* 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);
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
package com.sun.tools.javac.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -198,43 +199,48 @@ public class JavacElements implements Elements {
|
||||
|
||||
return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> {
|
||||
Set<S> found = new LinkedHashSet<>();
|
||||
Set<ModuleSymbol> allModules = new HashSet<>(modules.allModules());
|
||||
|
||||
for (ModuleSymbol msym : modules.allModules()) {
|
||||
S sym = nameToSymbol(msym, nameStr, clazz);
|
||||
allModules.removeAll(modules.getRootModules());
|
||||
|
||||
if (sym == null)
|
||||
continue;
|
||||
for (Set<ModuleSymbol> modules : Arrays.asList(modules.getRootModules(), allModules)) {
|
||||
for (ModuleSymbol msym : modules) {
|
||||
S sym = nameToSymbol(msym, nameStr, clazz);
|
||||
|
||||
if (clazz == ClassSymbol.class) {
|
||||
// Always include classes
|
||||
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) {
|
||||
if (sym == null)
|
||||
continue;
|
||||
|
||||
if (clazz == ClassSymbol.class) {
|
||||
// Always include classes
|
||||
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) {
|
||||
return Optional.of(found.iterator().next());
|
||||
} else if (found.size() > 1) {
|
||||
//more than one element found, produce a note:
|
||||
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
||||
String moduleNames = found.stream()
|
||||
.map(s -> s.packge().modle)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.joining(", "));
|
||||
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
|
||||
if (found.size() == 1) {
|
||||
return Optional.of(found.iterator().next());
|
||||
} else if (found.size() > 1) {
|
||||
//more than one element found, produce a note:
|
||||
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
|
||||
String moduleNames = found.stream()
|
||||
.map(s -> s.packge().modle)
|
||||
.map(m -> m.toString())
|
||||
.collect(Collectors.joining(", "));
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @library /tools/lib
|
||||
* @modules
|
||||
@ -46,6 +46,7 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@ -53,7 +54,6 @@ import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.processing.AbstractProcessor;
|
||||
@ -80,11 +80,8 @@ import javax.tools.Diagnostic.Kind;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaCompiler.CompilationTask;
|
||||
import javax.tools.JavaFileManager;
|
||||
import javax.tools.JavaFileManager.Location;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
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
|
||||
public void testUnboundLookup(Path base) throws Exception {
|
||||
Path src = base.resolve("src");
|
||||
@ -1333,7 +1764,7 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||
"package nested.pack; public class Impl { }");
|
||||
|
||||
//from source:
|
||||
String log = new JavacTask(tb)
|
||||
new JavacTask(tb)
|
||||
.options("--module-source-path", moduleSrc.toString(),
|
||||
"--source-path", src.toString(),
|
||||
"-processorpath", System.getProperty("test.class.path"),
|
||||
@ -1345,20 +1776,6 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||
.writeAll()
|
||||
.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)
|
||||
.options("--source-path", src.toString())
|
||||
.outdir(cpClasses)
|
||||
@ -1373,7 +1790,8 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||
"--add-modules", "m1x,m2x",
|
||||
"-processorpath", System.getProperty("test.class.path"),
|
||||
"-processor", UnboundLookup.class.getName(),
|
||||
"-proc:only")
|
||||
"-proc:only",
|
||||
"-Aunnamedmodule")
|
||||
.classes("java.lang.Object")
|
||||
.run()
|
||||
.writeAll();
|
||||
@ -1405,6 +1823,7 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||
}
|
||||
|
||||
@SupportedAnnotationTypes("*")
|
||||
@SupportedOptions("unnamedmodule")
|
||||
public static final class UnboundLookup extends AbstractProcessor {
|
||||
|
||||
@Override
|
||||
@ -1422,8 +1841,8 @@ public class AnnotationProcessing extends ModuleTestBase {
|
||||
assertTypeElementNotFound("impl.conflict.module.Impl");
|
||||
assertTypeElementNotFound("impl.conflict.module.Impl"); //check that the warning/note is produced only once
|
||||
assertPackageElementNotFound("impl.conflict.module");
|
||||
assertTypeElementNotFound("impl.conflict.src.Impl");
|
||||
assertPackageElementNotFound("impl.conflict.src");
|
||||
assertTypeElementExists("impl.conflict.src.Impl", processingEnv.getOptions().containsKey("unnamedmodule") ? "" : "m1x");
|
||||
assertPackageElementExists("impl.conflict.src", processingEnv.getOptions().containsKey("unnamedmodule") ? "" : "m1x");
|
||||
assertTypeElementNotFound("impl.conflict.clazz.pkg");
|
||||
assertPackageElementNotFound("unique"); //do not return packages without members in module mode
|
||||
assertTypeElementNotFound("nested"); //cannot distinguish between m1x and m2x
|
||||
|
Loading…
Reference in New Issue
Block a user