aboutsummaryrefslogtreecommitdiff
path: root/java/com/google/turbine/binder/CtSymClassBinder.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/turbine/binder/CtSymClassBinder.java')
-rw-r--r--java/com/google/turbine/binder/CtSymClassBinder.java47
1 files changed, 41 insertions, 6 deletions
diff --git a/java/com/google/turbine/binder/CtSymClassBinder.java b/java/com/google/turbine/binder/CtSymClassBinder.java
index a6f1b3d..1d7ece7 100644
--- a/java/com/google/turbine/binder/CtSymClassBinder.java
+++ b/java/com/google/turbine/binder/CtSymClassBinder.java
@@ -16,11 +16,15 @@
package com.google.turbine.binder;
+import static com.google.common.base.Ascii.toUpperCase;
import static com.google.common.base.StandardSystemProperty.JAVA_HOME;
+import static java.util.Objects.requireNonNull;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableMap;
+import com.google.common.primitives.Ints;
import com.google.turbine.binder.bound.ModuleInfo;
import com.google.turbine.binder.bytecode.BytecodeBinder;
import com.google.turbine.binder.bytecode.BytecodeBoundClass;
@@ -32,6 +36,7 @@ import com.google.turbine.binder.sym.ClassSymbol;
import com.google.turbine.binder.sym.ModuleSymbol;
import com.google.turbine.zip.Zip;
import java.io.IOException;
+import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -40,12 +45,13 @@ import java.util.Map;
import org.checkerframework.checker.nullness.qual.Nullable;
/** Constructs a platform {@link ClassPath} from the current JDK's ct.sym file. */
-public class CtSymClassBinder {
+public final class CtSymClassBinder {
@Nullable
public static ClassPath bind(String version) throws IOException {
- Path javaHome = Paths.get(JAVA_HOME.value());
- Path ctSym = javaHome.resolve("lib/ct.sym");
+ String javaHome = JAVA_HOME.value();
+ requireNonNull(javaHome, "attempted to use --release, but JAVA_HOME is not set");
+ Path ctSym = Paths.get(javaHome).resolve("lib/ct.sym");
if (!Files.exists(ctSym)) {
throw new IllegalStateException("lib/ct.sym does not exist in " + javaHome);
}
@@ -59,7 +65,9 @@ public class CtSymClassBinder {
}
};
// ct.sym contains directories whose names are the concatentation of a list of target versions
- // (e.g. 789) and which contain interface class files with a .sig extension.
+ // formatted as a single character 0-9 or A-Z (e.g. 789A) and which contain interface class
+ // files with a .sig extension.
+ String releaseString = formatReleaseVersion(version);
for (Zip.Entry ze : new Zip.ZipIterable(ctSym)) {
String name = ze.name();
if (!name.endsWith(".sig")) {
@@ -70,10 +78,13 @@ public class CtSymClassBinder {
continue;
}
// check if the directory matches the desired release
- // TODO(cushon): what happens when version numbers contain more than one digit?
- if (!ze.name().substring(0, idx).contains(version)) {
+ if (!ze.name().substring(0, idx).contains(releaseString)) {
continue;
}
+ if (isAtLeastJDK12()) {
+ // JDK >= 12 includes the module name as a prefix
+ idx = name.indexOf('/', idx + 1);
+ }
if (name.substring(name.lastIndexOf('/') + 1).equals("module-info.sig")) {
ModuleInfo moduleInfo = BytecodeBinder.bindModuleInfo(name, toByteArrayOrDie(ze));
modules.put(new ModuleSymbol(moduleInfo.name()), moduleInfo);
@@ -122,4 +133,28 @@ public class CtSymClassBinder {
}
});
}
+
+ @VisibleForTesting
+ static String formatReleaseVersion(String version) {
+ Integer n = Ints.tryParse(version);
+ if (n == null || n <= 4 || n >= 36) {
+ throw new IllegalArgumentException("invalid release version: " + version);
+ }
+ return toUpperCase(Integer.toString(n, 36));
+ }
+
+ private static boolean isAtLeastJDK12() {
+ int major;
+ try {
+ Method versionMethod = Runtime.class.getMethod("version");
+ Object version = versionMethod.invoke(null);
+ major = (int) version.getClass().getMethod("major").invoke(version);
+ } catch (ReflectiveOperationException e) {
+ // `Runtime.version()` was added in JDK 9
+ return false;
+ }
+ return major >= 12;
+ }
+
+ private CtSymClassBinder() {}
}