diff --git a/package.json b/package.json index 3e3d4c19f..8e1353fcc 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,13 @@ }, "description": "Relative paths from workspace root to .jar files, .zip files, or folders that should be included in the Java class path" }, + "java.extraCompilerArgs": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Extra compiler args, for example [\"--enable-preview\",\"-source 21\"]." + }, "java.docPath": { "type": "array", "items": { diff --git a/src/main/java/org/javacs/CompileBatch.java b/src/main/java/org/javacs/CompileBatch.java index 5956967c4..82fd516a4 100644 --- a/src/main/java/org/javacs/CompileBatch.java +++ b/src/main/java/org/javacs/CompileBatch.java @@ -101,7 +101,7 @@ public void close() { private static ReusableCompiler.Borrow batchTask( JavaCompilerService parent, Collection sources) { parent.diags.clear(); - var options = options(parent.classPath, parent.addExports); + var options = options(parent.classPath, parent.addExports,parent.extraArgs); return parent.compiler.getTask(parent.fileManager, parent.diags::add, options, List.of(), sources); } @@ -110,7 +110,7 @@ private static String joinPath(Collection classOrSourcePath) { return classOrSourcePath.stream().map(Path::toString).collect(Collectors.joining(File.pathSeparator)); } - private static List options(Set classPath, Set addExports) { + private static List options(Set classPath, Set addExports,Set extraArgs) { var list = new ArrayList(); Collections.addAll(list, "-classpath", joinPath(classPath)); @@ -131,6 +131,7 @@ private static List options(Set classPath, Set addExports) "-Xlint:unchecked", "-Xlint:varargs", "-Xlint:static"); + list.addAll(extraArgs); for (var export : addExports) { list.add("--add-exports"); list.add(export + "=ALL-UNNAMED"); diff --git a/src/main/java/org/javacs/JavaCompilerService.java b/src/main/java/org/javacs/JavaCompilerService.java index cfe727830..52126bdb1 100644 --- a/src/main/java/org/javacs/JavaCompilerService.java +++ b/src/main/java/org/javacs/JavaCompilerService.java @@ -12,6 +12,7 @@ class JavaCompilerService implements CompilerProvider { // Not modifiable! If you want to edit these, you need to create a new instance final Set classPath, docPath; final Set addExports; + final Set extraArgs; final ReusableCompiler compiler = new ReusableCompiler(); final Docs docs; final Set jdkClasses = ScanClassPath.jdkTopLevelClasses(), classPathClasses; @@ -21,7 +22,7 @@ class JavaCompilerService implements CompilerProvider { // TODO intercept files that aren't in the batch and erase method bodies so compilation is faster final SourceFileManager fileManager; - JavaCompilerService(Set classPath, Set docPath, Set addExports) { + JavaCompilerService(Set classPath, Set docPath, Set addExports, Set extraArgs) { System.err.println("Class path:"); for (var p : classPath) { System.err.println(" " + p); @@ -34,6 +35,7 @@ class JavaCompilerService implements CompilerProvider { this.classPath = Collections.unmodifiableSet(classPath); this.docPath = Collections.unmodifiableSet(docPath); this.addExports = Collections.unmodifiableSet(addExports); + this.extraArgs = Collections.unmodifiableSet(extraArgs); this.docs = new Docs(docPath); this.classPathClasses = ScanClassPath.classPathTopLevelClasses(classPath); this.fileManager = new SourceFileManager(); diff --git a/src/main/java/org/javacs/JavaLanguageServer.java b/src/main/java/org/javacs/JavaLanguageServer.java index aa96ebd09..dad1b96d9 100644 --- a/src/main/java/org/javacs/JavaLanguageServer.java +++ b/src/main/java/org/javacs/JavaLanguageServer.java @@ -92,11 +92,12 @@ private JavaCompilerService createCompiler() { var externalDependencies = externalDependencies(); var classPath = classPath(); + var extraArgs = extraCompilerArgs(); var addExports = addExports(); // If classpath is specified by the user, don't infer anything if (!classPath.isEmpty()) { javaEndProgress(); - return new JavaCompilerService(classPath, docPath(), addExports); + return new JavaCompilerService(classPath, docPath(), addExports, extraArgs); } // Otherwise, combine inference with user-specified external dependencies else { @@ -109,7 +110,7 @@ private JavaCompilerService createCompiler() { var docPath = infer.buildDocPath(); javaEndProgress(); - return new JavaCompilerService(classPath, docPath, addExports); + return new JavaCompilerService(classPath, docPath, addExports, extraArgs); } } @@ -133,6 +134,17 @@ private Set classPath() { return paths; } + private Set extraCompilerArgs(){ + if (!settings.has("extraCompilerArgs")) return Set.of(); + var array = settings.getAsJsonArray("extraCompilerArgs"); + var args = new HashSet(); + for (var each : array) { + // split "a b c" to ["a","b","c"] + args.addAll(Arrays.asList(each.getAsString().split("\\s+"))); + } + return args; + } + private Set docPath() { if (!settings.has("docPath")) return Set.of(); var array = settings.getAsJsonArray("docPath");