diff --git a/java/com/google/turbine/binder/ClassPathBinder.java b/java/com/google/turbine/binder/ClassPathBinder.java index af59bcac..b499fa23 100644 --- a/java/com/google/turbine/binder/ClassPathBinder.java +++ b/java/com/google/turbine/binder/ClassPathBinder.java @@ -17,7 +17,6 @@ package com.google.turbine.binder; import com.google.common.base.Supplier; -import com.google.common.base.Suppliers; import com.google.common.collect.ImmutableMap; import com.google.turbine.binder.bound.ModuleInfo; import com.google.turbine.binder.bytecode.BytecodeBinder; @@ -35,7 +34,6 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; -import java.util.function.Function; import org.jspecify.annotations.Nullable; /** Sets up an environment for symbols on the classpath. */ @@ -55,33 +53,31 @@ public final class ClassPathBinder { /** Creates an environment containing symbols in the given classpath. */ public static ClassPath bindClasspath(Collection paths) throws IOException { - // TODO(cushon): this is going to require an env eventually, - // e.g. to look up type parameters in enclosing declarations - Map transitive = new LinkedHashMap<>(); - Map map = new HashMap<>(); + Map> transitive = new LinkedHashMap<>(); + Map> map = new HashMap<>(); Map modules = new HashMap<>(); Map> resources = new HashMap<>(); - Env benv = + Env env = new Env() { @Override public @Nullable BytecodeBoundClass get(ClassSymbol sym) { - return map.get(sym); + Supplier supplier = map.get(sym); + return supplier == null ? null : supplier.get(); } }; for (Path path : paths) { try { - bindJar(path, map, modules, benv, transitive, resources); + bindJar(path, map, modules, env, transitive, resources); } catch (IOException e) { throw new IOException("error reading " + path, e); } } - for (Map.Entry entry : transitive.entrySet()) { + for (Map.Entry> entry : transitive.entrySet()) { ClassSymbol symbol = entry.getKey(); map.putIfAbsent(symbol, entry.getValue()); } - SimpleEnv env = new SimpleEnv<>(ImmutableMap.copyOf(map)); SimpleEnv moduleEnv = new SimpleEnv<>(ImmutableMap.copyOf(modules)); - TopLevelIndex index = SimpleTopLevelIndex.of(env.asMap().keySet()); + TopLevelIndex index = SimpleTopLevelIndex.of(map.keySet()); return new ClassPath() { @Override public Env env() { @@ -107,10 +103,10 @@ public TopLevelIndex index() { private static void bindJar( Path path, - Map env, + Map> env, Map modules, Env benv, - Map transitive, + Map> transitive, Map> resources) throws IOException { // TODO(cushon): don't leak file descriptors @@ -124,41 +120,22 @@ private static void bindJar( new ClassSymbol( name.substring( TRANSITIVE_PREFIX.length(), name.length() - TRANSITIVE_SUFFIX.length())); - transitive.computeIfAbsent( - sym, - new Function() { - @Override - public BytecodeBoundClass apply(ClassSymbol sym) { - return new BytecodeBoundClass(sym, toByteArrayOrDie(ze), benv, path.toString()); - } - }); + transitive.putIfAbsent(sym, BytecodeBoundClass.lazy(sym, ze, benv, path)); continue; } if (!name.endsWith(".class")) { - resources.put(name, toByteArrayOrDie(ze)); + resources.put(name, ze); continue; } if (name.substring(name.lastIndexOf('/') + 1).equals("module-info.class")) { - ModuleInfo moduleInfo = - BytecodeBinder.bindModuleInfo(path.toString(), toByteArrayOrDie(ze)); + ModuleInfo moduleInfo = BytecodeBinder.bindModuleInfo(path.toString(), ze); modules.put(new ModuleSymbol(moduleInfo.name()), moduleInfo); continue; } ClassSymbol sym = new ClassSymbol(name.substring(0, name.length() - ".class".length())); - env.putIfAbsent( - sym, new BytecodeBoundClass(sym, toByteArrayOrDie(ze), benv, path.toString())); + env.putIfAbsent(sym, BytecodeBoundClass.lazy(sym, ze, benv, path)); } } - private static Supplier toByteArrayOrDie(Zip.Entry ze) { - return Suppliers.memoize( - new Supplier() { - @Override - public byte[] get() { - return ze.data(); - } - }); - } - private ClassPathBinder() {} } diff --git a/java/com/google/turbine/binder/CtSymClassBinder.java b/java/com/google/turbine/binder/CtSymClassBinder.java index a04366f9..8b374a3e 100644 --- a/java/com/google/turbine/binder/CtSymClassBinder.java +++ b/java/com/google/turbine/binder/CtSymClassBinder.java @@ -21,7 +21,6 @@ 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.turbine.binder.bound.ModuleInfo; import com.google.turbine.binder.bytecode.BytecodeBinder; @@ -86,13 +85,12 @@ public final class CtSymClassBinder { // 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)); + ModuleInfo moduleInfo = BytecodeBinder.bindModuleInfo(name, ze); modules.put(new ModuleSymbol(moduleInfo.name()), moduleInfo); continue; } ClassSymbol sym = new ClassSymbol(name.substring(idx + 1, name.length() - ".sig".length())); - map.putIfAbsent( - sym, new BytecodeBoundClass(sym, toByteArrayOrDie(ze), benv, ctSym + "!" + ze.name())); + map.putIfAbsent(sym, new BytecodeBoundClass(sym, ze, benv, ctSym + "!" + ze.name())); } if (map.isEmpty()) { // we didn't find any classes for the desired release @@ -124,16 +122,6 @@ public TopLevelIndex index() { }; } - private static Supplier toByteArrayOrDie(Zip.Entry ze) { - return Suppliers.memoize( - new Supplier() { - @Override - public byte[] get() { - return ze.data(); - } - }); - } - // ct.sym contains directories whose names are the concatenation of a list of target versions // formatted as a single character 0-9 or A-Z (e.g. 789A) and which contain interface class // files with a .sig extension. diff --git a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java index fad57166..b86d0c4d 100644 --- a/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java +++ b/java/com/google/turbine/binder/bytecode/BytecodeBoundClass.java @@ -58,6 +58,7 @@ import com.google.turbine.type.Type.ClassTy; import com.google.turbine.type.Type.IntersectionTy; import java.lang.annotation.RetentionPolicy; +import java.nio.file.Path; import java.util.List; import java.util.Map; import org.jspecify.annotations.Nullable; @@ -72,6 +73,20 @@ */ public class BytecodeBoundClass implements TypeBoundClass { + public static Supplier lazy( + ClassSymbol sym, + Supplier bytes, + Env env, + Path path) { + return Suppliers.memoize( + new Supplier() { + @Override + public BytecodeBoundClass get() { + return new BytecodeBoundClass(sym, bytes, env, path.toString()); + } + }); + } + private final ClassSymbol sym; private final Env env; private final Supplier classFile; diff --git a/java/com/google/turbine/zip/Zip.java b/java/com/google/turbine/zip/Zip.java index bf0365b9..95ebb3fa 100644 --- a/java/com/google/turbine/zip/Zip.java +++ b/java/com/google/turbine/zip/Zip.java @@ -18,6 +18,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import com.google.common.base.Supplier; import com.google.common.primitives.UnsignedInts; import java.io.ByteArrayInputStream; import java.io.Closeable; @@ -251,7 +252,7 @@ public void close() throws IOException { } /** An entry in a zip archive. */ - public static class Entry { + public static class Entry implements Supplier { private final Path path; private final FileChannel chan; @@ -351,6 +352,11 @@ private byte[] getBytes( throw new IOError(e); } } + + @Override + public byte[] get() { + return data(); + } } static void checkSignature(