diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-05-21 08:16:36 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-05-21 08:16:36 -0700 |
commit | 4b01e1ff3dbe383be5a3f80747a5b7113b6e9521 (patch) | |
tree | b0f1c83132223b6f98e9a1ce576f83ccf91798b7 /src | |
parent | 08334b0721d6040d61a727702b718fb3f3d558d2 (diff) | |
parent | dbee14fba95480cc8dddeefde573444551827b30 (diff) | |
download | scala-4b01e1ff3dbe383be5a3f80747a5b7113b6e9521.tar.gz scala-4b01e1ff3dbe383be5a3f80747a5b7113b6e9521.tar.bz2 scala-4b01e1ff3dbe383be5a3f80747a5b7113b6e9521.zip |
Merge pull request #587 from retronym/ticket/5125
Fix @varargs forwarder generation in the presence of nested templates.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 28 |
1 files changed, 18 insertions, 10 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 |