Made NamesDefault more robust to support idempotent compilation.
git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@23923 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
5ff5d72a4f
commit
ec61c46830
|
@ -1036,6 +1036,13 @@ trait Namers { self: Analyzer =>
|
|||
if (!isConstr)
|
||||
meth.owner.resetFlag(INTERFACE) // there's a concrete member now
|
||||
val default = parentNamer.enterSyntheticSym(defaultTree)
|
||||
if (forInteractive && default.owner.isTerm) {
|
||||
// enter into map from method symbols to default arguments.
|
||||
// if compiling the same local block several times (which can happen in interactive mode)
|
||||
// we might otherwise not find the default symbol, because the second time it the
|
||||
// method symbol will be re-entered in the scope but the default parameter will not.
|
||||
defaultParametersOfMethod(meth) += default
|
||||
}
|
||||
} else if (baseHasDefault) {
|
||||
// the parameter does not have a default itself, but the corresponding parameter
|
||||
// in the base class does.
|
||||
|
|
|
@ -8,7 +8,8 @@ package typechecker
|
|||
|
||||
import symtab.Flags._
|
||||
|
||||
import scala.collection.mutable.ListBuffer
|
||||
import scala.collection.mutable.{ListBuffer, WeakHashMap}
|
||||
import scala.collection.immutable.Set
|
||||
|
||||
/**
|
||||
* @author Lukas Rytz
|
||||
|
@ -19,6 +20,10 @@ trait NamesDefaults { self: Analyzer =>
|
|||
import global._
|
||||
import definitions._
|
||||
|
||||
val defaultParametersOfMethod = new WeakHashMap[Symbol, Set[Symbol]] {
|
||||
override def default(key: Symbol) = Set()
|
||||
}
|
||||
|
||||
case class NamedApplyInfo(qual: Option[Tree], targs: List[Tree],
|
||||
vargss: List[List[Tree]], blockTyper: Typer)
|
||||
val noApplyInfo = NamedApplyInfo(None, Nil, Nil, null)
|
||||
|
@ -29,7 +34,6 @@ trait NamesDefaults { self: Analyzer =>
|
|||
}
|
||||
def isNamed(arg: Tree) = nameOf(arg).isDefined
|
||||
|
||||
|
||||
/** @param pos maps indicies from old to new */
|
||||
def reorderArgs[T: ClassManifest](args: List[T], pos: Int => Int): List[T] = {
|
||||
val res = new Array[T](args.length)
|
||||
|
|
|
@ -1797,14 +1797,20 @@ trait Typers extends Modes {
|
|||
*/
|
||||
def typedBlock(block: Block, mode: Int, pt: Type): Block = {
|
||||
val syntheticPrivates = new ListBuffer[Symbol]
|
||||
def enterIfNotThere(sym: Symbol) {
|
||||
var e = context.scope.lookupEntry(sym.name)
|
||||
while ((e ne null) && (e.sym ne sym)) e = e.tail
|
||||
if (e eq null) context.scope.enter(sym)
|
||||
}
|
||||
try {
|
||||
namer.enterSyms(block.stats)
|
||||
for (stat <- block.stats) {
|
||||
if (forInteractive && stat.isDef) {
|
||||
// this might be redundant now
|
||||
var e = context.scope.lookupEntry(stat.symbol.name)
|
||||
while ((e ne null) && (e.sym ne stat.symbol)) e = e.tail
|
||||
if (e eq null) context.scope.enter(stat.symbol)
|
||||
// this logic is needed in case typer was interrupted half way through a block and then comes
|
||||
// back to do the block again. In that case the definitions that were already attributed as well as any
|
||||
// default parameters of such methods need to be re-entered in the current scope.
|
||||
enterIfNotThere(stat.symbol)
|
||||
defaultParametersOfMethod(stat.symbol) foreach enterIfNotThere
|
||||
}
|
||||
enterLabelDef(stat)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue