@@ -62,8 +62,6 @@ class ClassfileParser(
62
62
import ClassfileConstants ._
63
63
import ClassfileParser ._
64
64
65
- protected var in : DataReader = _
66
-
67
65
protected val staticModule : Symbol = moduleRoot.sourceModule(using ictx)
68
66
69
67
protected val instanceScope : MutableScope = newScope // the scope of all instance definitions
@@ -84,7 +82,7 @@ class ClassfileParser(
84
82
throw new IOException (s " class file ' ${classfile.canonicalPath}' has location not matching its contents: contains class $className" )
85
83
86
84
def run ()(using Context ): Option [Embedded ] = try ctx.base.reusableDataReader.using { reader =>
87
- this .in = reader.reset(classfile)
85
+ implicit val in : DataReader = reader.reset(classfile)
88
86
89
87
report.debuglog(" [class] >> " + classRoot.fullName)
90
88
parseHeader()
@@ -93,13 +91,13 @@ class ClassfileParser(
93
91
}
94
92
catch {
95
93
case e : RuntimeException =>
96
- if (ctx.debug) e.printStackTrace()
94
+ e.printStackTrace()
97
95
throw new IOException (
98
96
i """ class file ${classfile.canonicalPath} is broken, reading aborted with ${e.getClass}
99
97
| ${Option (e.getMessage).getOrElse(" " )}""" )
100
98
}
101
99
102
- private def parseHeader (): Unit = {
100
+ private def parseHeader ()( using in : DataReader ) : Unit = {
103
101
val magic = in.nextInt
104
102
if (magic != JAVA_MAGIC )
105
103
throw new IOException (s " class file ' ${classfile}' has wrong magic number 0x ${toHexString(magic)}, should be 0x ${toHexString(JAVA_MAGIC )}" )
@@ -120,7 +118,7 @@ class ClassfileParser(
120
118
121
119
var sawPrivateConstructor : Boolean = false
122
120
123
- def parseClass ()(using Context ): Option [Embedded ] = {
121
+ def parseClass ()(using ctx : Context , in : DataReader ): Option [Embedded ] = {
124
122
val jflags = in.nextChar
125
123
val isAnnotation = hasAnnotation(jflags)
126
124
val sflags = classTranslation.flags(jflags)
@@ -220,7 +218,7 @@ class ClassfileParser(
220
218
}
221
219
}
222
220
223
- def parseMember (method : Boolean )(using Context ): Unit = {
221
+ def parseMember (method : Boolean )(using ctx : Context , in : DataReader ): Unit = {
224
222
val start = indexCoord(in.bp)
225
223
val jflags = in.nextChar
226
224
val sflags =
@@ -241,70 +239,67 @@ class ClassfileParser(
241
239
val memberCompleter : LazyType = new LazyType {
242
240
243
241
def complete (denot : SymDenotation )(using Context ): Unit = ctx.base.reusableDataReader.using { reader =>
244
- val oldIn = in
245
- in = reader.reset(classfile)
246
- try {
247
- in.bp = denot.symbol.coord.toIndex
248
- val sym = denot.symbol
249
- val jflags = in.nextChar
250
- val isEnum = (jflags & JAVA_ACC_ENUM ) != 0
251
- val name = pool.getName(in.nextChar)
252
- val isConstructor = name eq nme.CONSTRUCTOR
253
-
254
- /** Strip leading outer param from constructor and trailing access tag for
255
- * private inner constructors.
256
- */
257
- def normalizeConstructorParams () = innerClasses.get(currentClassName) match {
258
- case Some (entry) if ! isStatic(entry.jflags) =>
259
- val mt @ MethodTpe (paramNames, paramTypes, resultType) = denot.info
260
- var normalizedParamNames = paramNames.tail
261
- var normalizedParamTypes = paramTypes.tail
262
- if ((jflags & JAVA_ACC_SYNTHETIC ) != 0 ) {
263
- // SI-7455 strip trailing dummy argument ("access constructor tag") from synthetic constructors which
264
- // are added when an inner class needs to access a private constructor.
265
- normalizedParamNames = paramNames.dropRight(1 )
266
- normalizedParamTypes = paramTypes.dropRight(1 )
267
- }
268
- denot.info = mt.derivedLambdaType(normalizedParamNames, normalizedParamTypes, resultType)
269
- case _ =>
270
- }
242
+ implicit val in : DataReader = reader.reset(classfile)
271
243
272
- /** Make return type of constructor be the enclosing class type,
273
- * and make constructor type polymorphic in the type parameters of the class
274
- */
275
- def normalizeConstructorInfo () = {
276
- val rt = classRoot.typeRef appliedTo (classRoot.typeParams map (_.typeRef))
277
-
278
- def resultType (tpe : Type ): Type = tpe match {
279
- case mt @ MethodType (paramNames) => mt.derivedLambdaType(paramNames, mt.paramInfos, rt)
280
- case pt : PolyType => pt.derivedLambdaType(pt.paramNames, pt.paramInfos, resultType(pt.resType))
244
+ in.bp = denot.symbol.coord.toIndex
245
+ val sym = denot.symbol
246
+ val jflags = in.nextChar
247
+ val isEnum = (jflags & JAVA_ACC_ENUM ) != 0
248
+ val name = pool.getName(in.nextChar)
249
+ val isConstructor = name eq nme.CONSTRUCTOR
250
+
251
+ /** Strip leading outer param from constructor and trailing access tag for
252
+ * private inner constructors.
253
+ */
254
+ def normalizeConstructorParams () = innerClasses.get(currentClassName) match {
255
+ case Some (entry) if ! isStatic(entry.jflags) =>
256
+ val mt @ MethodTpe (paramNames, paramTypes, resultType) = denot.info
257
+ var normalizedParamNames = paramNames.tail
258
+ var normalizedParamTypes = paramTypes.tail
259
+ if ((jflags & JAVA_ACC_SYNTHETIC ) != 0 ) {
260
+ // SI-7455 strip trailing dummy argument ("access constructor tag") from synthetic constructors which
261
+ // are added when an inner class needs to access a private constructor.
262
+ normalizedParamNames = paramNames.dropRight(1 )
263
+ normalizedParamTypes = paramTypes.dropRight(1 )
281
264
}
265
+ denot.info = mt.derivedLambdaType(normalizedParamNames, normalizedParamTypes, resultType)
266
+ case _ =>
267
+ }
282
268
283
- denot.info = resultType(denot.info)
284
- addConstructorTypeParams(denot)
269
+ /** Make return type of constructor be the enclosing class type,
270
+ * and make constructor type polymorphic in the type parameters of the class
271
+ */
272
+ def normalizeConstructorInfo () = {
273
+ val rt = classRoot.typeRef appliedTo (classRoot.typeParams map (_.typeRef))
274
+
275
+ def resultType (tpe : Type ): Type = tpe match {
276
+ case mt @ MethodType (paramNames) => mt.derivedLambdaType(paramNames, mt.paramInfos, rt)
277
+ case pt : PolyType => pt.derivedLambdaType(pt.paramNames, pt.paramInfos, resultType(pt.resType))
285
278
}
286
279
287
- val isVarargs = denot.is(Flags .Method ) && (jflags & JAVA_ACC_VARARGS ) != 0
288
- denot.info = pool.getType(in.nextChar, isVarargs)
289
- if (isConstructor) normalizeConstructorParams()
290
- denot.info = translateTempPoly(parseAttributes(sym, denot.info, isVarargs))
291
- if (isConstructor) normalizeConstructorInfo()
280
+ denot.info = resultType(denot.info)
281
+ addConstructorTypeParams(denot)
282
+ }
292
283
293
- if (ctx.explicitNulls) denot.info = JavaNullInterop .nullifyMember(denot.symbol, denot.info, isEnum)
284
+ val isVarargs = denot.is(Flags .Method ) && (jflags & JAVA_ACC_VARARGS ) != 0
285
+ denot.info = pool.getType(in.nextChar, isVarargs)
286
+ if (isConstructor) normalizeConstructorParams()
287
+ denot.info = translateTempPoly(parseAttributes(sym, denot.info, isVarargs))
288
+ if (isConstructor) normalizeConstructorInfo()
294
289
295
- // seal java enums
296
- if (isEnum) {
297
- val enumClass = sym.owner.linkedClass
298
- if (! enumClass.exists)
299
- report.warning(s " no linked class for java enum $sym in ${sym.owner}. A referencing class file might be missing an InnerClasses entry. " )
300
- else {
301
- if (! enumClass.is(Flags .Sealed )) enumClass.setFlag(Flags .AbstractSealed )
302
- enumClass.addAnnotation(Annotation .Child (sym, NoSpan ))
303
- }
290
+ if (ctx.explicitNulls) denot.info = JavaNullInterop .nullifyMember(denot.symbol, denot.info, isEnum)
291
+
292
+ // seal java enums
293
+ if (isEnum) {
294
+ val enumClass = sym.owner.linkedClass
295
+ if (! enumClass.exists)
296
+ report.warning(s " no linked class for java enum $sym in ${sym.owner}. A referencing class file might be missing an InnerClasses entry. " )
297
+ else {
298
+ if (! enumClass.is(Flags .Sealed )) enumClass.setFlag(Flags .AbstractSealed )
299
+ enumClass.addAnnotation(Annotation .Child (sym, NoSpan ))
304
300
}
305
301
}
306
- finally
307
- in = oldIn
302
+
308
303
}
309
304
}
310
305
@@ -504,7 +499,7 @@ class ClassfileParser(
504
499
}
505
500
// sigToType
506
501
507
- def parseAnnotArg (skip : Boolean = false )(using Context ): Option [untpd.Tree ] = {
502
+ def parseAnnotArg (skip : Boolean = false )(using ctx : Context , in : DataReader ): Option [untpd.Tree ] = {
508
503
509
504
// If we encounter an empty array literal, we need the type of the corresponding
510
505
// parameter to properly type it, but that would require forcing the annotation
@@ -569,7 +564,7 @@ class ClassfileParser(
569
564
/** Parse and return a single annotation. If it is malformed,
570
565
* return None.
571
566
*/
572
- def parseAnnotation (attrNameIndex : Char , skip : Boolean = false )(using Context ): Option [ClassfileAnnotation ] = try {
567
+ def parseAnnotation (attrNameIndex : Char , skip : Boolean = false )(using ctx : Context , in : DataReader ): Option [ClassfileAnnotation ] = try {
573
568
val attrType = pool.getType(attrNameIndex)
574
569
attrType match
575
570
case tp : TypeRef =>
@@ -608,7 +603,7 @@ class ClassfileParser(
608
603
None // ignore malformed annotations
609
604
}
610
605
611
- def parseAttributes (sym : Symbol , symtype : Type , isVarargs : Boolean = false )(using Context ): Type = {
606
+ def parseAttributes (sym : Symbol , symtype : Type , isVarargs : Boolean = false )(using ctx : Context , in : DataReader ): Type = {
612
607
var newType = symtype
613
608
614
609
def parseAttribute (): Unit = {
@@ -749,7 +744,7 @@ class ClassfileParser(
749
744
* Restores the old `bp`.
750
745
* @return true iff classfile is from Scala, so no Java info needs to be read.
751
746
*/
752
- def unpickleOrParseInnerClasses ()(using Context ): Option [Embedded ] = {
747
+ def unpickleOrParseInnerClasses ()(using ctx : Context , in : DataReader ): Option [Embedded ] = {
753
748
val oldbp = in.bp
754
749
try {
755
750
skipSuperclasses()
@@ -985,21 +980,21 @@ class ClassfileParser(
985
980
}
986
981
}
987
982
988
- def skipAttributes (): Unit = {
983
+ def skipAttributes ()( using in : DataReader ) : Unit = {
989
984
val attrCount = in.nextChar
990
985
for (i <- 0 until attrCount) {
991
986
in.skip(2 ); in.skip(in.nextInt)
992
987
}
993
988
}
994
989
995
- def skipMembers (): Unit = {
990
+ def skipMembers ()( using in : DataReader ) : Unit = {
996
991
val memberCount = in.nextChar
997
992
for (i <- 0 until memberCount) {
998
993
in.skip(6 ); skipAttributes()
999
994
}
1000
995
}
1001
996
1002
- def skipSuperclasses (): Unit = {
997
+ def skipSuperclasses ()( using in : DataReader ) : Unit = {
1003
998
in.skip(2 ) // superclass
1004
999
val ifaces = in.nextChar
1005
1000
in.skip(2 * ifaces)
@@ -1035,7 +1030,7 @@ class ClassfileParser(
1035
1030
requiredModule(name.dropRight(1 ))
1036
1031
else classNameToSymbol(name)
1037
1032
1038
- class ConstantPool {
1033
+ class ConstantPool ( using in : DataReader ) {
1039
1034
private val len = in.nextChar
1040
1035
private val starts = new Array [Int ](len)
1041
1036
private val values = new Array [AnyRef ](len)
0 commit comments