diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-04-20 13:08:52 +0000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-04-20 13:08:52 +0000 |
commit | c5441dcc98a7c91d398cb43a35fcad9d07ad0da6 (patch) | |
tree | 8036e1a661645864b7da0469e4af16298aeb9a8e /src | |
parent | 9933cbe4e49bf558eb238c4d807551aaf5a2e94c (diff) | |
download | scala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.tar.gz scala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.tar.bz2 scala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.zip |
fix bootstrap library build. review by odersky
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/Global.scala | 35 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/TreeInfo.scala | 13 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 2 |
4 files changed, 42 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index b43908c4f9..0ec36cf9ab 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -714,7 +714,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable /** Compile list of source files */ def compileSources(_sources: List[SourceFile]) { val depSources = dependencyAnalysis.filter(_sources.distinct) // bug #1268, scalac confused by duplicated filenames - val sources = scalaObjectFirst(depSources) + val sources = coreClassesFirst(depSources) if (reporter.hasErrors) return // there is a problem already, e.g. a // plugin was passed a bad option @@ -871,14 +871,43 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable if (!pclazz.isRoot) resetPackageClass(pclazz.owner) } - private def scalaObjectFirst(files: List[SourceFile]) = { + /** + * Re-orders the source files to + * 1. ScalaObject + * 2. LowPriorityImplicits / StandardEmbeddings (i.e. parents of Predef) + * 3. the rest + * + * 1 is to avoid cyclic reference errors. + * 2 is due to the following. When completing "Predef" (*), typedIdent is called + * for its parents (e.g. "LowPriorityImplicits"). typedIdent checks wethter + * the symbol reallyExists, which tests if the type of the symbol after running + * its completer is != NoType. + * If the "namer" phase has not yet run for "LowPriorityImplicits", the symbol + * has a SourcefileLoader as type. Calling "doComplete" on it does nothing at + * all, because the source file is part of the files to be compiled anyway. + * So the "reallyExists" test will return "false". + * Only after the namer, the symbol has a lazy type which actually computes + * the info, and "reallyExists" behaves as expected. + * So we need to make sure that the "namer" phase is run on predef's parents + * before running it on predef. + * + * (*) Predef is completed early when calling "mkAttributedRef" during the + * addition of "import Predef._" to sourcefiles. So this situation can't + * happen for user classes. + * + */ + private def coreClassesFirst(files: List[SourceFile]) = { def inScalaFolder(f: SourceFile) = f.file.container.name == "scala" + var scalaObject: Option[SourceFile] = None val res = new ListBuffer[SourceFile] for (file <- files) file.file.name match { - case "ScalaObject.scala" if inScalaFolder(file) => file +=: res + case "ScalaObject.scala" if inScalaFolder(file) => scalaObject = Some(file) + case "LowPriorityImplicits.scala" if inScalaFolder(file) => file +=: res + case "StandardEmbeddings.scala" if inScalaFolder(file) => file +=: res case _ => res += file } + for (so <- scalaObject) so +=: res res.toList } } // class Run diff --git a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala index 2e543a0960..0f31a3a9f2 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeInfo.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeInfo.scala @@ -325,18 +325,19 @@ abstract class TreeInfo { false } - /** Compilation unit is the predef object + /** Compilation unit is class or object 'name' in package 'scala' */ def isUnitInScala(tree: Tree, name: Name) = tree match { - case PackageDef(Ident(nme.scala_), defs) => isObject(defs, name) + case PackageDef(Ident(nme.scala_), defs) => isImplDef(defs, name) case _ => false } - private def isObject(trees: List[Tree], name: Name): Boolean = trees match { - case Import(_, _) :: xs => isObject(xs, name) - case DocDef(_, tree1) :: Nil => isObject(List(tree1), name) - case Annotated(_, tree1) :: Nil => isObject(List(tree1), name) + private def isImplDef(trees: List[Tree], name: Name): Boolean = trees match { + case Import(_, _) :: xs => isImplDef(xs, name) + case DocDef(_, tree1) :: Nil => isImplDef(List(tree1), name) + case Annotated(_, tree1) :: Nil => isImplDef(List(tree1), name) case ModuleDef(_, `name`, _) :: Nil => true + case ClassDef(_, `name`, _, _) :: Nil => true case _ => false } diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 4c0c1ec739..026a2eb7e5 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -606,6 +606,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => supersym == NoSymbol || supersym.isIncompleteIn(base) } + // Does not always work if the rawInfo is a SourcefileLoader, see comment + // in "def coreClassesFirst" in Global. final def exists: Boolean = this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index becb4b069f..a922d2ad68 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -46,7 +46,7 @@ trait Contexts { self: Analyzer => assert(ScalaPackage ne null, "Scala package is null") imps += ScalaPackage if (!(treeInfo.isUnitInScala(unit.body, nme.Predef) || - treeInfo.isUnitInScala(unit.body, nme.ScalaObject) || + treeInfo.isUnitInScala(unit.body, nme.ScalaObject.toTypeName) || treeInfo.containsLeadingPredefImport(List(unit.body)))) imps += PredefModule } |