summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-08-15 09:25:53 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-08-15 09:25:53 +0000
commit6d236c4abdfbb0af8867a64461f69b9eecbeb279 (patch)
treeb0cdfd5c3d3684a2da86f8e86b1b5074ff5a6f1c /src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
parent6f141280bf6d375151f497e6e4ee0ff601d53ac0 (diff)
downloadscala-6d236c4abdfbb0af8867a64461f69b9eecbeb279.tar.gz
scala-6d236c4abdfbb0af8867a64461f69b9eecbeb279.tar.bz2
scala-6d236c4abdfbb0af8867a64461f69b9eecbeb279.zip
Added InnerClasses attribute in classfiles
Diffstat (limited to 'src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala80
1 files changed, 62 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index a9e0daae5d..34f68f9f67 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -37,18 +37,18 @@ abstract class ClassfileParser {
import ClassfileConstants._
import Flags._
- private var in: AbstractFileReader = _ // the class file
- private var clazz: Symbol = _ // the class symbol containing dynamic members
- private var staticModule: Symbol = _ // the module symbol containing static members
- private var instanceDefs: Scope = _ // the scope of all instance definitions
- private var staticDefs: Scope = _ // the scope of all static definitions
- private var pool: ConstantPool = _ // the classfile's constant pool
- private var isScala: boolean = _ // does class file describe a scala class?
- private var hasMeta: boolean = _ // does class file contain jaco meta attribute?s
- private var busy: boolean = false // lock to detect recursive reads
- private var classTParams: Map[Name,Symbol] =
+ protected var in: AbstractFileReader = _ // the class file reader
+ protected var clazz: Symbol = _ // the class symbol containing dynamic members
+ protected var staticModule: Symbol = _ // the module symbol containing static members
+ protected var instanceDefs: Scope = _ // the scope of all instance definitions
+ protected var staticDefs: Scope = _ // the scope of all static definitions
+ protected var pool: ConstantPool = _ // the classfile's constant pool
+ protected var isScala: boolean = _ // does class file describe a scala class?
+ protected var hasMeta: boolean = _ // does class file contain jaco meta attribute?s
+ protected var busy: boolean = false // lock to detect recursive reads
+ protected var classTParams: Map[Name,Symbol] =
collection.immutable.ListMap.Empty[Name,Symbol]
- private val fresh = new scala.tools.nsc.util.FreshNameCreator
+ protected val fresh = new scala.tools.nsc.util.FreshNameCreator
private object metaParser extends MetaParser {
val global: ClassfileParser.this.global.type = ClassfileParser.this.global
@@ -65,6 +65,10 @@ abstract class ClassfileParser {
}
assert(!busy)
busy = true
+ if (root.isInstanceOf[ClassSymbol]) {
+ root.asInstanceOf[ClassSymbol].classFile = file
+ }
+
this.in = new AbstractFileReader(file)
if (root.isModule) {
this.clazz = root.linkedClass
@@ -86,7 +90,7 @@ abstract class ClassfileParser {
busy = false
}
- private def statics: Symbol = staticModule.moduleClass
+ protected def statics: Symbol = staticModule.moduleClass
private def parseHeader: unit = {
val magic = in.nextInt
@@ -168,6 +172,44 @@ abstract class ClassfileParser {
c
}
+ def getMemberSymbol(index: Int, static: Boolean): Symbol = {
+ if (index <= 0 || len <= index) errorBadIndex(index)
+ var f = values(index).asInstanceOf[Symbol]
+ if (f == null) {
+ val start = starts(index)
+ if (in.buf(start) != CONSTANT_FIELDREF &&
+ in.buf(start) != CONSTANT_METHODREF &&
+ in.buf(start) != CONSTANT_INTFMETHODREF) errorBadTag(start)
+ val cls = getClassSymbol(in.getChar(start + 1))
+ val Pair(name, tpe) = getNameAndType(in.getChar(start + 3), cls);
+ f = ((if (static) cls.linkedModule.moduleClass else cls)
+ .info.decl(name).suchThat(s => s.tpe =:= tpe));
+ assert(f != NoSymbol, "Could not find symbol for " + name + ": " + tpe + " in " + cls);
+ values(index) = f
+ }
+ f
+ }
+
+ def getNameAndType(index: Int, ownerClass: Symbol): Pair[Name, Type] = {
+ if (index <= 0 || len <= index) errorBadIndex(index)
+ var p = values(index).asInstanceOf[Pair[Name, Type]]
+ if (p == null) {
+ val start = starts(index)
+ if (in.buf(start) != CONSTANT_NAMEANDTYPE) errorBadTag(start)
+ val name = getName(in.getChar(start + 1))
+ var tpe = getType(in.getChar(start + 3))
+ if (name == nme.CONSTRUCTOR)
+ tpe match {
+ case MethodType(formals, restpe) =>
+ assert(restpe.symbol == definitions.UnitClass)
+ tpe = MethodType(formals, ownerClass.tpe)
+ }
+
+ p = Pair(name, tpe)
+ }
+ p
+ }
+
def getType(index: int): Type =
sigToType(getExternalName(index))
@@ -200,7 +242,7 @@ abstract class ClassfileParser {
/** Throws an exception signaling a bad constant index. */
private def errorBadIndex(index: int) =
- throw new RuntimeException("bad constant pool index: " + index)
+ throw new RuntimeException("bad constant pool index: " + index + " at pos: " + in.bp)
/** Throws an exception signaling a bad tag at given address. */
private def errorBadTag(start: int) =
@@ -211,7 +253,7 @@ abstract class ClassfileParser {
var index = 0
val end = name.length
def objToAny(tp: Type): Type =
- if (tp.symbol == definitions.ObjectClass) definitions.AnyClass.tpe
+ if (!global.phase.erasedTypes && tp.symbol == definitions.ObjectClass) definitions.AnyClass.tpe
else tp
def paramsigs2types: List[Type] =
if (name(index) == ')') { index = index + 1; List() }
@@ -482,6 +524,7 @@ abstract class ClassfileParser {
def parseAttribute(): unit = {
val attrName = pool.getName(in.nextChar)
val attrLen = in.nextInt
+ val oldpb = in.bp;
attrName match {
case nme.SignatureATTR =>
if (global.settings.Xgenerics.value) {
@@ -508,9 +551,10 @@ abstract class ClassfileParser {
if (c1 != null) sym.setInfo(ConstantType(c1))
else System.out.println("failure to convert "+c+" to "+symtype);//debug
case nme.InnerClassesATTR =>
- parseInnerClasses()
+ if (!isScala) parseInnerClasses() else in.skip(attrLen)
case nme.ScalaSignatureATTR =>
unpickler.unpickle(in.buf, in.bp, clazz, staticModule, in.file.toString())
+ in.skip(attrLen);
this.isScala = true
case nme.JacoMetaATTR =>
val meta = pool.getName(in.nextChar).toString().trim()
@@ -617,13 +661,13 @@ abstract class ClassfileParser {
}
}
- private def getOwner(flags: int): Symbol =
+ protected def getOwner(flags: int): Symbol =
if ((flags & JAVA_ACC_STATIC) != 0) statics else clazz
- private def getScope(flags: int): Scope =
+ protected def getScope(flags: int): Scope =
if ((flags & JAVA_ACC_STATIC) != 0) staticDefs else instanceDefs
- private def transFlags(flags: int): long = {
+ protected def transFlags(flags: int): long = {
var res = 0l
if ((flags & JAVA_ACC_PRIVATE) != 0)
res = res | PRIVATE