@@ -30,12 +30,15 @@ abstract class ClassfileParser {
3030 import scala .reflect .internal .ClassfileConstants ._
3131 import Flags ._
3232
33+ protected type ThisConstantPool <: ConstantPool
34+ protected def newConstantPool : ThisConstantPool
35+
3336 protected var in : AbstractFileReader = _ // the class file reader
3437 protected var clazz : Symbol = _ // the class symbol containing dynamic members
3538 protected var staticModule : Symbol = _ // the module symbol containing static members
3639 protected var instanceScope : Scope = _ // the scope of all instance definitions
3740 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
3942 protected var isScala : Boolean = _ // does class file describe a scala class?
4043 protected var isScalaAnnot : Boolean = _ // does class file describe a scala class with its pickled info in an annotation?
4144 protected var isScalaRaw : Boolean = _ // this class file is a scala class with no pickled info
@@ -119,7 +122,7 @@ abstract class ClassfileParser {
119122 this .isScala = false
120123
121124 parseHeader()
122- this .pool = new ConstantPool
125+ this .pool = newConstantPool
123126 parseClass()
124127 }
125128 }
@@ -134,11 +137,14 @@ abstract class ClassfileParser {
134137 abort(s " class file ${in.file} has unknown version $major. $minor, should be at least $JAVA_MAJOR_VERSION. $JAVA_MINOR_VERSION" )
135138 }
136139
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)
142148
143149 { var i = 1
144150 while (i < starts.length) {
@@ -212,76 +218,13 @@ abstract class ClassfileParser {
212218 getExternalName((in getChar start).toInt)
213219 }
214220
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-
278221 /** Return a name and a type at the given index. If the type is a method
279222 * type, a dummy symbol is created in `ownerTpe`, which is used as the
280223 * owner of its value parameters. This might lead to inconsistencies,
281224 * if a symbol of the given name already exists, and has a different
282225 * type.
283226 */
284- private def getNameAndType (index : Int , ownerTpe : Type ): (Name , Type ) = {
227+ protected def getNameAndType (index : Int , ownerTpe : Type ): (Name , Type ) = {
285228 if (index <= 0 || len <= index) errorBadIndex(index)
286229 values(index) match {
287230 case p : ((Name @ unchecked, Type @ unchecked)) => p
@@ -381,35 +324,14 @@ abstract class ClassfileParser {
381324 }
382325
383326 /** Throws an exception signaling a bad constant index. */
384- private def errorBadIndex (index : Int ) =
327+ protected def errorBadIndex (index : Int ) =
385328 abort(s " bad constant pool index: $index at pos: ${in.bp}" )
386329
387330 /** Throws an exception signaling a bad tag at given address. */
388- private def errorBadTag (start : Int ) =
331+ protected def errorBadTag (start : Int ) =
389332 abort(" bad constant pool tag ${in.buf(start)} at byte $start" )
390333 }
391334
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-
413335 private def loadClassSymbol (name : Name ): Symbol = {
414336 val file = global.classPath findSourceFile (" " + name) getOrElse {
415337 // SI-5593 Scaladoc's current strategy is to visit all packages in search of user code that can be documented
0 commit comments