From 154326ab0c464bd10648b03998ea7a1700a572bb Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 23 Dec 2009 15:02:17 +0000 Subject: Weeds out stale symbols in typer. --- src/compiler/scala/tools/nsc/Global.scala | 16 ++++++++-------- src/compiler/scala/tools/nsc/typechecker/Typers.scala | 19 +++++++++++++++++-- 2 files changed, 25 insertions(+), 10 deletions(-) (limited to 'src/compiler/scala') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index dfa8dcbef4..1128150cb8 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -673,9 +673,9 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable refreshProgress } private def refreshProgress = - if (fileset.size > 0) - progress((phasec * fileset.size) + unitc, - (phaseDescriptors.length-1) * fileset.size) // terminal phase not part of the progress display + if (compiledFiles.size > 0) + progress((phasec * compiledFiles.size) + unitc, + (phaseDescriptors.length-1) * compiledFiles.size) // terminal phase not part of the progress display // ----- finding phases -------------------------------------------- @@ -704,12 +704,12 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable // ----------- Units and top-level classes and objects -------- private var unitbuf = new ListBuffer[CompilationUnit] - private var fileset = new HashSet[AbstractFile] + var compiledFiles = new HashSet[AbstractFile] /** add unit to be compiled in this run */ private def addUnit(unit: CompilationUnit) { unitbuf += unit - fileset += unit.source.file + compiledFiles += unit.source.file } /* An iterator returning all the units being compiled in this run */ @@ -847,12 +847,12 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable * to phase "namer". */ def compileLate(file: AbstractFile) { - if (fileset eq null) { + if (compiledFiles eq null) { val msg = "No class file for " + file + " was found\n(This file cannot be loaded as a source file)" inform(msg) throw new FatalError(msg) - } else if (!(fileset contains file)) { + } else if (!(compiledFiles contains file)) { compileLate(new CompilationUnit(getSourceFile(file))) } } @@ -863,7 +863,7 @@ class Global(var settings: Settings, var reporter: Reporter) extends SymbolTable def compileLate(unit: CompilationUnit) { addUnit(unit) var localPhase = firstPhase.asInstanceOf[GlobalPhase] - while (localPhase != null && (localPhase.id < globalPhase.id || localPhase.id <= namerPhase.id)/* && !reporter.hasErrors*/) { + while (localPhase != null && (localPhase.id < globalPhase.id || localPhase.id < typerPhase.id)/* && !reporter.hasErrors*/) { val oldSource = reporter.getSource reporter.withSource(unit.source) { atPhase(localPhase)(localPhase.applyPhase(unit)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index c43d9c8788..ec5ce91f3c 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3534,12 +3534,27 @@ trait Typers { self: Analyzer => var pre: Type = NoPrefix // the prefix type of defSym, if a class member var qual: Tree = EmptyTree // the qualififier tree if transformed tree is a select - // if we are in a constructor of a pattern, ignore all definitions + // a symbol is stale if it is toplevel, to be loaded from a classfile, and + // the classfile is produced from a sourcefile which is compiled in the current run. + def isStale(sym: Symbol): Boolean = { + sym.owner.isPackageClass && + sym.rawInfo.isInstanceOf[loaders.ClassfileLoader] && { + sym.rawInfo.load(sym) + (sym.sourceFile ne null) && + (currentRun.compiledFiles contains sym.sourceFile) + } + } + + // A symbol qualifies if it exists and is not stale. Stale symbols + // are made to disappear here. In addition, + // if we are in a constructor of a pattern, we ignore all definitions // which are methods (note: if we don't do that // case x :: xs in class List would return the :: method). - def qualifies(sym: Symbol): Boolean = + def qualifies(sym: Symbol): Boolean = { + if (isStale(sym)) sym.setInfo(NoType) sym.exists && ((mode & PATTERNmode | FUNmode) != (PATTERNmode | FUNmode) || !sym.isSourceMethod) + } if (defSym == NoSymbol) { var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope -- cgit v1.2.3