From e638fb866212108c09d4d09b9a26e24800b2b5f7 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Thu, 11 Jun 2009 15:50:56 +0000 Subject: Fixed a number of things in the icode reader, o... Fixed a number of things in the icode reader, optimizations still not fully functional. --- .../nsc/symtab/classfile/ClassfileParser.scala | 21 +++++++++++++++------ .../tools/nsc/symtab/classfile/ICodeReader.scala | 16 +++++++--------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 8c49e68c25..10879e663e 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -245,19 +245,28 @@ abstract class ClassfileParser { f } - def getNameAndType(index: Int, ownerTpe: Type): (Name, Type) = { + /** Return a name and a type at the given index. If the type is a method + * type, a dummy symbol is created in 'ownerTpe', which is used as the + * owner of its value parameters. This might lead to inconsistencies, + * if a symbol of the given name already exists, and has a different + * type. + */ + private def getNameAndType(index: Int, ownerTpe: Type): (Name, Type) = { if (index <= 0 || len <= index) errorBadIndex(index) var p = values(index).asInstanceOf[(Name, Type)] if (p eq 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)) + // create a dummy symbol for method types + val dummySym = ownerTpe.typeSymbol.newMethod(ownerTpe.typeSymbol.pos, name) + var tpe = getType(dummySym, in.getChar(start + 3)) + + // fix the return type, which is blindly set to the class currently parsed if (name == nme.CONSTRUCTOR) tpe match { - case MethodType(params, restpe) => - assert(restpe.typeSymbol == definitions.UnitClass) - tpe = MethodType(params, ownerTpe) + case MethodType(formals, restpe) => + tpe = MethodType(formals, ownerTpe) } p = (name, tpe) @@ -616,7 +625,7 @@ abstract class ClassfileParser { paramtypes += objToAny(sig2type(tparams, skiptvs)) } index += 1 - val restype = if (sym != null && sym.isConstructor) { + val restype = if (sym != null && sym.isClassConstructor) { accept('V') clazz.tpe } else diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 510183a22d..2358d68575 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -101,13 +101,11 @@ abstract class ICodeReader extends ClassfileParser { private def parseMember(field: Boolean): (Int, Symbol) = { val jflags = in.nextChar val name = pool.getName(in.nextChar) - var tpe = pool.getType(in.nextChar) - if (name == nme.CONSTRUCTOR) - tpe match { - case MethodType(formals, restpe) => - assert(restpe.typeSymbol == definitions.UnitClass) - tpe = MethodType(formals, getOwner(jflags).tpe) - } + + val owner = getOwner(jflags) + val dummySym = owner.newMethod(owner.pos, name).setFlag(javaToScalaFlags(jflags)) + + var tpe = pool.getType(dummySym, in.nextChar) if ("" == name.toString) (jflags, NoSymbol) @@ -117,12 +115,12 @@ abstract class ICodeReader extends ClassfileParser { if (sym == NoSymbol) sym = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(old => old.tpe =:= tpe); if (sym == NoSymbol) { - log("Could not find symbol for " + name + ": " + tpe/* + " in " + owner.info.decls*/) + log("Could not find symbol for " + name + ": " + tpe + " in " + owner.info.decls) log(owner.info.member(name).tpe + " : " + tpe) if (field) sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags)) else - sym = owner.newMethod(owner.pos, name).setInfo(tpe).setFlag(javaToScalaFlags(jflags)) + sym = dummySym.setInfo(tpe) owner.info.decls.enter(sym) log("added " + sym + ": " + sym.tpe) } -- cgit v1.2.3