@@ -13,22 +13,32 @@ import scala.collection.convert.decorateAsScala._
1313import scala .tools .nsc .io .AbstractFile
1414import scala .tools .nsc .util .ClassFileLookup
1515import OptimizerReporting ._
16+ import ByteCodeRepository ._
17+ import BTypes .InternalName
1618
17- class CodeRepository (val classPath : ClassFileLookup [AbstractFile ]) {
18- import BTypes .InternalName
19-
19+ /**
20+ * The ByteCodeRepository provides utilities to read the bytecode of classfiles from the compilation
21+ * classpath. Parsed classes are cached in the `classes` map.
22+ *
23+ * @param classPath The compiler classpath where classfiles are searched and read from.
24+ * @param classes Cache for parsed ClassNodes. Also stores the source of the bytecode:
25+ * [[Classfile ]] if read from `classPath`, [[CompilationUnit ]] if the bytecode
26+ * corresponds to a class being compiled.
27+ */
28+ class ByteCodeRepository (val classPath : ClassFileLookup [AbstractFile ], val classes : collection.concurrent.Map [InternalName , (ClassNode , Source )]) {
2029 /**
21- * Cache for parsed ClassNodes.
30+ * The class node and source for an internal name. If the class node is not yet available, it is
31+ * parsed from the classfile on the compile classpath.
2232 */
23- val classes : collection.concurrent.Map [InternalName , ClassNode ] = collection.concurrent.TrieMap .empty[InternalName , ClassNode ]
33+ def classNodeAndSource (internalName : InternalName ): (ClassNode , Source ) = {
34+ classes.getOrElseUpdate(internalName, (parseClass(internalName), Classfile ))
35+ }
2436
2537 /**
2638 * The class node for an internal name. If the class node is not yet available, it is parsed from
2739 * the classfile on the compile classpath.
2840 */
29- def classNode (internalName : InternalName ): ClassNode = {
30- classes.getOrElseUpdate(internalName, parseClass(internalName))
31- }
41+ def classNode (internalName : InternalName ) = classNodeAndSource(internalName)._1
3242
3343 /**
3444 * The field node for a field matching `name` and `descriptor`, accessed in class `classInternalName`.
@@ -74,7 +84,6 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) {
7484 // http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.11
7585 // https://jcp.org/aboutJava/communityprocess/final/jsr045/index.html
7686 removeLineNumberNodes(classNode)
77- classes(internalName) = classNode
7887 classNode
7988 } getOrElse {
8089 inlineFailure(s " Class file for class $fullName not found. " )
@@ -91,3 +100,13 @@ class CodeRepository(val classPath: ClassFileLookup[AbstractFile]) {
91100 }
92101 }
93102}
103+
104+ object ByteCodeRepository {
105+ /**
106+ * The source of a ClassNode in the ByteCodeRepository. Can be either [[CompilationUnit ]] if the
107+ * class is being compiled or [[Classfile ]] if the class was parsed from the compilation classpath.
108+ */
109+ sealed trait Source
110+ object CompilationUnit extends Source
111+ object Classfile extends Source
112+ }
0 commit comments