summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala28
2 files changed, 33 insertions, 23 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index f01cbade18..8af12f3f10 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -77,9 +77,17 @@ abstract class UnCurry extends InfoTransform
private var inConstructorFlag = 0L
private val byNameArgs = mutable.HashSet[Tree]()
private val noApply = mutable.HashSet[Tree]()
- private val newMembers = mutable.ArrayBuffer[Tree]()
+ private val newMembers = mutable.Map[Symbol, mutable.Buffer[Tree]]()
private val repeatedParams = mutable.Map[Symbol, List[ValDef]]()
+ /** Add a new synthetic member for `currentOwner` */
+ private def addNewMember(t: Tree): Unit =
+ newMembers.getOrElseUpdate(currentOwner, mutable.Buffer()) += t
+
+ /** Process synthetic members for `owner`. They are removed form the `newMembers` as a side-effect. */
+ @inline private def useNewMembers[T](owner: Symbol)(f: List[Tree] => T): T =
+ f(newMembers.remove(owner).getOrElse(Nil).toList)
+
@inline private def withInPattern[T](value: Boolean)(body: => T): T = {
inPattern = value
try body
@@ -573,7 +581,7 @@ abstract class UnCurry extends InfoTransform
val vparamssNoRhs = dd.vparamss mapConserve (_ mapConserve {p =>
treeCopy.ValDef(p, p.mods, p.name, p.tpt, EmptyTree)
})
-
+
if (dd.symbol hasAnnotation VarargsClass) saveRepeatedParams(dd)
withNeedLift(false) {
@@ -680,9 +688,8 @@ abstract class UnCurry extends InfoTransform
tree match {
/* Some uncurry post transformations add members to templates.
- * When inside a template, the following sequence is available:
- * - newMembers
- * Any entry in this sequence will be added into the template
+ *
+ * Members registered by `addMembers` for the current template are added
* once the template transformation has finished.
*
* In particular, this case will add:
@@ -690,8 +697,10 @@ abstract class UnCurry extends InfoTransform
*/
case Template(_, _, _) =>
localTyper = typer.atOwner(tree, currentClass)
- try deriveTemplate(tree)(transformTrees(newMembers.toList) ::: _)
- finally newMembers.clear()
+ useNewMembers(currentClass) {
+ newMembers =>
+ deriveTemplate(tree)(transformTrees(newMembers) ::: _)
+ }
case dd @ DefDef(_, _, _, vparamss0, _, rhs0) =>
val flatdd = copyDefDef(dd)(
@@ -763,7 +772,7 @@ abstract class UnCurry extends InfoTransform
/* Called during post transform, after the method argument lists have been flattened.
* It looks for the method in the `repeatedParams` map, and generates a Java-style
- * varargs forwarder. It then adds the forwarder to the `newMembers` sequence.
+ * varargs forwarder.
*/
private def addJavaVarargsForwarders(dd: DefDef, flatdd: DefDef): DefDef = {
if (!dd.symbol.hasAnnotation(VarargsClass) || !repeatedParams.contains(dd.symbol))
@@ -840,8 +849,7 @@ abstract class UnCurry extends InfoTransform
case None =>
// enter symbol into scope
currentClass.info.decls enter forwsym
- // add the method to `newMembers`
- newMembers += forwtree
+ addNewMember(forwtree)
}
flatdd
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index 2574a1d241..b7a6ea677e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -143,8 +143,8 @@ abstract class Duplicators extends Analyzer {
else
sym
- private def invalidate(tree: Tree) {
- debuglog("attempting to invalidate " + tree.symbol + ", owner - " + (if (tree.symbol ne null) tree.symbol.owner else "<NULL>"))
+ private def invalidate(tree: Tree, owner: Symbol = NoSymbol) {
+ debuglog("attempting to invalidate " + tree.symbol)
if (tree.isDef && tree.symbol != NoSymbol) {
debuglog("invalid " + tree.symbol)
invalidSyms(tree.symbol) = tree
@@ -158,18 +158,20 @@ abstract class Duplicators extends Analyzer {
newsym.setInfo(fixType(ldef.symbol.info))
ldef.symbol = newsym
debuglog("newsym: " + newsym + " info: " + newsym.info)
-
+
case vdef @ ValDef(mods, name, _, rhs) if mods.hasFlag(Flags.LAZY) =>
debuglog("ValDef " + name + " sym.info: " + vdef.symbol.info)
invalidSyms(vdef.symbol) = vdef
- val newsym = vdef.symbol.cloneSymbol(context.owner)
+ val newowner = if (owner != NoSymbol) owner else context.owner
+ val newsym = vdef.symbol.cloneSymbol(newowner)
newsym.setInfo(fixType(vdef.symbol.info))
vdef.symbol = newsym
- debuglog("newsym: " + newsym + " info: " + newsym.info)
-
+ debuglog("newsym: " + newsym + " info: " + newsym.info + ", owner: " + newsym.owner + ", " + newsym.owner.isClass)
+ if (newsym.owner.isClass) newsym.owner.info.decls enter newsym
+
case DefDef(_, name, tparams, vparamss, _, rhs) =>
// invalidate parameters
- invalidate(tparams ::: vparamss.flatten)
+ invalidateAll(tparams ::: vparamss.flatten)
tree.symbol = NoSymbol
case _ =>
@@ -178,14 +180,14 @@ abstract class Duplicators extends Analyzer {
}
}
- private def invalidate(stats: List[Tree]) {
- stats foreach invalidate
+ private def invalidateAll(stats: List[Tree], owner: Symbol = NoSymbol) {
+ stats.foreach(invalidate(_, owner))
}
def retypedMethod(ddef: DefDef, oldThis: Symbol, newThis: Symbol): Tree = {
oldClassOwner = oldThis
newClassOwner = newThis
- invalidate(ddef.tparams)
+ invalidateAll(ddef.tparams)
mforeach(ddef.vparamss) { vdef =>
invalidate(vdef)
vdef.tpe = null
@@ -239,15 +241,15 @@ abstract class Duplicators extends Analyzer {
case Block(stats, res) =>
debuglog("invalidating block")
- invalidate(stats)
+ invalidateAll(stats)
invalidate(res)
tree.tpe = null
super.typed(tree, mode, pt)
case ClassDef(_, _, _, tmpl @ Template(parents, _, stats)) =>
- // log("invalidating classdef " + tree.tpe)
+ // log("invalidating classdef " + tree)
tmpl.symbol = tree.symbol.newLocalDummy(tree.pos)
- invalidate(stats)
+ invalidateAll(stats, tree.symbol)
tree.tpe = null
super.typed(tree, mode, pt)