summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala58
-rwxr-xr-xtest/files/pos/t2433/A.java4
-rwxr-xr-xtest/files/pos/t2433/B.java4
-rwxr-xr-xtest/files/pos/t2433/Test.scala3
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()
+}