@@ -6,6 +6,8 @@ import org.objectweb.asm.{ClassReader, ClassVisitor, MethodVisitor, Opcodes}
66
77import java .net .URLClassLoader
88
9+ import scala .util .Using
10+
911case class ExternalSummary (
1012 directMethods : Map [JCls , Map [MethodSig , Boolean ]],
1113 directAncestors : Map [JCls , Set [JCls ]],
@@ -27,47 +29,49 @@ object ExternalSummary {
2729 localSummary : LocalSummary ,
2830 upstreamClasspath : Seq [os.Path ]
2931 )(implicit st : SymbolTable ): ExternalSummary = {
30- val upstreamClassloader = mill.util.Jvm .createClassLoader(
32+ def createUpstreamClassloader () = mill.util.Jvm .createClassLoader(
3133 upstreamClasspath,
3234 getClass.getClassLoader
3335 )
3436
35- val allDirectAncestors = localSummary.mapValuesOnly(_.directAncestors).flatten
36-
37- val allMethodCallParamClasses = localSummary
38- .mapValuesOnly(_.methods.values)
39- .flatten
40- .flatMap(_.calls)
41- .flatMap(call => Seq (call.cls) ++ call.desc.args)
42- .collect { case c : JType .Cls => c }
43-
4437 val methodsPerCls = collection.mutable.Map .empty[JCls , Map [MethodSig , Boolean ]]
4538 val ancestorsPerCls = collection.mutable.Map .empty[JCls , Set [JCls ]]
4639 val directSuperclasses = collection.mutable.Map .empty[JCls , JCls ]
4740
48- def load (cls : JCls ): Unit = methodsPerCls.getOrElse(cls, load0(cls))
49-
50- def load0 (cls : JCls ): Unit = {
51- val visitor = new MyClassVisitor ()
52- val resourcePath =
53- os.resource(upstreamClassloader) / os.SubPath (cls.name.replace('.' , '/' ) + " .class" )
54-
55- new ClassReader (os.read.inputStream(resourcePath)).accept(
56- visitor,
57- ClassReader .SKIP_CODE | ClassReader .SKIP_FRAMES | ClassReader .SKIP_DEBUG
58- )
59-
60- directSuperclasses(cls) = visitor.superclass
61- methodsPerCls(cls) = visitor.methods
62- ancestorsPerCls(cls) = visitor.ancestors
63- ancestorsPerCls(cls).foreach(load)
41+ Using .resource(createUpstreamClassloader()) { upstreamClassloader =>
42+ val allDirectAncestors = localSummary.mapValuesOnly(_.directAncestors).flatten
43+
44+ val allMethodCallParamClasses = localSummary
45+ .mapValuesOnly(_.methods.values)
46+ .flatten
47+ .flatMap(_.calls)
48+ .flatMap(call => Seq (call.cls) ++ call.desc.args)
49+ .collect { case c : JType .Cls => c }
50+
51+ def load (cls : JCls ): Unit = methodsPerCls.getOrElse(cls, load0(cls))
52+
53+ def load0 (cls : JCls ): Unit = {
54+ val visitor = new MyClassVisitor ()
55+ val resourcePath =
56+ os.resource(upstreamClassloader) / os.SubPath (cls.name.replace('.' , '/' ) + " .class" )
57+
58+ new ClassReader (os.read.inputStream(resourcePath)).accept(
59+ visitor,
60+ ClassReader .SKIP_CODE | ClassReader .SKIP_FRAMES | ClassReader .SKIP_DEBUG
61+ )
62+
63+ directSuperclasses(cls) = visitor.superclass
64+ methodsPerCls(cls) = visitor.methods
65+ ancestorsPerCls(cls) = visitor.ancestors
66+ ancestorsPerCls(cls).foreach(load)
67+ }
68+
69+ (allDirectAncestors ++ allMethodCallParamClasses)
70+ .filter(! localSummary.contains(_))
71+ .toSet
72+ .foreach(load)
6473 }
6574
66- (allDirectAncestors ++ allMethodCallParamClasses)
67- .filter(! localSummary.contains(_))
68- .toSet
69- .foreach(load)
70-
7175 ExternalSummary (methodsPerCls.toMap, ancestorsPerCls.toMap, directSuperclasses.toMap)
7276 }
7377
0 commit comments