summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2010-04-20 13:08:52 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2010-04-20 13:08:52 +0000
commitc5441dcc98a7c91d398cb43a35fcad9d07ad0da6 (patch)
tree8036e1a661645864b7da0469e4af16298aeb9a8e /src/compiler
parent9933cbe4e49bf558eb238c4d807551aaf5a2e94c (diff)
downloadscala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.tar.gz
scala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.tar.bz2
scala-c5441dcc98a7c91d398cb43a35fcad9d07ad0da6.zip
fix bootstrap library build. review by odersky
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala35
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeInfo.scala13
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala2
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
}