From fffe6449d14387df980f25aee9e9c1795b5f13aa Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 11 Dec 2009 14:57:35 +0000 Subject: fixes #2610 and fixes #2687. --- src/compiler/scala/tools/nsc/Global.scala | 16 +++++------ src/compiler/scala/tools/nsc/doc/DocFactory.scala | 1 + .../scala/tools/nsc/symtab/SymbolLoaders.scala | 32 +++++++++++++++------- .../scala/tools/nsc/typechecker/Analyzer.scala | 28 ++++++++++++++++++- .../scala/tools/nsc/typechecker/Namers.scala | 4 --- 5 files changed, 57 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 645eb1ecf6..dfa8dcbef4 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -521,7 +521,8 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable protected def computeInternalPhases() { phasesSet += syntaxAnalyzer // The parser phasesSet += analyzer.namerFactory // note: types are there because otherwise - phasesSet += analyzer.typerFactory // consistency check after refchecks would fail. + phasesSet += analyzer.packageObjects // consistency check after refchecks would fail. + phasesSet += analyzer.typerFactory phasesSet += superAccessors // add super accessors phasesSet += pickler // serialize symbol tables phasesSet += refchecks // perform reference and override checking, translate nested objects @@ -733,7 +734,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.removeDuplicates) // bug #1268, scalac confused by duplicated filenames - val sources = pkgObjectsFirst(depSources) + val sources = scalaObjectFirst(depSources) if (reporter.hasErrors) return // there is a problem already, e.g. a // plugin was passed a bad option @@ -883,18 +884,15 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable if (!pclazz.isRoot) resetPackageClass(pclazz.owner) } - private def pkgObjectsFirst(files: List[SourceFile]) = { + private def scalaObjectFirst(files: List[SourceFile]) = { def inScalaFolder(f: SourceFile) = f.file.container.name == "scala" val res = new ListBuffer[SourceFile] - var scalaObject: Option[SourceFile] = None for (file <- files) file.file.name match { - case "ScalaObject.scala" if inScalaFolder(file) => scalaObject = Some(file) - case "package.scala" => file +=: res // prepend package objects - case _ => res += file // append all others + case "ScalaObject.scala" if inScalaFolder(file) => file +=: res + case _ => res += file } - scalaObject.map(res.+=:(_)) // ScalaObject 1st - res.toList // then package objects, then others + res.toList } } // class Run diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala index 3c969c41f8..99cec01949 100644 --- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala @@ -31,6 +31,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor override protected def computeInternalPhases() { phasesSet += syntaxAnalyzer phasesSet += analyzer.namerFactory + phasesSet += analyzer.packageObjects phasesSet += analyzer.typerFactory phasesSet += superAccessors phasesSet += pickler diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala index 6fb46a4772..97a11acf99 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala @@ -166,24 +166,36 @@ abstract class SymbolLoaders { val pkgModule = root.info.decl(nme.PACKAGEkw) if (pkgModule.isModule && !pkgModule.rawInfo.isInstanceOf[SourcefileLoader]) { //println("open "+pkgModule)//DEBUG - openPackageModule(pkgModule) + openPackageModule(pkgModule)() } } } - def openPackageModule(m: Symbol) = { - val owner = m.owner - for (member <- m.info.decls.iterator) { - // todo: handle overlapping definitions in some way: mark as errors - // or treat as abstractions. For now the symbol in the package module takes precedence. - for (existing <- owner.info.decl(member.name).alternatives) - owner.info.decls.unlink(existing) + def openPackageModule(module: Symbol)(packageClass: Symbol = module.owner): Unit = { + // unlink existing symbols in the package + for (member <- module.info.decls.iterator) { + if (!member.hasFlag(PRIVATE) && !member.isConstructor) { + // todo: handle overlapping definitions in some way: mark as errors + // or treat as abstractions. For now the symbol in the package module takes precedence. + for (existing <- packageClass.info.decl(member.name).alternatives) + packageClass.info.decls.unlink(existing) + } } - for (member <- m.info.decls.iterator) { - owner.info.decls.enter(member) + // enter non-private decls the class + for (member <- module.info.decls.iterator) { + if (!member.hasFlag(PRIVATE) && !member.isConstructor) { + packageClass.info.decls.enter(member) + } + } + // enter decls of parent classes + for (pt <- module.info.parents; val p = pt.typeSymbol) { + if (p != definitions.ObjectClass && p != definitions.ScalaObjectClass) { + openPackageModule(p)(packageClass) + } } } + class JavaPackageLoader(classpath: ClassPath[AbstractFile]) extends PackageLoader(classpath) { protected def needCompile(bin: AbstractFile, src: AbstractFile) = (src.lastModified >= bin.lastModified) diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 3a4fc6d807..ead20f1cb8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -37,13 +37,39 @@ trait Analyzer extends AnyRef } } + object packageObjects extends SubComponent { + val global: Analyzer.this.global.type = Analyzer.this.global + val phaseName = "packageobjects" + val runsAfter = List[String]() + val runsRightAfter= Some("namer") + + def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) { + import global._ + + val openPackageObjectsTraverser = new Traverser { + override def traverse(tree: Tree): Unit = tree match { + case ModuleDef(_, _, _) => + if (tree.symbol.name == nme.PACKAGEkw) { + loaders.openPackageModule(tree.symbol)() + } + case ClassDef(_, _, _, _) => () // make it fast + case _ => super.traverse(tree) + } + } + + def apply(unit: CompilationUnit) { + openPackageObjectsTraverser(unit.body) + } + } + } + var typerTime = 0L object typerFactory extends SubComponent { val global: Analyzer.this.global.type = Analyzer.this.global val phaseName = "typer" val runsAfter = List[String]() - val runsRightAfter = Some("namer") + val runsRightAfter = Some("packageobjects") def newPhase(_prev: Phase): StdPhase = new StdPhase(_prev) { resetTyper() override def run { diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 2132be4d50..d5bd9c3c3f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -1136,10 +1136,6 @@ trait Namers { self: Analyzer => val clazz = sym.moduleClass clazz.setInfo(newNamer(context.makeNewScope(tree, clazz)).templateSig(impl)) //clazz.typeOfThis = singleType(sym.owner.thisType, sym); - tree.symbol.setInfo(clazz.tpe) // initialize module to avoid cycles - if (tree.symbol.name == nme.PACKAGEkw) { - loaders.openPackageModule(tree.symbol) - } clazz.tpe case DefDef(mods, _, tparams, vparamss, tpt, rhs) => -- cgit v1.2.3