summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-15 18:06:03 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-15 18:06:03 +0000
commit96d6f52454f99b220a34334431c9022c178a6304 (patch)
tree39ff62b6f6bd84cad9606cff57858fd55e8f6faa
parent1764075dea43f0d92e584d06b22e9bcc59786370 (diff)
parent88a62bb6769aa02fba887a969041572fab07e6f7 (diff)
downloadkythe-build-tools-release.tar.gz
Snap for 11582845 from 88a62bb6769aa02fba887a969041572fab07e6f7 to build-tools-releasebuild-tools-release
Change-Id: Ib851e35bca84c8e2d1b89e388ea8e9446bab50b6
-rw-r--r--Android.bp19
-rw-r--r--javac_extractor_manifest.txt2
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/15/JdkCompatibilityShimsImpl.java49
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/21/JdkCompatibilityShimsImpl.java48
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/9/JdkCompatibilityShimsImpl.java48
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java23
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/BUILD136
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/JavacWrapper.java (renamed from kythe/java/com/google/devtools/kythe/extractors/java/standalone/Javac9Wrapper.java)32
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/JdkCompatibilityShims.java37
-rw-r--r--kythe/java/com/google/devtools/kythe/extractors/java/standalone/ReflectiveJdkCompatibilityShims.java105
-rw-r--r--kythe/java/com/google/devtools/kythe/util/OrderedCompatibilityService.java115
11 files changed, 565 insertions, 49 deletions
diff --git a/Android.bp b/Android.bp
index 67d9d24a4..fffaeb0f6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -29,7 +29,16 @@ java_library_host {
name: "javac_extractor",
srcs: [
"kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java",
- "kythe/java/com/google/devtools/kythe/extractors/java/standalone/Javac9Wrapper.java",
+ "kythe/java/com/google/devtools/kythe/extractors/java/standalone/JavacWrapper.java",
+ "kythe/java/com/google/devtools/kythe/extractors/java/standalone/JdkCompatibilityShims.java",
+ // Currently it is not possible to pick a specific JDK version implementation of
+ // JdkCompatibilityShim, so only use the fallback (reflective) one. Otherwise, if it becomes
+ // possible, either through bp file configuration, or once JDK 21 is used consistently, we
+ // could also select one the options below.
+ "kythe/java/com/google/devtools/kythe/extractors/java/standalone/ReflectiveJdkCompatibilityShims.java",
+ // "kythe/java/com/google/devtools/kythe/extractors/java/standalone/9/JdkCompatibilityShimsImpl.java",
+ // "kythe/java/com/google/devtools/kythe/extractors/java/standalone/15/JdkCompatibilityShimsImpl.java",
+ // "kythe/java/com/google/devtools/kythe/extractors/java/standalone/21/JdkCompatibilityShimsImpl.java",
"kythe/java/com/google/devtools/kythe/extractors/java/*.java",
"kythe/java/com/google/devtools/kythe/extractors/shared/*.java",
"kythe/java/com/google/devtools/kythe/platform/kzip/*.java",
@@ -38,6 +47,7 @@ java_library_host {
"kythe/java/com/google/devtools/kythe/platform/shared/CompilationUnits.java",
"kythe/java/com/google/devtools/kythe/util/DeleteRecursively.java",
"kythe/java/com/google/devtools/kythe/util/JsonUtil.java",
+ "kythe/java/com/google/devtools/kythe/util/OrderedCompatibilityService.java",
":kythe_protos",
"kythe/proto/java.proto",
],
@@ -48,7 +58,10 @@ java_library_host {
"--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"--add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
"--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+ "--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED",
"--add-modules java.compiler",
+ "--add-modules jdk.internal.opt",
],
manifest: "javac_extractor_manifest.txt",
proto: {
@@ -65,6 +78,10 @@ java_library_host {
"libprotobuf-java-util-full",
"guava",
"jsr305",
+ "auto_service_annotations",
+ ],
+ plugins: [
+ "auto_service_plugin",
],
java_version: "1.9",
}
diff --git a/javac_extractor_manifest.txt b/javac_extractor_manifest.txt
index 7e039cc35..d30b75ecc 100644
--- a/javac_extractor_manifest.txt
+++ b/javac_extractor_manifest.txt
@@ -1 +1 @@
-Main-Class: com.google.devtools.kythe.extractors.java.standalone.Javac9Wrapper
+Main-Class: com.google.devtools.kythe.extractors.java.standalone.JavacWrapper
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/15/JdkCompatibilityShimsImpl.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/15/JdkCompatibilityShimsImpl.java
new file mode 100644
index 000000000..e0be7547f
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/15/JdkCompatibilityShimsImpl.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.extractors.java.standalone;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.Lists;
+import com.sun.tools.javac.main.Arguments;
+import com.sun.tools.javac.main.CommandLine;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/** JdkCompatibilityShims implementation for JDK15-compatible releases. */
+@AutoService(JdkCompatibilityShims.class)
+public final class JdkCompatibilityShimsImpl implements JdkCompatibilityShims {
+ private static final Runtime.Version minVersion = Runtime.Version.parse("15");
+ private static final Runtime.Version maxVersion = Runtime.Version.parse("21");
+
+ public JdkCompatibilityShimsImpl() {}
+
+ @Override
+ public CompatibilityRange getCompatibleRange() {
+ return new CompatibilityRange(minVersion, maxVersion);
+ }
+
+ @Override
+ public List<String> parseCompilerArguments(String[] args) throws IOException {
+ return Lists.newArrayList(CommandLine.parse(Arrays.asList(args)));
+ }
+
+ @Override
+ public void initializeArguments(Arguments arguments, String[] args) {
+ arguments.init("kythe_javac", Arrays.asList(args));
+ }
+}
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/21/JdkCompatibilityShimsImpl.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/21/JdkCompatibilityShimsImpl.java
new file mode 100644
index 000000000..a90082ed4
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/21/JdkCompatibilityShimsImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2023 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.extractors.java.standalone;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.Lists;
+import com.sun.tools.javac.main.Arguments;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import jdk.internal.opt.CommandLine;
+
+/** JdkCompatibilityShims implementation for JDK21-compatible releases. */
+@AutoService(JdkCompatibilityShims.class)
+public final class JdkCompatibilityShimsImpl implements JdkCompatibilityShims {
+ private static final Runtime.Version minVersion = Runtime.Version.parse("21");
+
+ public JdkCompatibilityShimsImpl() {}
+
+ @Override
+ public CompatibilityRange getCompatibleRange() {
+ return new CompatibilityRange(minVersion);
+ }
+
+ @Override
+ public List<String> parseCompilerArguments(String[] args) throws IOException {
+ return Lists.newArrayList(CommandLine.parse(Arrays.asList(args)));
+ }
+
+ @Override
+ public void initializeArguments(Arguments arguments, String[] args) {
+ arguments.init("kythe_javac", Arrays.asList(args));
+ }
+}
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/9/JdkCompatibilityShimsImpl.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/9/JdkCompatibilityShimsImpl.java
new file mode 100644
index 000000000..45f41ee47
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/9/JdkCompatibilityShimsImpl.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2022 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.extractors.java.standalone;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.Lists;
+import com.sun.tools.javac.main.Arguments;
+import com.sun.tools.javac.main.CommandLine;
+import java.io.IOException;
+import java.util.List;
+
+/** JdkCompatibilityShims implementation for JDK9-compatible releases. */
+@AutoService(JdkCompatibilityShims.class)
+public final class JdkCompatibilityShimsImpl implements JdkCompatibilityShims {
+ private static final Runtime.Version minVersion = Runtime.Version.parse("9");
+ private static final Runtime.Version maxVersion = Runtime.Version.parse("15");
+
+ public JdkCompatibilityShimsImpl() {}
+
+ @Override
+ public CompatibilityRange getCompatibleRange() {
+ return new CompatibilityRange(minVersion, maxVersion);
+ }
+
+ @Override
+ public List<String> parseCompilerArguments(String[] args) throws IOException {
+ return Lists.newArrayList(CommandLine.parse(args));
+ }
+
+ @Override
+ public void initializeArguments(Arguments arguments, String[] args) {
+ arguments.init("kythe_javac", args);
+ }
+}
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java
index 0c883ac6d..3a84d4a05 100644
--- a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/AbstractJavacWrapper.java
@@ -31,7 +31,6 @@ import com.google.devtools.kythe.extractors.shared.IndexInfoUtils;
import com.google.devtools.kythe.proto.Analysis.CompilationUnit;
import com.google.devtools.kythe.proto.Analysis.FileData;
import com.google.devtools.kythe.util.JsonUtil;
-import com.sun.tools.javac.main.CommandLine;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
@@ -66,6 +65,7 @@ import java.util.Optional;
*/
public abstract class AbstractJavacWrapper {
private static final Logger logger = Logger.getLogger(AbstractJavacWrapper.class.getName());
+ protected static final JdkCompatibilityShims shims = JdkCompatibilityShims.loadBest().get();
protected abstract Collection<CompilationDescription> processCompilation(
String[] arguments, JavaCompilationUnitExtractor javaCompilationUnitExtractor)
@@ -150,26 +150,7 @@ public abstract class AbstractJavacWrapper {
private static String[] getCleanedUpArguments(String[] args) throws IOException {
// Expand all @file arguments
- // JDK changed the signature of the CommandLine.parse method in JDK15,
- // support both versions
- List<String> expandedArgs = null;
- try {
- try {
- // JDK15+: the signature is
- // List<String> parse(List<String> args);
- expandedArgs = (List<String>)CommandLine.class.getMethod("parse", List.class).invoke(null, (Object)Arrays.asList(args));
- } catch (NoSuchMethodException nsme) {
- // pre-JDK15:
- // String[] parse(String[]);
- expandedArgs = Arrays.asList((String[])CommandLine.class.getMethod("parse", String[].class).invoke(null, (Object)args));
- }
- } catch (NoSuchMethodException ns2) {
- System.err.printf("Cannot locate com.sun.tools.javac.main.CommandLine.parse method, JDK version %s\n", System.getProperty("java.version"));
- System.exit(2);
- } catch (InvocationTargetException|IllegalAccessException ex) {
- System.err.printf("Cannot call com.sun.tools.javac.main.CommandLine.parse (JDK version %s):\n%s\n", System.getProperty("java.version"), ex);
- System.exit(2);
- }
+ List<String> expandedArgs = shims.parseCompilerArguments(args);
// We skip some arguments that would normally be passed to javac:
// -J, these are flags to the java environment running javac.
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/BUILD b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/BUILD
index 8b1a2f9f4..c118ef17a 100644
--- a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/BUILD
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/BUILD
@@ -1,5 +1,6 @@
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@rules_java//java:defs.bzl", "java_binary", "java_library")
+load("//tools:build_rules/selects.bzl", select_with_or = "with_or")
package(default_visibility = ["//kythe:default_visibility"])
@@ -7,13 +8,21 @@ exports_files(["javac-wrapper.sh"])
java_binary(
name = "javac_extractor",
- srcs = ["Javac9Wrapper.java"],
+ srcs = ["JavacWrapper.java"],
javacopts = [
"--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
"--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
],
- main_class = "com.google.devtools.kythe.extractors.java.standalone.Javac9Wrapper",
+ jvm_flags = [
+ "--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ ],
+ main_class = "com.google.devtools.kythe.extractors.java.standalone.JavacWrapper",
visibility = ["//visibility:public"],
deps = [
":abstract_javac_wrapper",
@@ -31,7 +40,22 @@ java_library(
javacopts = [
"--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
],
+ runtime_deps = [
+ ":reflective_jdk_compatibility_shims",
+ ] + select_with_or({
+ (
+ "//buildenv/java:language_version_default",
+ "//buildenv/java:language_version_11",
+ ): [":jdk9_compatibility_shims"],
+ (
+ "//buildenv/java:language_version_17",
+ "//buildenv/java:language_version_19",
+ "//buildenv/java:language_version_20",
+ "//buildenv/java:language_version_21",
+ ): [":jdk15_compatibility_shims"],
+ }),
deps = [
+ ":jdk_compatibility_shims",
"//kythe/java/com/google/devtools/kythe/extractors/java",
"//kythe/java/com/google/devtools/kythe/extractors/shared",
"//kythe/java/com/google/devtools/kythe/extractors/shared:environment",
@@ -43,7 +67,115 @@ java_library(
],
)
+java_library(
+ name = "jdk_compatibility_shims",
+ srcs = ["JdkCompatibilityShims.java"],
+ javacopts = [
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ ],
+ visibility = ["//visibility:private"],
+ deps = ["//kythe/java/com/google/devtools/kythe/util:ordered_compatibility_service"],
+)
+
+java_library(
+ name = "jdk9_compatibility_shims",
+ srcs = ["9/JdkCompatibilityShimsImpl.java"],
+ javacopts = [
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ "-Xep:PackageLocation:OFF",
+ ],
+ target_compatible_with = select_with_or({
+ (
+ "//buildenv/java:language_version_default",
+ "//buildenv/java:language_version_11",
+ ): [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ }),
+ visibility = ["//visibility:private"],
+ deps = [
+ ":jdk_compatibility_shims",
+ "//kythe/java/com/google/devtools/kythe/common:autoservice",
+ "//kythe/java/com/google/devtools/kythe/util:ordered_compatibility_service",
+ "//third_party/guava",
+ ],
+)
+
+java_library(
+ name = "jdk15_compatibility_shims",
+ srcs = ["15/JdkCompatibilityShimsImpl.java"],
+ javacopts = [
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ "-Xep:PackageLocation:OFF",
+ ],
+ # This is incompatible with the default test configuration and
+ # bazel cquery doesn't work with objc_library targets.
+ tags = ["manual"],
+ target_compatible_with = select_with_or({
+ (
+ "//buildenv/java:language_version_17",
+ "//buildenv/java:language_version_19",
+ "//buildenv/java:language_version_20",
+ ): [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ }),
+ visibility = ["//visibility:private"],
+ deps = [
+ ":jdk_compatibility_shims",
+ "//kythe/java/com/google/devtools/kythe/common:autoservice",
+ "//kythe/java/com/google/devtools/kythe/util:ordered_compatibility_service",
+ "//third_party/guava",
+ ],
+)
+
+java_library(
+ name = "jdk21_compatibility_shims",
+ srcs = ["21/JdkCompatibilityShimsImpl.java"],
+ javacopts = [
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ "--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
+ "--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED",
+ "-Xep:PackageLocation:OFF",
+ ],
+ # This is incompatible with the default test configuration and
+ # bazel cquery doesn't work with objc_library targets.
+ tags = ["manual"],
+ target_compatible_with = select_with_or({
+ (
+ "//buildenv/java:language_version_21",
+ ): [],
+ "//conditions:default": ["@platforms//:incompatible"],
+ }),
+ visibility = ["//visibility:private"],
+ deps = [
+ ":jdk_compatibility_shims",
+ "//kythe/java/com/google/devtools/kythe/common:autoservice",
+ "//kythe/java/com/google/devtools/kythe/util:ordered_compatibility_service",
+ "//third_party/guava",
+ ],
+)
+
+java_library(
+ name = "reflective_jdk_compatibility_shims",
+ srcs = ["ReflectiveJdkCompatibilityShims.java"],
+ javacopts = [
+ "--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
+ ] + select_with_or({
+ (
+ "//buildenv/java:language_version_21",
+ ): ["--add-exports=jdk.internal.opt/jdk.internal.opt=ALL-UNNAMED"],
+ "//conditions:default": [],
+ }),
+ visibility = ["//visibility:private"],
+ deps = [
+ ":jdk_compatibility_shims",
+ "//kythe/java/com/google/devtools/kythe/common:autoservice",
+ "//kythe/java/com/google/devtools/kythe/util:ordered_compatibility_service",
+ "//third_party/guava",
+ ],
+)
+
bzl_library(
name = "aspect_bzl",
srcs = ["aspect.bzl"],
+ deps = ["@rules_java//java:utils"],
)
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/Javac9Wrapper.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/JavacWrapper.java
index 31bc66a7b..291145129 100644
--- a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/Javac9Wrapper.java
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/JavacWrapper.java
@@ -37,8 +37,12 @@ import java.util.List;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
-/** A class that wraps javac to extract compilation information and write it to an index file. */
-public class Javac9Wrapper extends AbstractJavacWrapper {
+/**
+ * A class that wraps javac to extract compilation information and write it to an index file.
+ *
+ * <p>This class works for Java 9 and later.
+ */
+public class JavacWrapper extends AbstractJavacWrapper {
@Override
protected Collection<CompilationDescription> processCompilation(
String[] arguments, JavaCompilationUnitExtractor javaCompilationUnitExtractor)
@@ -48,27 +52,7 @@ public class Javac9Wrapper extends AbstractJavacWrapper {
JavacFileManager fileManager = new JavacFileManager(context, true, null);
Arguments args = Arguments.instance(context);
- // JDK changed the signature of Arguments.init method, support both
- try {
- try {
- // JDK15+: the signature is
- // init(String, Iterable<String> args);
- Arguments.class.getMethod("init", String.class, Iterable.class)
- .invoke(args, "kythe_javac", (Object) Arrays.asList(arguments));
- } catch (NoSuchMethodException nsme) {
- // pre-JDK15:
- // init(String, String...);
- Arguments.class.getMethod("init", String.class,String[].class)
- .invoke(args, "kythe_javac", (Object)arguments);
- }
- } catch (NoSuchMethodException ns2) {
- System.err.printf("Cannot locate com.sun.tools.javac.main.Arguments.init method, JDK version %s\n", System.getProperty("java.version"));
- System.exit(2);
- } catch (InvocationTargetException|IllegalAccessException ex) {
- System.err.printf("Cannot call com.sun.tools.javac.main.Arguments.init (JDK version %s):\n%s\n", System.getProperty("java.version"), ex);
- System.exit(2);
- }
-
+ shims.initializeArguments(args, arguments);
fileManager.handleOptions(args.getDeferredFileManagerOptions());
Options options = Options.instance(context);
@@ -173,6 +157,6 @@ public class Javac9Wrapper extends AbstractJavacWrapper {
}
public static void main(String[] args) {
- new Javac9Wrapper().process(args);
+ new JavacWrapper().process(args);
}
}
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/JdkCompatibilityShims.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/JdkCompatibilityShims.java
new file mode 100644
index 000000000..3c042c5cf
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/JdkCompatibilityShims.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.extractors.java.standalone;
+
+import com.google.devtools.kythe.util.OrderedCompatibilityService;
+import com.sun.tools.javac.main.Arguments;
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+
+/** Shims for providing source-level compatibility between JDK versions. */
+public interface JdkCompatibilityShims extends OrderedCompatibilityService {
+ /** Loads the best service provider for this interface, if any. */
+ public static Optional<JdkCompatibilityShims> loadBest() {
+ return OrderedCompatibilityService.loadBest(JdkCompatibilityShims.class);
+ }
+
+ /** Parse the compiler arguments and returns them as an expanded list. */
+ List<String> parseCompilerArguments(String[] args) throws IOException;
+
+ /** Initialize the Arguments instance from the list of args. */
+ void initializeArguments(Arguments arguments, String[] args);
+}
diff --git a/kythe/java/com/google/devtools/kythe/extractors/java/standalone/ReflectiveJdkCompatibilityShims.java b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/ReflectiveJdkCompatibilityShims.java
new file mode 100644
index 000000000..80dacbe2f
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/extractors/java/standalone/ReflectiveJdkCompatibilityShims.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2022 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.extractors.java.standalone;
+
+import com.google.auto.service.AutoService;
+import com.google.common.collect.ImmutableList;
+import com.sun.tools.javac.main.Arguments;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+/** JdkCompatibilityShims implementation for JDK9-compatible releases. */
+@AutoService(JdkCompatibilityShims.class)
+public final class ReflectiveJdkCompatibilityShims implements JdkCompatibilityShims {
+ private static final Runtime.Version minVersion = Runtime.Version.parse("9");
+
+ public ReflectiveJdkCompatibilityShims() {}
+
+ @Override
+ public CompatibilityRange getCompatibleRange() {
+ return new CompatibilityRange(minVersion, Optional.empty(), CompatibilityLevel.FALLBACK);
+ }
+
+ @Override
+ @SuppressWarnings({"CheckedExceptionNotThrown", "unchecked"}) // Safe by specification.
+ public List<String> parseCompilerArguments(String[] args) throws IOException {
+ try {
+ Class<?> commandLine = loadCommandLineClass();
+ try {
+ // JDK15+: the signature is
+ // List<String> parse(List<String> args)
+ return (List<String>)
+ commandLine.getMethod("parse", List.class).invoke(null, (Object) Arrays.asList(args));
+ } catch (NoSuchMethodException nsme) {
+ // 9 <= JDK < 15: the signature is
+ // String[] parse(String[] args)
+ return Arrays.asList(
+ (String[]) commandLine.getMethod("parse", String[].class).invoke(null, (Object) args));
+ }
+ } catch (ClassCastException
+ | ClassNotFoundException
+ | InvocationTargetException
+ | IllegalAccessException
+ | NoSuchMethodException ex) {
+ throw new LinkageError(ex.getMessage(), ex);
+ }
+ }
+
+ @Override
+ public void initializeArguments(Arguments arguments, String[] args) {
+ try {
+ try {
+ // JDK15+: the signature is
+ // init(String, Iterable<String> args);
+ arguments
+ .getClass()
+ .getMethod("init", String.class, Iterable.class)
+ .invoke(arguments, "kythe_javac", (Object) Arrays.asList(args));
+ } catch (NoSuchMethodException nsme) {
+ // pre-JDK15:
+ // init(String, String...);
+ arguments
+ .getClass()
+ .getMethod("init", String.class, String[].class)
+ .invoke(arguments, "kythe_javac", (Object) args);
+ }
+ } catch (ClassCastException
+ | InvocationTargetException
+ | IllegalAccessException
+ | NoSuchMethodException ex) {
+ throw new LinkageError(ex.getMessage(), ex);
+ }
+ }
+
+ private static Class<?> loadCommandLineClass() throws ClassNotFoundException {
+ ImmutableList<String> classNames =
+ // < JDK21 the class is known as com.sun.tools.java.main.CommandLine
+ // >= JDK21 it's known as jdk.internal.opt.CommandLine
+ ImmutableList.of("com.sun.tools.javac.main.CommandLine", "jdk.internal.opt.CommandLine");
+ for (String name : classNames) {
+ try {
+ return ReflectiveJdkCompatibilityShims.class.getClassLoader().loadClass(name);
+ } catch (ClassNotFoundException unused) {
+ continue;
+ }
+ }
+ throw new ClassNotFoundException("unable to load JDK CommandLine class");
+ }
+}
diff --git a/kythe/java/com/google/devtools/kythe/util/OrderedCompatibilityService.java b/kythe/java/com/google/devtools/kythe/util/OrderedCompatibilityService.java
new file mode 100644
index 000000000..84db8c4cd
--- /dev/null
+++ b/kythe/java/com/google/devtools/kythe/util/OrderedCompatibilityService.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2022 The Kythe Authors. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.devtools.kythe.util;
+
+import com.google.common.collect.Streams;
+import java.util.Comparator;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+/**
+ * OrderedCompatibilityService defines shared functionality between between JdkCompatibilityShim
+ * interfaces.
+ */
+public interface OrderedCompatibilityService {
+
+ /** The compatibility level of the provider. */
+ public enum CompatibilityLevel {
+ /** This provider is incompatible with the current runtime. */
+ INCOMPATIBLE,
+ /**
+ * This provider is compatible with the current runtime, but should only be used if a COMPATIBLE
+ * provider can't be found.
+ */
+ FALLBACK,
+ /**
+ * This provider is compatible with the current runtime and should be preferred over a fallback,
+ * if any.
+ */
+ COMPATIBLE
+ }
+
+ /** Indicates the range of runtime versions with which these shims are compatible. */
+ public static class CompatibilityRange {
+ private final Runtime.Version minVersion;
+ private final Optional<Runtime.Version> maxVersion;
+ private final CompatibilityLevel level;
+
+ public CompatibilityRange(Runtime.Version minVersion) {
+ this(minVersion, Optional.empty(), CompatibilityLevel.COMPATIBLE);
+ }
+
+ public CompatibilityRange(Runtime.Version minVersion, Runtime.Version maxVersion) {
+ this(minVersion, Optional.of(maxVersion), CompatibilityLevel.COMPATIBLE);
+ }
+
+ public CompatibilityRange(
+ Runtime.Version minVersion,
+ Optional<Runtime.Version> maxVersion,
+ CompatibilityLevel level) {
+ this.minVersion = minVersion;
+ this.maxVersion = maxVersion;
+ this.level = level;
+ }
+
+ /** Returns the minimum known compatible runtime version. */
+ public Runtime.Version getMinVersion() {
+ return minVersion;
+ }
+
+ /** Returns the maximum known compatible runtime version, if any. */
+ public Optional<Runtime.Version> getMaxVersion() {
+ return maxVersion;
+ }
+
+ /** Returns the compatibility level. */
+ public CompatibilityLevel getCompatibilityLevel() {
+ return level;
+ }
+ }
+
+ /** Returns the compatibility level of the service provider. */
+ CompatibilityRange getCompatibleRange();
+
+ public static <S extends OrderedCompatibilityService> Optional<S> loadBest(Class<S> klass) {
+ Runtime.Version version = Runtime.version();
+ return Streams.stream(ServiceLoader.load(klass))
+ // Filter out incompatible providers.
+ .filter(p -> isCompatible(version, p.getCompatibleRange()))
+ // Then find the best.
+ .max(OrderedCompatibilityService::compareProviders);
+ }
+
+ private static boolean isCompatible(Runtime.Version version, CompatibilityRange range) {
+ return range.getCompatibilityLevel() != CompatibilityLevel.INCOMPATIBLE
+ && version.compareToIgnoreOptional(range.getMinVersion()) >= 0
+ && range.getMaxVersion().map(max -> version.compareToIgnoreOptional(max) < 0).orElse(true);
+ }
+
+ private static int compareCompatibilityRanges(CompatibilityRange lhs, CompatibilityRange rhs) {
+ return Comparator.comparing(CompatibilityRange::getCompatibilityLevel)
+ .thenComparing(CompatibilityRange::getMinVersion, Runtime.Version::compareToIgnoreOptional)
+ .compare(lhs, rhs);
+ }
+
+ private static <S extends OrderedCompatibilityService> int compareProviders(S lhs, S rhs) {
+ return Comparator.comparing(
+ OrderedCompatibilityService::getCompatibleRange,
+ OrderedCompatibilityService::compareCompatibilityRanges)
+ .compare(lhs, rhs);
+ }
+}