1717package com .google .turbine .binder ;
1818
1919import com .google .common .base .Supplier ;
20- import com .google .common .base .Suppliers ;
2120import com .google .common .collect .ImmutableMap ;
2221import com .google .turbine .binder .bound .ModuleInfo ;
2322import com .google .turbine .binder .bytecode .BytecodeBinder ;
3534import java .util .HashMap ;
3635import java .util .LinkedHashMap ;
3736import java .util .Map ;
38- import java .util .function .Function ;
3937import org .jspecify .annotations .Nullable ;
4038
4139/** Sets up an environment for symbols on the classpath. */
@@ -55,33 +53,31 @@ public final class ClassPathBinder {
5553
5654 /** Creates an environment containing symbols in the given classpath. */
5755 public static ClassPath bindClasspath (Collection <Path > paths ) throws IOException {
58- // TODO(cushon): this is going to require an env eventually,
59- // e.g. to look up type parameters in enclosing declarations
60- Map <ClassSymbol , BytecodeBoundClass > transitive = new LinkedHashMap <>();
61- Map <ClassSymbol , BytecodeBoundClass > map = new HashMap <>();
56+ Map <ClassSymbol , Supplier <BytecodeBoundClass >> transitive = new LinkedHashMap <>();
57+ Map <ClassSymbol , Supplier <BytecodeBoundClass >> map = new HashMap <>();
6258 Map <ModuleSymbol , ModuleInfo > modules = new HashMap <>();
6359 Map <String , Supplier <byte []>> resources = new HashMap <>();
64- Env <ClassSymbol , BytecodeBoundClass > benv =
60+ Env <ClassSymbol , BytecodeBoundClass > env =
6561 new Env <ClassSymbol , BytecodeBoundClass >() {
6662 @ Override
6763 public @ Nullable BytecodeBoundClass get (ClassSymbol sym ) {
68- return map .get (sym );
64+ Supplier <BytecodeBoundClass > supplier = map .get (sym );
65+ return supplier == null ? null : supplier .get ();
6966 }
7067 };
7168 for (Path path : paths ) {
7269 try {
73- bindJar (path , map , modules , benv , transitive , resources );
70+ bindJar (path , map , modules , env , transitive , resources );
7471 } catch (IOException e ) {
7572 throw new IOException ("error reading " + path , e );
7673 }
7774 }
78- for (Map .Entry <ClassSymbol , BytecodeBoundClass > entry : transitive .entrySet ()) {
75+ for (Map .Entry <ClassSymbol , Supplier < BytecodeBoundClass > > entry : transitive .entrySet ()) {
7976 ClassSymbol symbol = entry .getKey ();
8077 map .putIfAbsent (symbol , entry .getValue ());
8178 }
82- SimpleEnv <ClassSymbol , BytecodeBoundClass > env = new SimpleEnv <>(ImmutableMap .copyOf (map ));
8379 SimpleEnv <ModuleSymbol , ModuleInfo > moduleEnv = new SimpleEnv <>(ImmutableMap .copyOf (modules ));
84- TopLevelIndex index = SimpleTopLevelIndex .of (env . asMap () .keySet ());
80+ TopLevelIndex index = SimpleTopLevelIndex .of (map .keySet ());
8581 return new ClassPath () {
8682 @ Override
8783 public Env <ClassSymbol , BytecodeBoundClass > env () {
@@ -107,10 +103,10 @@ public TopLevelIndex index() {
107103
108104 private static void bindJar (
109105 Path path ,
110- Map <ClassSymbol , BytecodeBoundClass > env ,
106+ Map <ClassSymbol , Supplier < BytecodeBoundClass > > env ,
111107 Map <ModuleSymbol , ModuleInfo > modules ,
112108 Env <ClassSymbol , BytecodeBoundClass > benv ,
113- Map <ClassSymbol , BytecodeBoundClass > transitive ,
109+ Map <ClassSymbol , Supplier < BytecodeBoundClass > > transitive ,
114110 Map <String , Supplier <byte []>> resources )
115111 throws IOException {
116112 // TODO(cushon): don't leak file descriptors
@@ -124,41 +120,22 @@ private static void bindJar(
124120 new ClassSymbol (
125121 name .substring (
126122 TRANSITIVE_PREFIX .length (), name .length () - TRANSITIVE_SUFFIX .length ()));
127- transitive .computeIfAbsent (
128- sym ,
129- new Function <ClassSymbol , BytecodeBoundClass >() {
130- @ Override
131- public BytecodeBoundClass apply (ClassSymbol sym ) {
132- return new BytecodeBoundClass (sym , toByteArrayOrDie (ze ), benv , path .toString ());
133- }
134- });
123+ transitive .putIfAbsent (sym , BytecodeBoundClass .lazy (sym , ze , benv , path ));
135124 continue ;
136125 }
137126 if (!name .endsWith (".class" )) {
138- resources .put (name , toByteArrayOrDie ( ze ) );
127+ resources .put (name , ze );
139128 continue ;
140129 }
141130 if (name .substring (name .lastIndexOf ('/' ) + 1 ).equals ("module-info.class" )) {
142- ModuleInfo moduleInfo =
143- BytecodeBinder .bindModuleInfo (path .toString (), toByteArrayOrDie (ze ));
131+ ModuleInfo moduleInfo = BytecodeBinder .bindModuleInfo (path .toString (), ze );
144132 modules .put (new ModuleSymbol (moduleInfo .name ()), moduleInfo );
145133 continue ;
146134 }
147135 ClassSymbol sym = new ClassSymbol (name .substring (0 , name .length () - ".class" .length ()));
148- env .putIfAbsent (
149- sym , new BytecodeBoundClass (sym , toByteArrayOrDie (ze ), benv , path .toString ()));
136+ env .putIfAbsent (sym , BytecodeBoundClass .lazy (sym , ze , benv , path ));
150137 }
151138 }
152139
153- private static Supplier <byte []> toByteArrayOrDie (Zip .Entry ze ) {
154- return Suppliers .memoize (
155- new Supplier <byte []>() {
156- @ Override
157- public byte [] get () {
158- return ze .data ();
159- }
160- });
161- }
162-
163140 private ClassPathBinder () {}
164141}
0 commit comments