From edee27f59f17873b378d96504d0b20013a31d081 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Mon, 25 Mar 2013 15:50:41 +0100 Subject: SI-6168 Retain prefix when parsing types in JVM signatures When reading Java classfiles, the generic signatures are used to construct the corresponding Scala type signatures. In the enclosed test case, the field `SomeClass.f` had the JVM signature: LContext.Field; The parser first (correctly) parsed the prefix as `Context[SomeClass]`. It then looked up the type symbol for `Field` in that that type. It then discarded the parsed prefix, and instead used the prefix from the info of the type symbol: `Context[ParentType]`. This commit changes the signature parser after the first `.` to use the result of prior parsing as the prefix. I've also included a test case with Java static inner classes, which don't require any special treatment. --- .../scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index d26a61f187..30851f1d46 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -607,6 +607,8 @@ abstract class ClassfileParser { val sym = getOwner(jflags).newValue(name.toTermName, NoPosition, sflags) val isEnum = (jflags & JAVA_ACC_ENUM) != 0 + // Note: the info may be overrwritten later with a generic signature + // parsed from SignatureATTR sym setInfo { if (isEnum) ConstantType(Constant(sym)) else info @@ -661,6 +663,8 @@ abstract class ClassfileParser { } info = MethodType(newParams, clazz.tpe) } + // Note: the info may be overrwritten later with a generic signature + // parsed from SignatureATTR sym.setInfo(info) importPrivateWithinFromJavaFlags(sym, jflags) parseAttributes(sym, info) @@ -754,7 +758,9 @@ abstract class ClassfileParser { accept('.') val name = subName(c => c == ';' || c == '<' || c == '.').toTypeName val clazz = tpe.member(name) - tpe = processClassType(processInner(clazz.tpe)) + val dummyArgs = Nil // the actual arguments are added in processClassType + val inner = typeRef(pre = tpe, sym = clazz, args = dummyArgs) + tpe = processClassType(inner) } accept(';') tpe -- cgit v1.2.3