Skip to content

Commit ba0df8e

Browse files
committed
javac: support extra compiler args
1 parent 82c3f10 commit ba0df8e

7 files changed

Lines changed: 106 additions & 6 deletions

File tree

package.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@
6666
},
6767
"description": "Relative paths from workspace root to .jar files, .zip files, or folders that should be included in the Java class path"
6868
},
69+
"java.extraCompilerArgs": {
70+
"type": "array",
71+
"items": {
72+
"type": "string"
73+
},
74+
"description": "Extra compiler args, for example [\"--enable-preview\",\"-source 21\"]."
75+
},
6976
"java.docPath": {
7077
"type": "array",
7178
"items": {

src/main/java/org/javacs/CompileBatch.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ public void close() {
103103
private static ReusableCompiler.Borrow batchTask(
104104
JavaCompilerService parent, Collection<? extends JavaFileObject> sources) {
105105
parent.diags.clear();
106-
var options = options(parent.classPath, parent.addExports);
106+
var options = options(parent.classPath, parent.addExports, parent.extraArgs);
107107
return parent.compiler.getTask(parent.fileManager, parent.diags::add, options, List.of(), sources);
108108
}
109109

@@ -112,7 +112,7 @@ private static String joinPath(Collection<Path> classOrSourcePath) {
112112
return classOrSourcePath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator));
113113
}
114114

115-
private static List<String> options(Set<Path> classPath, Set<String> addExports) {
115+
private static List<String> options(Set<Path> classPath, Set<String> addExports, List<String> extraArgs) {
116116
var list = new ArrayList<String>();
117117

118118
Collections.addAll(list, "-classpath", joinPath(classPath));
@@ -133,6 +133,7 @@ private static List<String> options(Set<Path> classPath, Set<String> addExports)
133133
"-Xlint:unchecked",
134134
"-Xlint:varargs",
135135
"-Xlint:static");
136+
list.addAll(extraArgs);
136137
for (var export : addExports) {
137138
list.add("--add-exports");
138139
list.add(export + "=ALL-UNNAMED");

src/main/java/org/javacs/JavaCompilerService.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class JavaCompilerService implements CompilerProvider {
1212
// Not modifiable! If you want to edit these, you need to create a new instance
1313
final Set<Path> classPath, docPath;
1414
final Set<String> addExports;
15+
final List<String> extraArgs;
1516
final ReusableCompiler compiler = new ReusableCompiler();
1617
final Docs docs;
1718
final Set<String> jdkClasses = ScanClassPath.jdkTopLevelClasses(), classPathClasses;
@@ -21,7 +22,7 @@ class JavaCompilerService implements CompilerProvider {
2122
// TODO intercept files that aren't in the batch and erase method bodies so compilation is faster
2223
final SourceFileManager fileManager;
2324

24-
JavaCompilerService(Set<Path> classPath, Set<Path> docPath, Set<String> addExports) {
25+
JavaCompilerService(Set<Path> classPath, Set<Path> docPath, Set<String> addExports, List<String> extraArgs) {
2526
System.err.println("Class path:");
2627
for (var p : classPath) {
2728
System.err.println(" " + p);
@@ -34,6 +35,7 @@ class JavaCompilerService implements CompilerProvider {
3435
this.classPath = Collections.unmodifiableSet(classPath);
3536
this.docPath = Collections.unmodifiableSet(docPath);
3637
this.addExports = Collections.unmodifiableSet(addExports);
38+
this.extraArgs = Collections.unmodifiableList(new ArrayList<>(extraArgs));
3739
this.docs = new Docs(docPath);
3840
this.classPathClasses = ScanClassPath.classPathTopLevelClasses(classPath);
3941
this.fileManager = new SourceFileManager();

src/main/java/org/javacs/JavaLanguageServer.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,12 @@ private JavaCompilerService createCompiler() {
9393

9494
var externalDependencies = externalDependencies();
9595
var classPath = classPath();
96+
var extraArgs = extraCompilerArgs();
9697
var addExports = addExports();
9798
// If classpath is specified by the user, don't infer anything
9899
if (!classPath.isEmpty()) {
99100
javaEndProgress();
100-
return new JavaCompilerService(classPath, docPath(), addExports);
101+
return new JavaCompilerService(classPath, docPath(), addExports, extraArgs);
101102
}
102103
// Otherwise, combine inference with user-specified external dependencies
103104
else {
@@ -110,7 +111,7 @@ private JavaCompilerService createCompiler() {
110111
var docPath = infer.buildDocPath();
111112

112113
javaEndProgress();
113-
return new JavaCompilerService(classPath, docPath, addExports);
114+
return new JavaCompilerService(classPath, docPath, addExports, extraArgs);
114115
}
115116
}
116117

@@ -134,6 +135,20 @@ private Set<Path> classPath() {
134135
return paths;
135136
}
136137

138+
private List<String> extraCompilerArgs() {
139+
if (!settings.has("extraCompilerArgs")) return List.of();
140+
var array = settings.getAsJsonArray("extraCompilerArgs");
141+
var args = new ArrayList<String>();
142+
for (var each : array) {
143+
for (var arg : each.getAsString().split("\\s+")) {
144+
if (!arg.isEmpty()) {
145+
args.add(arg);
146+
}
147+
}
148+
}
149+
return args;
150+
}
151+
137152
private Set<Path> docPath() {
138153
if (!settings.has("docPath")) return Set.of();
139154
var array = settings.getAsJsonArray("docPath");
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class UsesPreviewStringTemplate {
2+
void test(String name) {
3+
String message = STR."hello \{name}";
4+
System.out.println(message);
5+
}
6+
}

src/test/java/org/javacs/BenchmarkPruner.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private static JavaCompilerService createCompiler() {
5656
var workspaceRoot = Paths.get(".").normalize().toAbsolutePath();
5757
FileStore.setWorkspaceRoots(Set.of(workspaceRoot));
5858
var classPath = new InferConfig(workspaceRoot).classPath();
59-
return new JavaCompilerService(classPath, Collections.emptySet(), Collections.emptySet());
59+
return new JavaCompilerService(classPath, Collections.emptySet(), Collections.emptySet(), List.of());
6060
}
6161

6262
private static void quietBenchmarkLogging() {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.javacs;
2+
3+
import static org.hamcrest.MatcherAssert.assertThat;
4+
import static org.hamcrest.Matchers.nullValue;
5+
import static org.hamcrest.Matchers.notNullValue;
6+
7+
import com.google.gson.JsonArray;
8+
import com.google.gson.JsonObject;
9+
import java.nio.file.Path;
10+
import java.nio.file.Paths;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import org.javacs.lsp.Diagnostic;
14+
import org.javacs.lsp.DiagnosticSeverity;
15+
import org.javacs.lsp.DidChangeConfigurationParams;
16+
import org.junit.Before;
17+
import org.junit.Test;
18+
19+
public class ExtraCompilerArgsTest {
20+
private static final Path WORKSPACE_ROOT = Paths.get("src/test/examples/compiler-args-project").normalize();
21+
private static final Path FILE = WORKSPACE_ROOT.resolve("UsesPreviewStringTemplate.java").normalize();
22+
23+
private final List<Diagnostic> diagnostics = new ArrayList<>();
24+
25+
@Before
26+
public void clearDiagnostics() {
27+
diagnostics.clear();
28+
}
29+
30+
@Test
31+
public void reportsErrorWithoutExtraCompilerArgs() {
32+
var server = LanguageServerFixture.getJavaLanguageServer(WORKSPACE_ROOT, diagnostics::add);
33+
34+
server.lint(List.of(FILE));
35+
36+
assertThat(firstError(), notNullValue());
37+
}
38+
39+
@Test
40+
public void appliesExtraCompilerArgsFromSettings() {
41+
var server = LanguageServerFixture.getJavaLanguageServer(WORKSPACE_ROOT, diagnostics::add);
42+
var change = new DidChangeConfigurationParams();
43+
var settings = new JsonObject();
44+
var java = new JsonObject();
45+
var args = new JsonArray();
46+
args.add("--enable-preview");
47+
args.add("-source");
48+
args.add("21");
49+
java.add("extraCompilerArgs", args);
50+
settings.add("java", java);
51+
change.settings = settings;
52+
53+
server.didChangeConfiguration(change);
54+
server.lint(List.of(FILE));
55+
56+
assertThat(firstError(), nullValue());
57+
}
58+
59+
private Diagnostic firstError() {
60+
Diagnostic error = null;
61+
for (var diagnostic : diagnostics) {
62+
if (diagnostic.severity == DiagnosticSeverity.Error) {
63+
error = diagnostic;
64+
break;
65+
}
66+
}
67+
return error;
68+
}
69+
}

0 commit comments

Comments
 (0)