Skip to content

Commit 66dfba7

Browse files
committed
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 apache/maven-compiler-plugin#314
1 parent a88cdb5 commit 66dfba7

11 files changed

Lines changed: 137 additions & 86 deletions

File tree

plexus-java/pom.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
<version>9.10.1</version>
1919
</dependency>
2020
<dependency>
21-
<groupId>com.thoughtworks.qdox</groupId>
22-
<artifactId>qdox</artifactId>
23-
<version>2.2.0</version>
21+
<groupId>com.github.javaparser</groupId>
22+
<artifactId>javaparser-core</artifactId>
23+
<version>3.28.2</version>
2424
</dependency>
2525
<dependency>
2626
<groupId>javax.inject</groupId>

plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java

Lines changed: 56 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,87 +19,88 @@
1919
* under the License.
2020
*/
2121

22-
import java.io.File;
2322
import java.io.IOException;
23+
import java.nio.file.Files;
2424
import java.nio.file.Path;
2525
import java.util.ArrayList;
2626
import java.util.LinkedHashSet;
2727
import java.util.List;
2828
import java.util.Set;
2929

30-
import com.thoughtworks.qdox.JavaProjectBuilder;
31-
import com.thoughtworks.qdox.model.JavaClass;
32-
import com.thoughtworks.qdox.model.JavaModule;
33-
import com.thoughtworks.qdox.model.JavaModuleDescriptor;
30+
import com.github.javaparser.StaticJavaParser;
31+
import com.github.javaparser.ast.expr.Name;
32+
import com.github.javaparser.ast.modules.ModuleDeclaration;
33+
import com.github.javaparser.ast.modules.ModuleDirective;
34+
import com.github.javaparser.ast.modules.ModuleExportsDirective;
35+
import com.github.javaparser.ast.modules.ModuleProvidesDirective;
36+
import com.github.javaparser.ast.modules.ModuleRequiresDirective;
37+
import com.github.javaparser.ast.modules.ModuleUsesDirective;
3438

3539
/**
36-
* Extract information from module with QDox
40+
* Extracts information from a source module descriptor.
3741
*
3842
* @author Robert Scholte
3943
* @since 1.0.0
4044
*/
4145
class SourceModuleInfoParser {
4246

43-
public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePath(Path modulePath)
44-
throws IOException {
45-
File moduleDescriptor = modulePath.toFile();
47+
public JavaModuleDescriptor fromSourcePath(Path modulePath) throws IOException {
48+
JavaModuleDescriptor.Builder builder;
49+
if (Files.exists(modulePath)) {
50+
ModuleDeclaration descriptor = StaticJavaParser.parse(modulePath)
51+
.getModule()
52+
.orElseThrow(() -> new IOException("Module declaration not found in " + modulePath));
4653

47-
org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder builder;
48-
if (moduleDescriptor.exists()) {
49-
JavaModuleDescriptor descriptor = new JavaProjectBuilder()
50-
.addSourceFolder(moduleDescriptor.getParentFile())
51-
.getDescriptor();
54+
builder = JavaModuleDescriptor.newModule(descriptor.getName().asString());
5255

53-
builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newModule(descriptor.getName());
54-
55-
for (JavaModuleDescriptor.JavaRequires requires : descriptor.getRequires()) {
56-
if (requires.isStatic() || requires.isTransitive()) {
57-
Set<org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier>
58-
modifiers = new LinkedHashSet<>(2);
59-
if (requires.isStatic()) {
60-
modifiers.add(
61-
org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier
62-
.STATIC);
63-
}
64-
if (requires.isTransitive()) {
65-
modifiers.add(
66-
org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier
67-
.TRANSITIVE);
56+
for (ModuleDirective directive : descriptor.getDirectives()) {
57+
if (directive instanceof ModuleRequiresDirective) {
58+
addRequires(builder, (ModuleRequiresDirective) directive);
59+
} else if (directive instanceof ModuleExportsDirective) {
60+
addExports(builder, (ModuleExportsDirective) directive);
61+
} else if (directive instanceof ModuleUsesDirective) {
62+
ModuleUsesDirective uses = (ModuleUsesDirective) directive;
63+
builder.uses(uses.getName().asString());
64+
} else if (directive instanceof ModuleProvidesDirective) {
65+
ModuleProvidesDirective provides = (ModuleProvidesDirective) directive;
66+
List<String> providers = new ArrayList<>(provides.getWith().size());
67+
for (Name provider : provides.getWith()) {
68+
providers.add(provider.asString());
6869
}
69-
builder.requires(modifiers, requires.getModule().getName());
70-
} else {
71-
builder.requires(requires.getModule().getName());
70+
builder.provides(provides.getName().asString(), providers);
7271
}
7372
}
73+
} else {
74+
builder = JavaModuleDescriptor.newAutomaticModule(null);
75+
}
7476

75-
for (JavaModuleDescriptor.JavaExports exports : descriptor.getExports()) {
76-
if (exports.getTargets().isEmpty()) {
77-
builder.exports(exports.getSource().getName());
78-
} else {
79-
Set<String> targets = new LinkedHashSet<>();
80-
for (JavaModule module : exports.getTargets()) {
81-
targets.add(module.getName());
82-
}
83-
builder.exports(exports.getSource().getName(), targets);
84-
}
85-
}
77+
return builder.build();
78+
}
8679

87-
for (JavaModuleDescriptor.JavaUses uses : descriptor.getUses()) {
88-
builder.uses(uses.getService().getName());
80+
private static void addRequires(JavaModuleDescriptor.Builder builder, ModuleRequiresDirective requires) {
81+
if (requires.isStatic() || requires.isTransitive()) {
82+
Set<JavaModuleDescriptor.JavaRequires.JavaModifier> modifiers = new LinkedHashSet<>(2);
83+
if (requires.isStatic()) {
84+
modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC);
8985
}
90-
91-
for (JavaModuleDescriptor.JavaProvides provides : descriptor.getProvides()) {
92-
List<String> providers = new ArrayList<>(provides.getProviders().size());
93-
for (JavaClass provider : provides.getProviders()) {
94-
providers.add(provider.getName());
95-
}
96-
97-
builder.provides(provides.getService().getName(), providers);
86+
if (requires.isTransitive()) {
87+
modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE);
9888
}
89+
builder.requires(modifiers, requires.getName().asString());
9990
} else {
100-
builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newAutomaticModule(null);
91+
builder.requires(requires.getName().asString());
10192
}
93+
}
10294

103-
return builder.build();
95+
private static void addExports(JavaModuleDescriptor.Builder builder, ModuleExportsDirective exports) {
96+
if (exports.getModuleNames().isEmpty()) {
97+
builder.exports(exports.getName().asString());
98+
} else {
99+
Set<String> targets = new LinkedHashSet<>();
100+
for (Name module : exports.getModuleNames()) {
101+
targets.add(module.asString());
102+
}
103+
builder.exports(exports.getName().asString(), targets);
104+
}
104105
}
105106
}

plexus-java/src/main/java9/module-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* under the License.
1818
*/
1919
module org.codehaus.plexus.languages.java {
20-
requires com.thoughtworks.qdox;
20+
requires com.github.javaparser.core;
2121
requires org.objectweb.asm;
2222

2323
exports org.codehaus.plexus.languages.java.jpms;

plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,15 @@ class LocationManagerIT {
4949
private BinaryModuleInfoParser asmParser;
5050

5151
@Mock
52-
private SourceModuleInfoParser qdoxParser;
52+
private SourceModuleInfoParser sourceParser;
5353

5454
private LocationManager locationManager;
5555

5656
final Path mockModuleInfoJava = Paths.get("src/test/test-data/mock/module-info.java");
5757

5858
@BeforeEach
5959
void onSetup() {
60-
locationManager = new LocationManager(qdoxParser) {
60+
locationManager = new LocationManager(sourceParser) {
6161
@Override
6262
ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) {
6363
return asmParser;
@@ -70,7 +70,7 @@ void manifestWithoutReflectRequires() throws Exception {
7070
Path abc = Paths.get("src/test/test-data/manifest.without/out");
7171
JavaModuleDescriptor descriptor =
7272
JavaModuleDescriptor.newModule("base").requires("any").build();
73-
when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
73+
when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
7474
ResolvePathsRequest<Path> request =
7575
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
7676

@@ -88,7 +88,7 @@ void emptyWithReflectRequires() throws Exception {
8888
Path abc = Paths.get("src/test/test-data/empty/out");
8989
JavaModuleDescriptor descriptor =
9090
JavaModuleDescriptor.newModule("base").requires("a.b.c").build();
91-
when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
91+
when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
9292
ResolvePathsRequest<Path> request =
9393
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
9494

0 commit comments

Comments
 (0)