@@ -4,7 +4,7 @@ package core
4
4
package pickling
5
5
6
6
import Contexts ._ , Symbols ._ , Types ._ , Names ._ , StdNames ._ , NameOps ._ , Scopes ._ , Decorators ._
7
- import SymDenotations ._ , UnPickler ._ , Constants ._ , Annotations ._ , util .Positions ._
7
+ import SymDenotations ._ , Scala2Unpickler ._ , Constants ._ , Annotations ._ , util .Positions ._
8
8
import ast .tpd ._
9
9
import java .io .{ File , IOException }
10
10
import java .lang .Integer .toHexString
@@ -15,12 +15,18 @@ import typer.Checking.checkNonCyclic
15
15
import io .AbstractFile
16
16
import scala .util .control .NonFatal
17
17
18
+ object ClassfileParser {
19
+ /** Marker trait for unpicklers that can be embedded in classfiles. */
20
+ trait Embedded
21
+ }
22
+
18
23
class ClassfileParser (
19
24
classfile : AbstractFile ,
20
25
classRoot : ClassDenotation ,
21
26
moduleRoot : ClassDenotation )(ictx : Context ) {
22
27
23
28
import ClassfileConstants ._
29
+ import ClassfileParser ._
24
30
25
31
protected val in = new AbstractFileReader (classfile)
26
32
@@ -41,7 +47,7 @@ class ClassfileParser(
41
47
private def mismatchError (c : Symbol ) =
42
48
throw new IOException (s " class file ' ${in.file}' has location not matching its contents: contains $c" )
43
49
44
- def run ()(implicit ctx : Context ): Unit = try {
50
+ def run ()(implicit ctx : Context ): Option [ Embedded ] = try {
45
51
ctx.debuglog(" [class] >> " + classRoot.fullName)
46
52
parseHeader
47
53
this .pool = new ConstantPool
@@ -80,7 +86,7 @@ class ClassfileParser(
80
86
81
87
var sawPrivateConstructor = false
82
88
83
- def parseClass ()(implicit ctx : Context ): Unit = {
89
+ def parseClass ()(implicit ctx : Context ): Option [ Embedded ] = {
84
90
val jflags = in.nextChar
85
91
val isAnnotation = hasAnnotation(jflags)
86
92
val sflags = FlagTranslation .classFlags(jflags)
@@ -94,8 +100,6 @@ class ClassfileParser(
94
100
95
101
addEnclosingTParams()
96
102
97
- if (unpickleOrParseInnerClasses()) return
98
-
99
103
/** Parse parents for Java classes. For Scala, return AnyRef, since the real type will be unpickled.
100
104
* Updates the read pointer of 'in'. */
101
105
def parseParents : List [Type ] = {
@@ -114,33 +118,36 @@ class ClassfileParser(
114
118
superType :: ifaces
115
119
}
116
120
117
- var classInfo : Type = TempClassInfoType (parseParents, instanceScope, classRoot.symbol)
121
+ val result = unpickleOrParseInnerClasses()
122
+ if (! result.isDefined) {
123
+ var classInfo : Type = TempClassInfoType (parseParents, instanceScope, classRoot.symbol)
118
124
// might be reassigned by later parseAttributes
119
- val staticInfo = TempClassInfoType (List (), staticScope, moduleRoot.symbol)
125
+ val staticInfo = TempClassInfoType (List (), staticScope, moduleRoot.symbol)
120
126
121
- enterOwnInnerClasses
127
+ enterOwnInnerClasses
122
128
123
- classRoot.setFlag(sflags)
124
- moduleRoot.setFlag(Flags .JavaDefined | Flags .ModuleClassCreationFlags )
125
- setPrivateWithin(classRoot, jflags)
126
- setPrivateWithin(moduleRoot, jflags)
127
- setPrivateWithin(moduleRoot.sourceModule, jflags)
129
+ classRoot.setFlag(sflags)
130
+ moduleRoot.setFlag(Flags .JavaDefined | Flags .ModuleClassCreationFlags )
131
+ setPrivateWithin(classRoot, jflags)
132
+ setPrivateWithin(moduleRoot, jflags)
133
+ setPrivateWithin(moduleRoot.sourceModule, jflags)
128
134
129
- for (i <- 0 until in.nextChar) parseMember(method = false )
130
- for (i <- 0 until in.nextChar) parseMember(method = true )
131
- classInfo = parseAttributes(classRoot.symbol, classInfo)
132
- if (isAnnotation) addAnnotationConstructor(classInfo)
135
+ for (i <- 0 until in.nextChar) parseMember(method = false )
136
+ for (i <- 0 until in.nextChar) parseMember(method = true )
137
+ classInfo = parseAttributes(classRoot.symbol, classInfo)
138
+ if (isAnnotation) addAnnotationConstructor(classInfo)
133
139
134
- val companionClassMethod = ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD , classRoot, moduleRoot)
135
- if (companionClassMethod.exists) companionClassMethod.entered
136
- val companionModuleMethod = ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD , moduleRoot, classRoot)
137
- if (companionModuleMethod.exists) companionModuleMethod.entered
140
+ val companionClassMethod = ctx.synthesizeCompanionMethod(nme.COMPANION_CLASS_METHOD , classRoot, moduleRoot)
141
+ if (companionClassMethod.exists) companionClassMethod.entered
142
+ val companionModuleMethod = ctx.synthesizeCompanionMethod(nme.COMPANION_MODULE_METHOD , moduleRoot, classRoot)
143
+ if (companionModuleMethod.exists) companionModuleMethod.entered
138
144
139
- setClassInfo(classRoot, classInfo)
140
- setClassInfo(moduleRoot, staticInfo)
145
+ setClassInfo(classRoot, classInfo)
146
+ setClassInfo(moduleRoot, staticInfo)
147
+ }
148
+ result
141
149
}
142
150
143
-
144
151
/** Add type parameters of enclosing classes */
145
152
def addEnclosingTParams ()(implicit ctx : Context ): Unit = {
146
153
var sym = classRoot.owner
@@ -644,7 +651,7 @@ class ClassfileParser(
644
651
* Restores the old `bp`.
645
652
* @return true iff classfile is from Scala, so no Java info needs to be read.
646
653
*/
647
- def unpickleOrParseInnerClasses ()(implicit ctx : Context ): Boolean = {
654
+ def unpickleOrParseInnerClasses ()(implicit ctx : Context ): Option [ Embedded ] = {
648
655
val oldbp = in.bp
649
656
try {
650
657
skipSuperclasses()
@@ -664,15 +671,16 @@ class ClassfileParser(
664
671
i < attrs
665
672
}
666
673
667
- def unpickleScala (bytes : Array [Byte ]): Boolean = {
668
- new UnPickler (bytes, classRoot, moduleRoot)(ctx).run()
669
- true
674
+ def unpickleScala (bytes : Array [Byte ]): Some [Embedded ] = {
675
+ val unpickler = new Scala2Unpickler (bytes, classRoot, moduleRoot)(ctx)
676
+ unpickler.run()
677
+ Some (unpickler)
670
678
}
671
679
672
- def unpickleTASTY (bytes : Array [Byte ]): Boolean = {
673
- new DottyUnpickler (bytes)
674
- .enter(roots = Set (classRoot, moduleRoot, moduleRoot.sourceModule))
675
- true
680
+ def unpickleTASTY (bytes : Array [Byte ]): Some [ Embedded ] = {
681
+ val unpickler = new DottyUnpickler (bytes)
682
+ unpickler .enter(roots = Set (classRoot, moduleRoot, moduleRoot.sourceModule))
683
+ Some (unpickler)
676
684
}
677
685
678
686
def parseScalaSigBytes : Array [Byte ] = {
@@ -739,7 +747,7 @@ class ClassfileParser(
739
747
}
740
748
}
741
749
}
742
- false
750
+ None
743
751
} finally in.bp = oldbp
744
752
}
745
753
0 commit comments