aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-02-22 18:05:38 +0100
committerMartin Odersky <odersky@gmail.com>2013-02-22 18:05:38 +0100
commita0bbaa8f42b16274071b30a8f1d6ad23a4ee9584 (patch)
treefe00a968cb9b19f1997c54dfc0359737fb806fd6 /src
parent49931062dfa6785bc9a7af6350812e5a7dbc546d (diff)
downloaddotty-a0bbaa8f42b16274071b30a8f1d6ad23a4ee9584.tar.gz
dotty-a0bbaa8f42b16274071b30a8f1d6ad23a4ee9584.tar.bz2
dotty-a0bbaa8f42b16274071b30a8f1d6ad23a4ee9584.zip
Changed meaning of DefTree/isDef, plus other Tree changes
isDef now means: Defines a new symbol. Consequently, templates are DefTrees (because they define LocalDummy), but package clauses are not. DefTrees are now pickier about the names they accept. New generic instances of TreeAccumulator: ShallowFolder and DeepFolder.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/Trees.scala60
1 files changed, 39 insertions, 21 deletions
diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala
index 4f739ced1..7a6884bb6 100644
--- a/src/dotty/tools/dotc/core/Trees.scala
+++ b/src/dotty/tools/dotc/core/Trees.scala
@@ -86,7 +86,7 @@ object Trees {
/** Is this a legal part of a pattern which is not at the same time a term? */
def isPattern: Boolean = false
- /** Does this tree represent a definition or declaration? */
+ /** Does this tree define a new symbol that is not defined elsewhere? */
def isDef: Boolean = false
/** Is this tree either the empty tree or the empty ValDef? */
@@ -168,8 +168,8 @@ object Trees {
override def isTerm = name.isTermName
}
- /** Tree represents a definition */
- abstract class DefTree[T] extends NameTree[T] {
+ /** Tree defines a new symbol */
+ trait DefTree[T] extends SymTree[T] {
type ThisTree[T] <: DefTree[T]
override def isDef = true
}
@@ -390,7 +390,7 @@ object Trees {
/** name @ body */
case class Bind[T](name: Name, body: Tree[T])(implicit cpos: Position)
- extends DefTree[T] with PatternTree[T] {
+ extends NameTree[T] with DefTree[T] with PatternTree[T] {
type ThisTree[T] = Bind[T]
val pos = cpos union body.pos
}
@@ -410,43 +410,43 @@ object Trees {
}
/** mods val name: tpt = rhs */
- case class ValDef[T](mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position)
- extends DefTree[T] {
+ case class ValDef[T](mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position)
+ extends NameTree[T] with DefTree[T] {
type ThisTree[T] = ValDef[T]
val pos = cpos union tpt.pos union rhs.pos
}
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
- case class DefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position)
- extends DefTree[T] {
+ case class DefDef[T](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit cpos: Position)
+ extends NameTree[T] with DefTree[T] {
type ThisTree[T] = DefDef[T]
val pos = (unionPos(cpos union tpt.pos union rhs.pos, tparams) /: vparamss)(unionPos)
}
- class ImplicitDefDef[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) {
- override def copy[T](mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) =
+ class ImplicitDefDef[T](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) extends DefDef[T](mods, name, tparams, vparamss, tpt, rhs) {
+ override def copy[T](mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T])(implicit pos: Position) =
new ImplicitDefDef[T](mods, name, tparams, vparamss, tpt, rhs)
}
/** mods type name = rhs or
* mods type name >: lo <: hi, if rhs = TypeBoundsTree(lo, hi)
*/
- case class TypeDef[T](mods: Modifiers[T], name: Name, rhs: Tree[T])(implicit cpos: Position)
- extends DefTree[T] {
+ case class TypeDef[T](mods: Modifiers[T], name: TypeName, rhs: Tree[T])(implicit cpos: Position)
+ extends NameTree[T] with DefTree[T] {
type ThisTree[T] = TypeDef[T]
val pos = cpos union rhs.pos
}
/** extends parents { self => body } */
case class Template[T](parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])(implicit cpos: Position)
- extends SymTree[T] {
+ extends DefTree[T] {
type ThisTree[T] = Template[T]
val pos = unionPos(unionPos(cpos union self.pos, parents), body)
}
/** mods class name[tparams] impl */
case class ClassDef[T](mods: Modifiers[T], name: TypeName, tparams: List[TypeDef[T]], impl: Template[T])(implicit cpos: Position)
- extends DefTree[T] {
+ extends NameTree[T] with DefTree[T] {
type ThisTree[T] = ClassDef[T]
val pos = unionPos(cpos union impl.pos, tparams)
}
@@ -463,10 +463,10 @@ object Trees {
/** package pid { stats } */
case class PackageDef[T](pid: RefTree[T], stats: List[Tree[T]])(implicit cpos: Position)
- extends DefTree[T] {
+ extends ProxyTree[T] {
type ThisTree[T] = PackageDef[T]
val pos = unionPos(cpos union pid.pos, stats)
- override def name = pid.name
+ def forwardTo = pid
}
/** arg @annot */
@@ -525,13 +525,15 @@ object Trees {
/** mods object name impl */
case class ModuleDef(mods: Modifiers[Nothing], name: TermName, impl: Template[Nothing])(implicit cpos: Position)
- extends DefTree[Nothing] {
+ extends NameTree[Nothing] with DefTree[Nothing] {
+ type ThisTree[T] <: NameTree[T] with DefTree[T] with ModuleDef
val pos = cpos union impl.pos
}
/** (vparams) => body */
case class Function(vparams: List[ValDef[Nothing]], body: Tree[Nothing])(implicit cpos: Position)
extends TermTree[Nothing] {
+ type ThisTree[T] <: TermTree[T] with Function
val pos = unionPos(cpos union body.pos, vparams)
}
@@ -668,15 +670,15 @@ object Trees {
case tree: UnApply[_] if (fun eq tree.fun) && (args eq tree.args) => tree
case _ => UnApply(fun, args).copyAttr(tree)
}
- def derivedValDef(mods: Modifiers[T], name: Name, tpt: Tree[T], rhs: Tree[T]): ValDef[T] = tree match {
+ def derivedValDef(mods: Modifiers[T], name: TermName, tpt: Tree[T], rhs: Tree[T]): ValDef[T] = tree match {
case tree: ValDef[_] if (mods == tree.mods) && (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
case _ => ValDef(mods, name, tpt, rhs).copyAttr(tree)
}
- def derivedDefDef(mods: Modifiers[T], name: Name, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]): DefDef[T] = tree match {
+ def derivedDefDef(mods: Modifiers[T], name: TermName, tparams: List[TypeDef[T]], vparamss: List[List[ValDef[T]]], tpt: Tree[T], rhs: Tree[T]): DefDef[T] = tree match {
case tree: DefDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
case _ => DefDef(mods, name, tparams, vparamss, tpt, rhs).copyAttr(tree)
}
- def derivedTypeDef(mods: Modifiers[T], name: Name, rhs: Tree[T]): TypeDef[T] = tree match {
+ def derivedTypeDef(mods: Modifiers[T], name: TypeName, rhs: Tree[T]): TypeDef[T] = tree match {
case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (rhs eq tree.rhs) => tree
case _ => TypeDef(mods, name, rhs).copyAttr(tree)
}
@@ -806,7 +808,7 @@ object Trees {
def transformSub(tree: Tree[T], c: C): tree.ThisTree[T] =
transform(tree, c).asInstanceOf[tree.ThisTree[T]]
def transformSub[TT <: Tree[T]](trees: List[TT], c: C): List[TT] =
- (trees mapConserve (transformSub(_, c))).asInstanceOf[List[TT]]
+ transform(trees, c).asInstanceOf[List[TT]]
type Plugins >: Null
def plugins: Plugins = null
@@ -950,4 +952,20 @@ object Trees {
}
}
}
+
+ /** Fold `f` over all tree nodes, in depth-first, prefix order */
+ class DeepFolder[T, U](f: (T, Tree[U]) => T) extends TreeAccumulator[T, U] {
+ def apply(x: T, tree: Tree[U]): T = foldOver(f(x, tree), tree)
+ }
+
+ /** Fold `f` over all tree nodes, in depth-first, prefix order, but don't visit
+ * subtrees where `f` returns a different result for the root, i.e. `f(x, root) ne x`.
+ */
+ class ShallowFolder[T, U](f: (T, Tree[U]) => T) extends TreeAccumulator[T, U] {
+ def apply(x: T, tree: Tree[U]): T = {
+ val x1 = f(x, tree)
+ if (x1.asInstanceOf[AnyRef] ne x1.asInstanceOf[AnyRef]) x1
+ else foldOver(x1, tree)
+ }
+ }
}