@@ -30,12 +30,15 @@ abstract class ClassfileParser {
30
30
import scala .reflect .internal .ClassfileConstants ._
31
31
import Flags ._
32
32
33
+ protected type ThisConstantPool <: ConstantPool
34
+ protected def newConstantPool : ThisConstantPool
35
+
33
36
protected var in : AbstractFileReader = _ // the class file reader
34
37
protected var clazz : Symbol = _ // the class symbol containing dynamic members
35
38
protected var staticModule : Symbol = _ // the module symbol containing static members
36
39
protected var instanceScope : Scope = _ // the scope of all instance definitions
37
40
protected var staticScope : Scope = _ // the scope of all static definitions
38
- protected var pool : ConstantPool = _ // the classfile's constant pool
41
+ protected var pool : ThisConstantPool = _ // the classfile's constant pool
39
42
protected var isScala : Boolean = _ // does class file describe a scala class?
40
43
protected var isScalaAnnot : Boolean = _ // does class file describe a scala class with its pickled info in an annotation?
41
44
protected var isScalaRaw : Boolean = _ // this class file is a scala class with no pickled info
@@ -119,7 +122,7 @@ abstract class ClassfileParser {
119
122
this .isScala = false
120
123
121
124
parseHeader()
122
- this .pool = new ConstantPool
125
+ this .pool = newConstantPool
123
126
parseClass()
124
127
}
125
128
}
@@ -134,11 +137,14 @@ abstract class ClassfileParser {
134
137
abort(s " class file ${in.file} has unknown version $major. $minor, should be at least $JAVA_MAJOR_VERSION. $JAVA_MINOR_VERSION" )
135
138
}
136
139
137
- class ConstantPool {
138
- private val len = u2
139
- private val starts = new Array [Int ](len)
140
- private val values = new Array [AnyRef ](len)
141
- private val internalized = new Array [Name ](len)
140
+ /**
141
+ * Constructor of this class should not be called directly, use `newConstantPool` instead.
142
+ */
143
+ protected class ConstantPool {
144
+ protected val len = u2
145
+ protected val starts = new Array [Int ](len)
146
+ protected val values = new Array [AnyRef ](len)
147
+ protected val internalized = new Array [Name ](len)
142
148
143
149
{ var i = 1
144
150
while (i < starts.length) {
@@ -212,76 +218,13 @@ abstract class ClassfileParser {
212
218
getExternalName((in getChar start).toInt)
213
219
}
214
220
215
- /** Return the symbol of the class member at `index`.
216
- * The following special cases exist:
217
- * - If the member refers to special `MODULE$` static field, return
218
- * the symbol of the corresponding module.
219
- * - If the member is a field, and is not found with the given name,
220
- * another try is made by appending `nme.LOCAL_SUFFIX_STRING`
221
- * - If no symbol is found in the right tpe, a new try is made in the
222
- * companion class, in case the owner is an implementation class.
223
- */
224
- def getMemberSymbol (index : Int , static : Boolean ): Symbol = {
225
- if (index <= 0 || len <= index) errorBadIndex(index)
226
- var f = values(index).asInstanceOf [Symbol ]
227
- if (f eq null ) {
228
- val start = starts(index)
229
- val first = in.buf(start).toInt
230
- if (first != CONSTANT_FIELDREF &&
231
- first != CONSTANT_METHODREF &&
232
- first != CONSTANT_INTFMETHODREF ) errorBadTag(start)
233
- val ownerTpe = getClassOrArrayType(in.getChar(start + 1 ).toInt)
234
- debuglog(" getMemberSymbol(static: " + static + " ): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.originalName)
235
- val (name0, tpe0) = getNameAndType(in.getChar(start + 3 ).toInt, ownerTpe)
236
- debuglog(" getMemberSymbol: name and tpe: " + name0 + " : " + tpe0)
237
-
238
- forceMangledName(tpe0.typeSymbol.name, module = false )
239
- val (name, tpe) = getNameAndType(in.getChar(start + 3 ).toInt, ownerTpe)
240
- if (name == nme.MODULE_INSTANCE_FIELD ) {
241
- val index = in.getChar(start + 1 ).toInt
242
- val name = getExternalName(in.getChar(starts(index).toInt + 1 ).toInt)
243
- // assert(name.endsWith("$"), "Not a module class: " + name)
244
- f = forceMangledName(name dropRight 1 , module = true )
245
- if (f == NoSymbol )
246
- f = rootMirror.getModuleByName(name dropRight 1 )
247
- } else {
248
- val origName = nme.unexpandedName(name)
249
- val owner = if (static) ownerTpe.typeSymbol.linkedClassOfClass else ownerTpe.typeSymbol
250
- f = owner.info.findMember(origName, 0 , 0 , stableOnly = false ).suchThat(_.tpe.widen =:= tpe)
251
- if (f == NoSymbol )
252
- f = owner.info.findMember(newTermName(origName + nme.LOCAL_SUFFIX_STRING ), 0 , 0 , stableOnly = false ).suchThat(_.tpe =:= tpe)
253
- if (f == NoSymbol ) {
254
- // if it's an impl class, try to find it's static member inside the class
255
- if (ownerTpe.typeSymbol.isImplClass) {
256
- f = ownerTpe.findMember(origName, 0 , 0 , stableOnly = false ).suchThat(_.tpe =:= tpe)
257
- } else {
258
- log(" Couldn't find " + name + " : " + tpe + " inside: \n " + ownerTpe)
259
- f = tpe match {
260
- case MethodType (_, _) => owner.newMethod(name.toTermName, owner.pos)
261
- case _ => owner.newVariable(name.toTermName, owner.pos)
262
- }
263
- f setInfo tpe
264
- log(" created fake member " + f.fullName)
265
- }
266
- }
267
- }
268
- assert(f != NoSymbol ,
269
- s " could not find $name: $tpe in $ownerTpe" + (
270
- if (settings.debug.value) ownerTpe.members.mkString(" , members are:\n " , " \n " , " " ) else " "
271
- )
272
- )
273
- values(index) = f
274
- }
275
- f
276
- }
277
-
278
221
/** Return a name and a type at the given index. If the type is a method
279
222
* type, a dummy symbol is created in `ownerTpe`, which is used as the
280
223
* owner of its value parameters. This might lead to inconsistencies,
281
224
* if a symbol of the given name already exists, and has a different
282
225
* type.
283
226
*/
284
- private def getNameAndType (index : Int , ownerTpe : Type ): (Name , Type ) = {
227
+ protected def getNameAndType (index : Int , ownerTpe : Type ): (Name , Type ) = {
285
228
if (index <= 0 || len <= index) errorBadIndex(index)
286
229
values(index) match {
287
230
case p : ((Name @ unchecked, Type @ unchecked)) => p
@@ -381,35 +324,14 @@ abstract class ClassfileParser {
381
324
}
382
325
383
326
/** Throws an exception signaling a bad constant index. */
384
- private def errorBadIndex (index : Int ) =
327
+ protected def errorBadIndex (index : Int ) =
385
328
abort(s " bad constant pool index: $index at pos: ${in.bp}" )
386
329
387
330
/** Throws an exception signaling a bad tag at given address. */
388
- private def errorBadTag (start : Int ) =
331
+ protected def errorBadTag (start : Int ) =
389
332
abort(" bad constant pool tag ${in.buf(start)} at byte $start" )
390
333
}
391
334
392
- /** Try to force the chain of enclosing classes for the given name. Otherwise
393
- * flatten would not lift classes that were not referenced in the source code.
394
- */
395
- def forceMangledName (name : Name , module : Boolean ): Symbol = {
396
- val parts = name.decode.toString.split(Array ('.' , '$' ))
397
- var sym : Symbol = rootMirror.RootClass
398
-
399
- // was "at flatten.prev"
400
- enteringFlatten {
401
- for (part0 <- parts; if ! (part0 == " " ); part = newTermName(part0)) {
402
- val sym1 = enteringIcode {
403
- sym.linkedClassOfClass.info
404
- sym.info.decl(part.encode)
405
- }// .suchThat(module == _.isModule)
406
-
407
- sym = sym1 orElse sym.info.decl(part.encode.toTypeName)
408
- }
409
- }
410
- sym
411
- }
412
-
413
335
private def loadClassSymbol (name : Name ): Symbol = {
414
336
val file = global.classPath findSourceFile (" " + name) getOrElse {
415
337
// SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
0 commit comments