summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2010-03-25 20:21:45 +0000
committerMartin Odersky <odersky@gmail.com>2010-03-25 20:21:45 +0000
commitaa406f4b8264a17926f3cafdc61010b7210c67b8 (patch)
tree87e881fec60dfe1d0f9250feff3946cbcc465bc2 /src/compiler/scala/tools
parent6ee24a3c5d31ef769e47410d8806a5f4bd7a06bf (diff)
downloadscala-aa406f4b8264a17926f3cafdc61010b7210c67b8.tar.gz
scala-aa406f4b8264a17926f3cafdc61010b7210c67b8.tar.bz2
scala-aa406f4b8264a17926f3cafdc61010b7210c67b8.zip
I think this closes #2433.
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala6
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala58
2 files changed, 42 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)
}