summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-01-07 14:44:18 +0000
committerMartin Odersky <odersky@gmail.com>2011-01-07 14:44:18 +0000
commit148736c3df1fa6463b4b2658c01bcf452a52c224 (patch)
tree7804fb4ac7d10946f8b154b482ac360289dac838 /src
parentced363bf5aa276356201815b22a015d30754f114 (diff)
downloadscala-148736c3df1fa6463b4b2658c01bcf452a52c224.tar.gz
scala-148736c3df1fa6463b4b2658c01bcf452a52c224.tar.bz2
scala-148736c3df1fa6463b4b2658c01bcf452a52c224.zip
Made NamesDefault more robust to support idempo...
Made NamesDefault more robust to support idempotent compilation.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala14
3 files changed, 23 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 5aabe7a72e..4bebc0fddc 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -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.
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 7982617fee..0c9bebd510 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -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)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 7ef219bb23..2099278fe3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -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)
}