summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-04-09 15:43:27 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-04-09 15:43:27 +0000
commit2209c911ce5f2a8a3f2115d83dcac400227aba6e (patch)
treeeb6dfbb016ef2fb869374e97ea40729b773662c0 /src
parent04e60a56e945f760dee3813e4ce2972a4c812844 (diff)
downloadscala-2209c911ce5f2a8a3f2115d83dcac400227aba6e.tar.gz
scala-2209c911ce5f2a8a3f2115d83dcac400227aba6e.tar.bz2
scala-2209c911ce5f2a8a3f2115d83dcac400227aba6e.zip
Changed TreeSymSubstituter from a traverser to
transformer. It now aligns tree nodes that contain names to the symbol name that was substituted. Before this change identifiers may refer to one symbol, while the name they carry would resovlve to another one.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala25
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala3
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala6
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala16
4 files changed, 32 insertions, 18 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 9097dd460e..3640b6825b 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -935,19 +935,34 @@ trait Trees extends reflect.generic.Trees { self: SymbolTable =>
lazy val EmptyTreeTypeSubstituter = new TreeTypeSubstituter(List(), List())
- class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Traverser {
+ /** Substitute symbols in 'from' with symbols in 'to'. Returns a new
+ * tree using the new symbols and whose Ident and Select nodes are
+ * name-consistent with the new symbols.
+ */
+ class TreeSymSubstituter(from: List[Symbol], to: List[Symbol]) extends Transformer {
val symSubst = new SubstSymMap(from, to)
- override def traverse(tree: Tree) {
+ override def transform(tree: Tree): Tree = {
def subst(from: List[Symbol], to: List[Symbol]) {
if (!from.isEmpty)
if (tree.symbol == from.head) tree setSymbol to.head
else subst(from.tail, to.tail)
}
+
if (tree.tpe ne null) tree.tpe = symSubst(tree.tpe)
- if (tree.hasSymbol) subst(from, to)
- super.traverse(tree)
+ if (tree.hasSymbol) {
+ subst(from, to)
+ tree match {
+ case Ident(name0) if tree.symbol != NoSymbol =>
+ treeCopy.Ident(tree, tree.symbol.name)
+ case Select(qual, name0) =>
+ treeCopy.Select(tree, transform(qual), tree.symbol.name)
+ case _ =>
+ super.transform(tree)
+ }
+ } else
+ super.transform(tree)
}
- override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
+ def apply[T <: Tree](tree: T): T = transform(tree).asInstanceOf[T]
override def toString() = "TreeSymSubstituter("+from+","+to+")"
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index dad654c967..f2b896dc96 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -354,8 +354,7 @@ abstract class ExplicitOuter extends InfoTransform
localTyper typed (DEF(method) === {
new ChangeOwnerTraverser(currentOwner, method) traverse guard
- new TreeSymSubstituter(vs, method.paramss.head) traverse guard
- guard
+ new TreeSymSubstituter(vs, method.paramss.head) transform (guard)
})
}
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 0525e6fdbc..936b572caf 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -211,12 +211,12 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
case ldef @ LabelDef(name, params, rhs) =>
if (hasAnswerTypeAnn(tree.tpe)) {
- val sym = currentOwner.newMethod(tree.pos, name)//unit.fresh.newName(tree.pos, "myloopvar"))
+ val sym = currentOwner.newMethod(tree.pos, name)//unit.fresh.newName(tree.pos, "myloopvar")
.setInfo(ldef.symbol.info)
.setFlag(Flags.SYNTHETIC)
- new TreeSymSubstituter(List(ldef.symbol), List(sym)).traverse(rhs)
- val rhsVal = transExpr(rhs, None, getAnswerTypeAnn(tree.tpe))
+ val rhs1 = new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
+ val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe))
val stm1 = localTyper.typed(DefDef(sym, rhsVal))
val expr = localTyper.typed(Apply(Ident(sym), List()))
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
index 6da56f93d4..07a9e5fed5 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveCPSTransform.scala
@@ -288,9 +288,9 @@ abstract class SelectiveCPSTransform extends PluginComponent with
def applyTrivial(ctxValSym: Symbol, body: Tree) = {
- new TreeSymSubstituter(List(vd.symbol), List(ctxValSym)).traverse(body)
+ val body1 = (new TreeSymSubstituter(List(vd.symbol), List(ctxValSym)))(body)
- val body2 = localTyper.typed(atPos(vd.symbol.pos) { body })
+ val body2 = localTyper.typed(atPos(vd.symbol.pos) { body1 })
// in theory it would be nicer to look for an @cps annotation instead
// of testing for Context
@@ -303,10 +303,10 @@ abstract class SelectiveCPSTransform extends PluginComponent with
def applyCombinatorFun(ctxR: Tree, body: Tree) = {
val arg = currentOwner.newValueParameter(ctxR.pos, name).setInfo(tpe)
- new TreeSymSubstituter(List(vd.symbol), List(arg)).traverse(body)
- val fun = localTyper.typed(atPos(vd.symbol.pos) { Function(List(ValDef(arg)), body) }) // types body as well
+ val body1 = (new TreeSymSubstituter(List(vd.symbol), List(arg)))(body)
+ val fun = localTyper.typed(atPos(vd.symbol.pos) { Function(List(ValDef(arg)), body1) }) // types body as well
arg.owner = fun.symbol
- new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body)
+ new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(body1)
// see note about multiple traversals above
@@ -315,12 +315,12 @@ abstract class SelectiveCPSTransform extends PluginComponent with
log("arg.owner: "+arg.owner)
log("fun.tpe:"+fun.tpe)
- log("return type of fun:"+body.tpe)
+ log("return type of fun:"+body1.tpe)
var methodName = "map"
- if (body.tpe != null) {
- if (body.tpe.typeSymbol == Context)
+ if (body1.tpe != null) {
+ if (body1.tpe.typeSymbol == Context)
methodName = "flatMap"
}
else