From 66dfba7613aab76edfbfc4f2abb66b42223bb993 Mon Sep 17 00:00:00 2001 From: Vaclav Haisman Date: Tue, 28 Jul 2026 15:41:08 +0200 Subject: [PATCH] Replace QDox with JavaParser Parse module-info.java directly instead of registering its source directory with QDox. This avoids parsing referenced service implementations while collecting JPMS directives and supports current Java syntax. Fixes https://github.com/apache/maven-compiler-plugin/issues/314 --- plexus-java/pom.xml | 6 +- .../java/jpms/SourceModuleInfoParser.java | 111 +++++++++--------- plexus-java/src/main/java9/module-info.java | 2 +- .../java/jpms/LocationManagerIT.java | 8 +- .../java/jpms/LocationManagerTest.java | 46 ++++---- .../java/jpms/SourceModuleInfoParserTest.java | 16 +++ .../example/AlternativeServiceImpl.java | 8 ++ .../example/Nullable.java | 7 ++ .../example/Service.java | 7 ++ .../example/ServiceImpl.java | 8 ++ .../annotated-type-argument/module-info.java | 4 + 11 files changed, 137 insertions(+), 86 deletions(-) create mode 100644 plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java create mode 100644 plexus-java/src/test/test-data/annotated-type-argument/example/Nullable.java create mode 100644 plexus-java/src/test/test-data/annotated-type-argument/example/Service.java create mode 100644 plexus-java/src/test/test-data/annotated-type-argument/example/ServiceImpl.java create mode 100644 plexus-java/src/test/test-data/annotated-type-argument/module-info.java diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml index 4f85f59..6607cb4 100644 --- a/plexus-java/pom.xml +++ b/plexus-java/pom.xml @@ -18,9 +18,9 @@ 9.10.1 - com.thoughtworks.qdox - qdox - 2.2.0 + com.github.javaparser + javaparser-core + 3.28.2 javax.inject diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java index b484919..418ec9b 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java @@ -19,87 +19,88 @@ * under the License. */ -import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; -import com.thoughtworks.qdox.JavaProjectBuilder; -import com.thoughtworks.qdox.model.JavaClass; -import com.thoughtworks.qdox.model.JavaModule; -import com.thoughtworks.qdox.model.JavaModuleDescriptor; +import com.github.javaparser.StaticJavaParser; +import com.github.javaparser.ast.expr.Name; +import com.github.javaparser.ast.modules.ModuleDeclaration; +import com.github.javaparser.ast.modules.ModuleDirective; +import com.github.javaparser.ast.modules.ModuleExportsDirective; +import com.github.javaparser.ast.modules.ModuleProvidesDirective; +import com.github.javaparser.ast.modules.ModuleRequiresDirective; +import com.github.javaparser.ast.modules.ModuleUsesDirective; /** - * Extract information from module with QDox + * Extracts information from a source module descriptor. * * @author Robert Scholte * @since 1.0.0 */ class SourceModuleInfoParser { - public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePath(Path modulePath) - throws IOException { - File moduleDescriptor = modulePath.toFile(); + public JavaModuleDescriptor fromSourcePath(Path modulePath) throws IOException { + JavaModuleDescriptor.Builder builder; + if (Files.exists(modulePath)) { + ModuleDeclaration descriptor = StaticJavaParser.parse(modulePath) + .getModule() + .orElseThrow(() -> new IOException("Module declaration not found in " + modulePath)); - org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder builder; - if (moduleDescriptor.exists()) { - JavaModuleDescriptor descriptor = new JavaProjectBuilder() - .addSourceFolder(moduleDescriptor.getParentFile()) - .getDescriptor(); + builder = JavaModuleDescriptor.newModule(descriptor.getName().asString()); - builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newModule(descriptor.getName()); - - for (JavaModuleDescriptor.JavaRequires requires : descriptor.getRequires()) { - if (requires.isStatic() || requires.isTransitive()) { - Set - modifiers = new LinkedHashSet<>(2); - if (requires.isStatic()) { - modifiers.add( - org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier - .STATIC); - } - if (requires.isTransitive()) { - modifiers.add( - org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier - .TRANSITIVE); + for (ModuleDirective directive : descriptor.getDirectives()) { + if (directive instanceof ModuleRequiresDirective) { + addRequires(builder, (ModuleRequiresDirective) directive); + } else if (directive instanceof ModuleExportsDirective) { + addExports(builder, (ModuleExportsDirective) directive); + } else if (directive instanceof ModuleUsesDirective) { + ModuleUsesDirective uses = (ModuleUsesDirective) directive; + builder.uses(uses.getName().asString()); + } else if (directive instanceof ModuleProvidesDirective) { + ModuleProvidesDirective provides = (ModuleProvidesDirective) directive; + List providers = new ArrayList<>(provides.getWith().size()); + for (Name provider : provides.getWith()) { + providers.add(provider.asString()); } - builder.requires(modifiers, requires.getModule().getName()); - } else { - builder.requires(requires.getModule().getName()); + builder.provides(provides.getName().asString(), providers); } } + } else { + builder = JavaModuleDescriptor.newAutomaticModule(null); + } - for (JavaModuleDescriptor.JavaExports exports : descriptor.getExports()) { - if (exports.getTargets().isEmpty()) { - builder.exports(exports.getSource().getName()); - } else { - Set targets = new LinkedHashSet<>(); - for (JavaModule module : exports.getTargets()) { - targets.add(module.getName()); - } - builder.exports(exports.getSource().getName(), targets); - } - } + return builder.build(); + } - for (JavaModuleDescriptor.JavaUses uses : descriptor.getUses()) { - builder.uses(uses.getService().getName()); + private static void addRequires(JavaModuleDescriptor.Builder builder, ModuleRequiresDirective requires) { + if (requires.isStatic() || requires.isTransitive()) { + Set modifiers = new LinkedHashSet<>(2); + if (requires.isStatic()) { + modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC); } - - for (JavaModuleDescriptor.JavaProvides provides : descriptor.getProvides()) { - List providers = new ArrayList<>(provides.getProviders().size()); - for (JavaClass provider : provides.getProviders()) { - providers.add(provider.getName()); - } - - builder.provides(provides.getService().getName(), providers); + if (requires.isTransitive()) { + modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE); } + builder.requires(modifiers, requires.getName().asString()); } else { - builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newAutomaticModule(null); + builder.requires(requires.getName().asString()); } + } - return builder.build(); + private static void addExports(JavaModuleDescriptor.Builder builder, ModuleExportsDirective exports) { + if (exports.getModuleNames().isEmpty()) { + builder.exports(exports.getName().asString()); + } else { + Set targets = new LinkedHashSet<>(); + for (Name module : exports.getModuleNames()) { + targets.add(module.asString()); + } + builder.exports(exports.getName().asString(), targets); + } } } diff --git a/plexus-java/src/main/java9/module-info.java b/plexus-java/src/main/java9/module-info.java index c09093b..b9ce123 100644 --- a/plexus-java/src/main/java9/module-info.java +++ b/plexus-java/src/main/java9/module-info.java @@ -17,7 +17,7 @@ * under the License. */ module org.codehaus.plexus.languages.java { - requires com.thoughtworks.qdox; + requires com.github.javaparser.core; requires org.objectweb.asm; exports org.codehaus.plexus.languages.java.jpms; diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java index 0859fd8..2ae3392 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java @@ -49,7 +49,7 @@ class LocationManagerIT { private BinaryModuleInfoParser asmParser; @Mock - private SourceModuleInfoParser qdoxParser; + private SourceModuleInfoParser sourceParser; private LocationManager locationManager; @@ -57,7 +57,7 @@ class LocationManagerIT { @BeforeEach void onSetup() { - locationManager = new LocationManager(qdoxParser) { + locationManager = new LocationManager(sourceParser) { @Override ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) { return asmParser; @@ -70,7 +70,7 @@ void manifestWithoutReflectRequires() throws Exception { Path abc = Paths.get("src/test/test-data/manifest.without/out"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").requires("any").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); @@ -88,7 +88,7 @@ void emptyWithReflectRequires() throws Exception { Path abc = Paths.get("src/test/test-data/empty/out"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").requires("a.b.c").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java index d758a0c..0fe8f29 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java @@ -38,7 +38,7 @@ class LocationManagerTest { private BinaryModuleInfoParser asmParser; - private SourceModuleInfoParser qdoxParser; + private SourceModuleInfoParser sourceParser; private LocationManager locationManager; @@ -47,8 +47,8 @@ class LocationManagerTest { @BeforeEach void onSetup() { asmParser = mock(BinaryModuleInfoParser.class); - qdoxParser = mock(SourceModuleInfoParser.class); - locationManager = new LocationManager(qdoxParser) { + sourceParser = mock(SourceModuleInfoParser.class); + locationManager = new LocationManager(sourceParser) { @Override ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) { return asmParser; @@ -73,7 +73,7 @@ void withUnknownRequires() throws Exception { .requires("java.base") .requires("jdk.net") .build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofFiles(Collections.emptyList()) .setMainModuleDescriptor(mockModuleInfoJava.toFile()); @@ -92,7 +92,7 @@ void manifestWithReflectRequires() throws Exception { JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") .requires("auto.by.manifest") .build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); @@ -112,7 +112,7 @@ void dirDescriptorWithReflectRequires() throws Exception { JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") .requires("dir.descriptor") .build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); @@ -135,7 +135,7 @@ void jarWithAsmRequires() throws Exception { JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") .requires("org.objectweb.asm") .build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); @@ -157,7 +157,7 @@ void identicalModuleNames() throws Exception { Path pj2 = Paths.get("src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); @@ -187,7 +187,7 @@ void identicalAutomaticModuleNames() throws Exception { Path pj2 = Paths.get("src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); @@ -217,7 +217,7 @@ void mainJarModuleAndTestJarAutomatic() throws Exception { Path pj2 = Paths.get("src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT-tests.jar"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); @@ -258,7 +258,7 @@ void additionalModules() throws Exception { Path p = Paths.get("src/test/test-data/mock/jar0.jar"); JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").build(); - when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(p)) .setMainModuleDescriptor(mockModuleInfoJava) .setAdditionalModules(Collections.singletonList("plexus.java")); @@ -297,7 +297,7 @@ void noMatchingProviders() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true); - when(qdoxParser.fromSourcePath(abc)) + when(sourceParser.fromSourcePath(abc)) .thenReturn(JavaModuleDescriptor.newModule("abc").uses("device").build()); when(asmParser.getModuleDescriptor(def)) .thenReturn(JavaModuleDescriptor.newModule("def") @@ -318,7 +318,7 @@ void mainModuleDescriptorWithProviders() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true); - when(qdoxParser.fromSourcePath(abc)) + when(sourceParser.fromSourcePath(abc)) .thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build()); when(asmParser.getModuleDescriptor(def)) .thenReturn(JavaModuleDescriptor.newModule("def") @@ -338,7 +338,7 @@ void mainModuleDescriptorWithProvidersDontIncludeProviders() throws Exception { Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc); - when(qdoxParser.fromSourcePath(abc)) + when(sourceParser.fromSourcePath(abc)) .thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build()); when(asmParser.getModuleDescriptor(def)) .thenReturn(JavaModuleDescriptor.newModule("def") @@ -361,7 +361,7 @@ void transitiveProviders() throws Exception { .setMainModuleDescriptor(abc) .setIncludeAllProviders(true); - when(qdoxParser.fromSourcePath(abc)) + when(sourceParser.fromSourcePath(abc)) .thenReturn( JavaModuleDescriptor.newModule("abc").requires("ghi").build()); when(asmParser.getModuleDescriptor(def)) @@ -386,7 +386,7 @@ void dontIncludeProviders() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def, ghi).setMainModuleDescriptor(abc); - when(qdoxParser.fromSourcePath(abc)) + when(sourceParser.fromSourcePath(abc)) .thenReturn( JavaModuleDescriptor.newModule("abc").requires("ghi").build()); when(asmParser.getModuleDescriptor(def)) @@ -443,7 +443,7 @@ void reuseModuleDescriptor() throws Exception { @Test void parseModuleDescriptor() throws Exception { Path descriptorPath = Paths.get("src/test/test-data/src.dir/module-info.java"); - when(qdoxParser.fromSourcePath(descriptorPath)) + when(sourceParser.fromSourcePath(descriptorPath)) .thenReturn(JavaModuleDescriptor.newModule("a.b.c").build()); ResolvePathResult result = locationManager.parseModuleDescriptor(descriptorPath); @@ -467,7 +467,7 @@ void transitiveStatic() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("moduleB") .build()); @@ -495,7 +495,7 @@ void directStatic() throws Exception { ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA); // .setIncludeStatic( true ); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("moduleB") .requires(Collections.singleton(JavaModifier.STATIC), "moduleD") @@ -525,7 +525,7 @@ void duplicateModule() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("anonymous") .build()); @@ -555,7 +555,7 @@ void staticTransitive() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("moduleB") .build()); @@ -588,7 +588,7 @@ void includeDeeperRequiresStatic() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC) .setMainModuleDescriptor(moduleA) .setIncludeStatic(true); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("moduleB") .build()); @@ -615,7 +615,7 @@ void includeDeeperRequiresStaticTransitive() throws Exception { ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC, moduleD) .setMainModuleDescriptor(moduleA) .setIncludeStatic(true); - when(qdoxParser.fromSourcePath(moduleA)) + when(sourceParser.fromSourcePath(moduleA)) .thenReturn(JavaModuleDescriptor.newModule("moduleA") .requires("moduleB") .build()); diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java index c29e921..3f7f694 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java @@ -85,4 +85,20 @@ void test() throws Exception { assertArrayEquals( new String[] {"com.example.foo.Impl"}, provides.providers().toArray(new String[0])); } + + @Test + void doesNotParseReferencedSources() throws Exception { + JavaModuleDescriptor moduleDescriptor = + parser.fromSourcePath(Paths.get("src/test/test-data/annotated-type-argument/module-info.java")); + + assertEquals("annotated.type.argument", moduleDescriptor.name()); + assertArrayEquals( + new String[] {"example.Service"}, moduleDescriptor.uses().toArray(new String[0])); + + JavaProvides provides = moduleDescriptor.provides().iterator().next(); + assertEquals("example.Service", provides.service()); + assertArrayEquals( + new String[] {"example.ServiceImpl", "example.AlternativeServiceImpl"}, + provides.providers().toArray(new String[0])); + } } diff --git a/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java b/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java new file mode 100644 index 0000000..b03890e --- /dev/null +++ b/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java @@ -0,0 +1,8 @@ +package example; + +import java.util.List; + +public class AlternativeServiceImpl implements Service { + @Override + public void accept(List<@Nullable String> values) {} +} diff --git a/plexus-java/src/test/test-data/annotated-type-argument/example/Nullable.java b/plexus-java/src/test/test-data/annotated-type-argument/example/Nullable.java new file mode 100644 index 0000000..2454225 --- /dev/null +++ b/plexus-java/src/test/test-data/annotated-type-argument/example/Nullable.java @@ -0,0 +1,7 @@ +package example; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE_USE) +public @interface Nullable {} diff --git a/plexus-java/src/test/test-data/annotated-type-argument/example/Service.java b/plexus-java/src/test/test-data/annotated-type-argument/example/Service.java new file mode 100644 index 0000000..35526f8 --- /dev/null +++ b/plexus-java/src/test/test-data/annotated-type-argument/example/Service.java @@ -0,0 +1,7 @@ +package example; + +import java.util.List; + +public interface Service { + void accept(List<@Nullable String> values); +} diff --git a/plexus-java/src/test/test-data/annotated-type-argument/example/ServiceImpl.java b/plexus-java/src/test/test-data/annotated-type-argument/example/ServiceImpl.java new file mode 100644 index 0000000..0d5eff0 --- /dev/null +++ b/plexus-java/src/test/test-data/annotated-type-argument/example/ServiceImpl.java @@ -0,0 +1,8 @@ +package example; + +import java.util.List; + +public class ServiceImpl implements Service { + @Override + public void accept(List<@Nullable String> values) {} +} diff --git a/plexus-java/src/test/test-data/annotated-type-argument/module-info.java b/plexus-java/src/test/test-data/annotated-type-argument/module-info.java new file mode 100644 index 0000000..72f11dc --- /dev/null +++ b/plexus-java/src/test/test-data/annotated-type-argument/module-info.java @@ -0,0 +1,4 @@ +module annotated.type.argument { + uses example.Service; + provides example.Service with example.ServiceImpl, example.AlternativeServiceImpl; +}