diff options
author | Martin Odersky <odersky@gmail.com> | 2010-03-25 20:21:45 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2010-03-25 20:21:45 +0000 |
commit | aa406f4b8264a17926f3cafdc61010b7210c67b8 (patch) | |
tree | 87e881fec60dfe1d0f9250feff3946cbcc465bc2 | |
parent | 6ee24a3c5d31ef769e47410d8806a5f4bd7a06bf (diff) | |
download | scala-aa406f4b8264a17926f3cafdc61010b7210c67b8.tar.gz scala-aa406f4b8264a17926f3cafdc61010b7210c67b8.tar.bz2 scala-aa406f4b8264a17926f3cafdc61010b7210c67b8.zip |
I think this closes #2433.
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala | 6 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 58 | ||||
-rwxr-xr-x | test/files/pos/t2433/A.java | 4 | ||||
-rwxr-xr-x | test/files/pos/t2433/B.java | 4 | ||||
-rwxr-xr-x | test/files/pos/t2433/Test.scala | 3 |
5 files changed, 53 insertions, 22 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index d44c1ac514..947f5a8f88 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -11,7 +11,7 @@ import java.io.{File, IOException} import ch.epfl.lamp.compiler.msil.{Type => MSILType, Attribute => MSILAttribute} -import scala.collection.mutable.{HashMap, HashSet} +import scala.collection.mutable.{HashMap, HashSet, ListBuffer} import scala.compat.Platform.currentTime import scala.tools.nsc.io.AbstractFile import scala.tools.nsc.util.{ ClassPath, JavaClassPath } @@ -275,4 +275,8 @@ abstract class SymbolLoaders { val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global if (global.forMSIL) init() } + + /** used from classfile parser to avoid cyclies */ + var parentsLevel = 0 + var pendingLoadActions: List[() => Unit] = Nil } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 99754c4804..f7e78d6588 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -439,12 +439,17 @@ abstract class ClassfileParser { in.bp += ifaces * 2 // .. and iface count interfaces List(definitions.AnyRefClass.tpe) // dummy superclass, will be replaced by pickled information } else { - val superType = if (isAnnotation) { in.nextChar; definitions.AnnotationClass.tpe } - else pool.getSuperClass(in.nextChar).tpe - val ifaceCount = in.nextChar - var ifaces = for (i <- List.range(0, ifaceCount)) yield pool.getSuperClass(in.nextChar).tpe - if (isAnnotation) ifaces = definitions.ClassfileAnnotationClass.tpe :: ifaces - superType :: ifaces + try { + loaders.parentsLevel += 1 + val superType = if (isAnnotation) { in.nextChar; definitions.AnnotationClass.tpe } + else pool.getSuperClass(in.nextChar).tpe + val ifaceCount = in.nextChar + var ifaces = for (i <- List.range(0, ifaceCount)) yield pool.getSuperClass(in.nextChar).tpe + if (isAnnotation) ifaces = definitions.ClassfileAnnotationClass.tpe :: ifaces + superType :: ifaces + } finally { + loaders.parentsLevel -= 1 + } } } @@ -458,6 +463,7 @@ abstract class ClassfileParser { // get the class file parser to reuse scopes. instanceDefs = new Scope staticDefs = new Scope + val classInfo = ClassInfoType(parseParents, instanceDefs, clazz) val staticInfo = ClassInfoType(List(), staticDefs, statics) @@ -482,22 +488,32 @@ abstract class ClassfileParser { // attributes now depend on having infos set already parseAttributes(clazz, classInfo) - in.bp = curbp - val fieldCount = in.nextChar - for (i <- 0 until fieldCount) parseField() - sawPrivateConstructor = false - val methodCount = in.nextChar - for (i <- 0 until methodCount) parseMethod() - if (!sawPrivateConstructor && - (instanceDefs.lookup(nme.CONSTRUCTOR) == NoSymbol && - (sflags & INTERFACE) == 0L)) - { - //Console.println("adding constructor to " + clazz);//DEBUG - instanceDefs.enter( - clazz.newConstructor(NoPosition) - .setFlag(clazz.flags & ConstrFlags) - .setInfo(MethodType(List(), clazz.tpe))) + loaders.pendingLoadActions = { () => + in.bp = curbp + val fieldCount = in.nextChar + for (i <- 0 until fieldCount) parseField() + sawPrivateConstructor = false + val methodCount = in.nextChar + for (i <- 0 until methodCount) parseMethod() + if (!sawPrivateConstructor && + (instanceDefs.lookup(nme.CONSTRUCTOR) == NoSymbol && + (sflags & INTERFACE) == 0L)) + { + //Console.println("adding constructor to " + clazz);//DEBUG + instanceDefs.enter( + clazz.newConstructor(NoPosition) + .setFlag(clazz.flags & ConstrFlags) + .setInfo(MethodType(List(), clazz.tpe))) + } + () + } :: loaders.pendingLoadActions + if (loaders.parentsLevel == 0) { + while (!loaders.pendingLoadActions.isEmpty) { + val item = loaders.pendingLoadActions.head + loaders.pendingLoadActions = loaders.pendingLoadActions.tail + item() } + } } else parseAttributes(clazz, classInfo) } diff --git a/test/files/pos/t2433/A.java b/test/files/pos/t2433/A.java new file mode 100755 index 0000000000..340690c402 --- /dev/null +++ b/test/files/pos/t2433/A.java @@ -0,0 +1,4 @@ +class A223 extends B223.Inner { + static class Inner {} + void foo() {} +}
\ No newline at end of file diff --git a/test/files/pos/t2433/B.java b/test/files/pos/t2433/B.java new file mode 100755 index 0000000000..151dd71ca1 --- /dev/null +++ b/test/files/pos/t2433/B.java @@ -0,0 +1,4 @@ +class B223 { + static class Inner {} + void m(A223.Inner x) {} +}
\ No newline at end of file diff --git a/test/files/pos/t2433/Test.scala b/test/files/pos/t2433/Test.scala new file mode 100755 index 0000000000..02fd89b646 --- /dev/null +++ b/test/files/pos/t2433/Test.scala @@ -0,0 +1,3 @@ +object Test { + (new A223).foo() +} |