aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/ast/untpd.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/ast/untpd.scala
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/src/dotty/tools/dotc/ast/untpd.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/ast/untpd.scala562
1 files changed, 562 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/ast/untpd.scala b/compiler/src/dotty/tools/dotc/ast/untpd.scala
new file mode 100644
index 000000000..6c5210287
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/ast/untpd.scala
@@ -0,0 +1,562 @@
+package dotty.tools
+package dotc
+package ast
+
+import core._
+import util.Positions._, Types._, Contexts._, Constants._, Names._, NameOps._, Flags._
+import Denotations._, SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._
+import Decorators._
+import util.Property
+import language.higherKinds
+import collection.mutable.ListBuffer
+
+object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
+
+ // ----- Tree cases that exist in untyped form only ------------------
+
+ trait OpTree extends Tree {
+ def op: Name
+ override def isTerm = op.isTermName
+ override def isType = op.isTypeName
+ }
+
+ /** A typed subtree of an untyped tree needs to be wrapped in a TypedSlice
+ * @param owner The current owner at the time the tree was defined
+ */
+ abstract case class TypedSplice(tree: tpd.Tree)(val owner: Symbol) extends ProxyTree {
+ def forwardTo = tree
+ }
+
+ object TypedSplice {
+ def apply(tree: tpd.Tree)(implicit ctx: Context): TypedSplice =
+ new TypedSplice(tree)(ctx.owner) {}
+ }
+
+ /** mods object name impl */
+ case class ModuleDef(name: TermName, impl: Template)
+ extends MemberDef {
+ type ThisTree[-T >: Untyped] <: Trees.NameTree[T] with Trees.MemberDef[T] with ModuleDef
+ def withName(name: Name)(implicit ctx: Context) = cpy.ModuleDef(this)(name.toTermName, impl)
+ }
+
+ case class ParsedTry(expr: Tree, handler: Tree, finalizer: Tree) extends TermTree
+
+ case class SymbolLit(str: String) extends TermTree
+
+ /** An interpolated string
+ * @param segments a list of two element tickets consisting of string literal and argument tree,
+ * possibly with a simple string literal as last element of the list
+ */
+ case class InterpolatedString(id: TermName, segments: List[Tree]) extends TermTree
+
+ case class Function(args: List[Tree], body: Tree) extends Tree {
+ override def isTerm = body.isTerm
+ override def isType = body.isType
+ }
+ /** A function created from a wildcard expression
+ * @param placeHolderParams a list of definitions of synthetic parameters
+ * @param body the function body where wildcards are replaced by
+ * references to synthetic parameters.
+ */
+ class WildcardFunction(placeholderParams: List[ValDef], body: Tree) extends Function(placeholderParams, body)
+
+ case class InfixOp(left: Tree, op: Name, right: Tree) extends OpTree
+ case class PostfixOp(od: Tree, op: Name) extends OpTree
+ case class PrefixOp(op: Name, od: Tree) extends OpTree
+ case class Parens(t: Tree) extends ProxyTree {
+ def forwardTo = t
+ }
+ case class Tuple(trees: List[Tree]) extends Tree {
+ override def isTerm = trees.isEmpty || trees.head.isTerm
+ override def isType = !isTerm
+ }
+ case class Throw(expr: Tree) extends TermTree
+ case class WhileDo(cond: Tree, body: Tree) extends TermTree
+ case class DoWhile(body: Tree, cond: Tree) extends TermTree
+ case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
+ case class ForDo(enums: List[Tree], body: Tree) extends TermTree
+ case class GenFrom(pat: Tree, expr: Tree) extends Tree
+ case class GenAlias(pat: Tree, expr: Tree) extends Tree
+ case class ContextBounds(bounds: TypeBoundsTree, cxBounds: List[Tree]) extends TypTree
+ case class PatDef(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) extends DefTree
+
+ @sharable object EmptyTypeIdent extends Ident(tpnme.EMPTY) with WithoutTypeOrPos[Untyped] {
+ override def isEmpty = true
+ }
+
+ /** A block arising from a right-associative infix operation, where, e.g.
+ *
+ * a +: b
+ *
+ * is expanded to
+ *
+ * { val x = a; b.+:(x) }
+ */
+ class InfixOpBlock(leftOperand: Tree, rightOp: Tree) extends Block(leftOperand :: Nil, rightOp)
+
+ // ----- Modifiers -----------------------------------------------------
+ /** Mod is intended to record syntactic information about modifiers, it's
+ * NOT a replacement of FlagSet.
+ *
+ * For any query about semantic information, check `flags` instead.
+ */
+ sealed abstract class Mod(val flags: FlagSet) extends Positioned
+
+ object Mod {
+ case class Private() extends Mod(Flags.Private)
+
+ case class Protected() extends Mod(Flags.Protected)
+
+ case class Val() extends Mod(Flags.EmptyFlags)
+
+ case class Var() extends Mod(Flags.Mutable)
+
+ case class Implicit(flag: FlagSet = Flags.ImplicitCommon) extends Mod(flag)
+
+ case class Final() extends Mod(Flags.Final)
+
+ case class Sealed() extends Mod(Flags.Sealed)
+
+ case class Override() extends Mod(Flags.Override)
+
+ case class Abstract() extends Mod(Flags.Abstract)
+
+ case class Lazy() extends Mod(Flags.Lazy)
+
+ case class Inline() extends Mod(Flags.Inline)
+
+ case class Type() extends Mod(Flags.EmptyFlags)
+ }
+
+ /** Modifiers and annotations for definitions
+ *
+ * @param flags The set flags
+ * @param privateWithin If a private or protected has is followed by a
+ * qualifier [q], the name q, "" as a typename otherwise.
+ * @param annotations The annotations preceding the modifiers
+ */
+ case class Modifiers (
+ flags: FlagSet = EmptyFlags,
+ privateWithin: TypeName = tpnme.EMPTY,
+ annotations: List[Tree] = Nil,
+ mods: List[Mod] = Nil) extends Positioned with Cloneable {
+
+ def is(fs: FlagSet): Boolean = flags is fs
+ def is(fc: FlagConjunction): Boolean = flags is fc
+
+ def | (fs: FlagSet): Modifiers = withFlags(flags | fs)
+ def & (fs: FlagSet): Modifiers = withFlags(flags & fs)
+ def &~(fs: FlagSet): Modifiers = withFlags(flags &~ fs)
+
+ def toTypeFlags: Modifiers = withFlags(flags.toTypeFlags)
+ def toTermFlags: Modifiers = withFlags(flags.toTermFlags)
+
+ def withFlags(flags: FlagSet) =
+ if (this.flags == flags) this
+ else copy(flags = flags)
+
+ def withAddedMod(mod: Mod): Modifiers =
+ if (mods.exists(_ eq mod)) this
+ else withMods(mods :+ mod)
+
+ def withMods(ms: List[Mod]): Modifiers =
+ if (mods eq ms) this
+ else copy(mods = ms)
+
+ def withAddedAnnotation(annot: Tree): Modifiers =
+ if (annotations.exists(_ eq annot)) this
+ else withAnnotations(annotations :+ annot)
+
+ def withAnnotations(annots: List[Tree]): Modifiers =
+ if (annots eq annotations) this
+ else copy(annotations = annots)
+
+ def withPrivateWithin(pw: TypeName) =
+ if (pw.isEmpty) this
+ else copy(privateWithin = pw)
+
+ def hasFlags = flags != EmptyFlags
+ def hasAnnotations = annotations.nonEmpty
+ def hasPrivateWithin = privateWithin != tpnme.EMPTY
+ }
+
+ @sharable val EmptyModifiers: Modifiers = new Modifiers()
+
+ // ----- TypeTrees that refer to other tree's symbols -------------------
+
+ /** A type tree that gets its type from some other tree's symbol. Enters the
+ * type tree in the References attachment of the `from` tree as a side effect.
+ */
+ abstract class DerivedTypeTree extends TypeTree {
+
+ private var myWatched: Tree = EmptyTree
+
+ /** The watched tree; used only for printing */
+ def watched: Tree = myWatched
+
+ /** Install the derived type tree as a dependency on `original` */
+ def watching(original: DefTree): this.type = {
+ myWatched = original
+ val existing = original.attachmentOrElse(References, Nil)
+ original.putAttachment(References, this :: existing)
+ this
+ }
+
+ /** A hook to ensure that all necessary symbols are completed so that
+ * OriginalSymbol attachments are propagated to this tree
+ */
+ def ensureCompletions(implicit ctx: Context): Unit = ()
+
+ /** The method that computes the type of this tree */
+ def derivedType(originalSym: Symbol)(implicit ctx: Context): Type
+ }
+
+ /** Property key containing TypeTrees whose type is computed
+ * from the symbol in this type. These type trees have marker trees
+ * TypeRefOfSym or InfoOfSym as their originals.
+ */
+ val References = new Property.Key[List[Tree]]
+
+ /** Property key for TypeTrees marked with TypeRefOfSym or InfoOfSym
+ * which contains the symbol of the original tree from which this
+ * TypeTree is derived.
+ */
+ val OriginalSymbol = new Property.Key[Symbol]
+
+ // ------ Creation methods for untyped only -----------------
+
+ def Ident(name: Name): Ident = new Ident(name)
+ def BackquotedIdent(name: Name): BackquotedIdent = new BackquotedIdent(name)
+ def Select(qualifier: Tree, name: Name): Select = new Select(qualifier, name)
+ def SelectWithSig(qualifier: Tree, name: Name, sig: Signature): Select = new SelectWithSig(qualifier, name, sig)
+ def This(qual: Ident): This = new This(qual)
+ def Super(qual: Tree, mix: Ident): Super = new Super(qual, mix)
+ def Apply(fun: Tree, args: List[Tree]): Apply = new Apply(fun, args)
+ def TypeApply(fun: Tree, args: List[Tree]): TypeApply = new TypeApply(fun, args)
+ def Literal(const: Constant): Literal = new Literal(const)
+ def New(tpt: Tree): New = new New(tpt)
+ def Typed(expr: Tree, tpt: Tree): Typed = new Typed(expr, tpt)
+ def NamedArg(name: Name, arg: Tree): NamedArg = new NamedArg(name, arg)
+ def Assign(lhs: Tree, rhs: Tree): Assign = new Assign(lhs, rhs)
+ def Block(stats: List[Tree], expr: Tree): Block = new Block(stats, expr)
+ def If(cond: Tree, thenp: Tree, elsep: Tree): If = new If(cond, thenp, elsep)
+ def Closure(env: List[Tree], meth: Tree, tpt: Tree): Closure = new Closure(env, meth, tpt)
+ def Match(selector: Tree, cases: List[CaseDef]): Match = new Match(selector, cases)
+ def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
+ def Return(expr: Tree, from: Tree): Return = new Return(expr, from)
+ def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree): Try = new Try(expr, cases, finalizer)
+ def SeqLiteral(elems: List[Tree], elemtpt: Tree): SeqLiteral = new SeqLiteral(elems, elemtpt)
+ def JavaSeqLiteral(elems: List[Tree], elemtpt: Tree): JavaSeqLiteral = new JavaSeqLiteral(elems, elemtpt)
+ def Inlined(call: tpd.Tree, bindings: List[MemberDef], expansion: Tree): Inlined = new Inlined(call, bindings, expansion)
+ def TypeTree() = new TypeTree()
+ def SingletonTypeTree(ref: Tree): SingletonTypeTree = new SingletonTypeTree(ref)
+ def AndTypeTree(left: Tree, right: Tree): AndTypeTree = new AndTypeTree(left, right)
+ def OrTypeTree(left: Tree, right: Tree): OrTypeTree = new OrTypeTree(left, right)
+ def RefinedTypeTree(tpt: Tree, refinements: List[Tree]): RefinedTypeTree = new RefinedTypeTree(tpt, refinements)
+ def AppliedTypeTree(tpt: Tree, args: List[Tree]): AppliedTypeTree = new AppliedTypeTree(tpt, args)
+ def PolyTypeTree(tparams: List[TypeDef], body: Tree): PolyTypeTree = new PolyTypeTree(tparams, body)
+ def ByNameTypeTree(result: Tree): ByNameTypeTree = new ByNameTypeTree(result)
+ def TypeBoundsTree(lo: Tree, hi: Tree): TypeBoundsTree = new TypeBoundsTree(lo, hi)
+ def Bind(name: Name, body: Tree): Bind = new Bind(name, body)
+ def Alternative(trees: List[Tree]): Alternative = new Alternative(trees)
+ def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree]): UnApply = new UnApply(fun, implicits, patterns)
+ def ValDef(name: TermName, tpt: Tree, rhs: LazyTree): ValDef = new ValDef(name, tpt, rhs)
+ def DefDef(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: LazyTree): DefDef = new DefDef(name, tparams, vparamss, tpt, rhs)
+ def TypeDef(name: TypeName, rhs: Tree): TypeDef = new TypeDef(name, rhs)
+ def Template(constr: DefDef, parents: List[Tree], self: ValDef, body: LazyTreeList): Template = new Template(constr, parents, self, body)
+ def Import(expr: Tree, selectors: List[untpd.Tree]): Import = new Import(expr, selectors)
+ def PackageDef(pid: RefTree, stats: List[Tree]): PackageDef = new PackageDef(pid, stats)
+ def Annotated(arg: Tree, annot: Tree): Annotated = new Annotated(arg, annot)
+
+ // ------ Additional creation methods for untyped only -----------------
+
+ // def TypeTree(tpe: Type): TypeTree = TypeTree().withType(tpe) todo: move to untpd/tpd
+
+ /** new pre.C[Ts](args1)...(args_n)
+ * ==>
+ * (new pre.C).<init>[Ts](args1)...(args_n)
+ */
+ def New(tpt: Tree, argss: List[List[Tree]])(implicit ctx: Context): Tree = {
+ val (tycon, targs) = tpt match {
+ case AppliedTypeTree(tycon, targs) =>
+ (tycon, targs)
+ case TypedSplice(AppliedTypeTree(tycon, targs)) =>
+ (TypedSplice(tycon), targs map (TypedSplice(_)))
+ case TypedSplice(tpt1: Tree) =>
+ val argTypes = tpt1.tpe.argTypesLo
+ val tycon = tpt1.tpe.withoutArgs(argTypes)
+ def wrap(tpe: Type) = TypeTree(tpe) withPos tpt.pos
+ (wrap(tycon), argTypes map wrap)
+ case _ =>
+ (tpt, Nil)
+ }
+ var prefix: Tree = Select(New(tycon), nme.CONSTRUCTOR)
+ if (targs.nonEmpty) prefix = TypeApply(prefix, targs)
+ ensureApplied((prefix /: argss)(Apply(_, _)))
+ }
+
+ def Block(stat: Tree, expr: Tree): Block =
+ Block(stat :: Nil, expr)
+
+ def Apply(fn: Tree, arg: Tree): Apply =
+ Apply(fn, arg :: Nil)
+
+ def ensureApplied(tpt: Tree) = tpt match {
+ case _: Apply => tpt
+ case _ => Apply(tpt, Nil)
+ }
+
+ def AppliedTypeTree(tpt: Tree, arg: Tree): AppliedTypeTree =
+ AppliedTypeTree(tpt, arg :: Nil)
+
+ def TypeTree(tpe: Type)(implicit ctx: Context): TypedSplice = TypedSplice(TypeTree().withTypeUnchecked(tpe))
+
+ def unitLiteral = Literal(Constant(()))
+
+ def ref(tp: NamedType)(implicit ctx: Context): Tree =
+ TypedSplice(tpd.ref(tp))
+
+ def rootDot(name: Name) = Select(Ident(nme.ROOTPKG), name)
+ def scalaDot(name: Name) = Select(rootDot(nme.scala_), name)
+ def scalaUnit = scalaDot(tpnme.Unit)
+ def scalaAny = scalaDot(tpnme.Any)
+
+ def makeConstructor(tparams: List[TypeDef], vparamss: List[List[ValDef]], rhs: Tree = EmptyTree)(implicit ctx: Context): DefDef =
+ DefDef(nme.CONSTRUCTOR, tparams, vparamss, TypeTree(), rhs)
+
+ def emptyConstructor(implicit ctx: Context): DefDef =
+ makeConstructor(Nil, Nil)
+
+ def makeSelfDef(name: TermName, tpt: Tree)(implicit ctx: Context) =
+ ValDef(name, tpt, EmptyTree).withFlags(PrivateLocal)
+
+ def makeTupleOrParens(ts: List[Tree])(implicit ctx: Context) = ts match {
+ case t :: Nil => Parens(t)
+ case _ => Tuple(ts)
+ }
+
+ def makeTuple(ts: List[Tree])(implicit ctx: Context) = ts match {
+ case t :: Nil => t
+ case _ => Tuple(ts)
+ }
+
+ def makeParameter(pname: TermName, tpe: Tree, mods: Modifiers = EmptyModifiers)(implicit ctx: Context): ValDef =
+ ValDef(pname, tpe, EmptyTree).withMods(mods | Param)
+
+ def makeSyntheticParameter(n: Int = 1, tpt: Tree = TypeTree())(implicit ctx: Context): ValDef =
+ ValDef(nme.syntheticParamName(n), tpt, EmptyTree).withFlags(SyntheticTermParam)
+
+ def lambdaAbstract(tparams: List[TypeDef], tpt: Tree)(implicit ctx: Context) =
+ if (tparams.isEmpty) tpt else PolyTypeTree(tparams, tpt)
+
+ /** A reference to given definition. If definition is a repeated
+ * parameter, the reference will be a repeated argument.
+ */
+ def refOfDef(tree: MemberDef)(implicit ctx: Context) = tree match {
+ case ValDef(_, PostfixOp(_, nme.raw.STAR), _) => repeated(Ident(tree.name))
+ case _ => Ident(tree.name)
+ }
+
+ /** A repeated argument such as `arg: _*` */
+ def repeated(arg: Tree)(implicit ctx: Context) = Typed(arg, Ident(tpnme.WILDCARD_STAR))
+
+// ----- Accessing modifiers ----------------------------------------------------
+
+ abstract class ModsDecorator { def mods: Modifiers }
+
+ implicit class modsDeco(val mdef: MemberDef)(implicit ctx: Context) {
+ def mods = mdef.rawMods
+ }
+
+// --------- Copier/Transformer/Accumulator classes for untyped trees -----
+
+ override val cpy: UntypedTreeCopier = new UntypedTreeCopier
+
+ class UntypedTreeCopier extends TreeCopier {
+
+ def postProcess(tree: Tree, copied: Tree): copied.ThisTree[Untyped] =
+ copied.asInstanceOf[copied.ThisTree[Untyped]]
+
+ def postProcess(tree: Tree, copied: MemberDef): copied.ThisTree[Untyped] = {
+ tree match {
+ case tree: MemberDef => copied.withMods(tree.rawMods)
+ case _ => copied
+ }
+ }.asInstanceOf[copied.ThisTree[Untyped]]
+
+ def ModuleDef(tree: Tree)(name: TermName, impl: Template) = tree match {
+ case tree: ModuleDef if (name eq tree.name) && (impl eq tree.impl) => tree
+ case _ => untpd.ModuleDef(name, impl).withPos(tree.pos)
+ }
+ def ParsedTry(tree: Tree)(expr: Tree, handler: Tree, finalizer: Tree) = tree match {
+ case tree: ParsedTry
+ if (expr eq tree.expr) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree
+ case _ => untpd.ParsedTry(expr, handler, finalizer).withPos(tree.pos)
+ }
+ def SymbolLit(tree: Tree)(str: String) = tree match {
+ case tree: SymbolLit if str == tree.str => tree
+ case _ => untpd.SymbolLit(str).withPos(tree.pos)
+ }
+ def InterpolatedString(tree: Tree)(id: TermName, segments: List[Tree]) = tree match {
+ case tree: InterpolatedString if (id eq tree.id) && (segments eq tree.segments) => tree
+ case _ => untpd.InterpolatedString(id, segments).withPos(tree.pos)
+ }
+ def Function(tree: Tree)(args: List[Tree], body: Tree) = tree match {
+ case tree: Function if (args eq tree.args) && (body eq tree.body) => tree
+ case _ => untpd.Function(args, body).withPos(tree.pos)
+ }
+ def InfixOp(tree: Tree)(left: Tree, op: Name, right: Tree) = tree match {
+ case tree: InfixOp if (left eq tree.left) && (op eq tree.op) && (right eq tree.right) => tree
+ case _ => untpd.InfixOp(left, op, right).withPos(tree.pos)
+ }
+ def PostfixOp(tree: Tree)(od: Tree, op: Name) = tree match {
+ case tree: PostfixOp if (od eq tree.od) && (op eq tree.op) => tree
+ case _ => untpd.PostfixOp(od, op).withPos(tree.pos)
+ }
+ def PrefixOp(tree: Tree)(op: Name, od: Tree) = tree match {
+ case tree: PrefixOp if (op eq tree.op) && (od eq tree.od) => tree
+ case _ => untpd.PrefixOp(op, od).withPos(tree.pos)
+ }
+ def Parens(tree: Tree)(t: Tree) = tree match {
+ case tree: Parens if t eq tree.t => tree
+ case _ => untpd.Parens(t).withPos(tree.pos)
+ }
+ def Tuple(tree: Tree)(trees: List[Tree]) = tree match {
+ case tree: Tuple if trees eq tree.trees => tree
+ case _ => untpd.Tuple(trees).withPos(tree.pos)
+ }
+ def Throw(tree: Tree)(expr: Tree) = tree match {
+ case tree: Throw if expr eq tree.expr => tree
+ case _ => untpd.Throw(expr).withPos(tree.pos)
+ }
+ def WhileDo(tree: Tree)(cond: Tree, body: Tree) = tree match {
+ case tree: WhileDo if (cond eq tree.cond) && (body eq tree.body) => tree
+ case _ => untpd.WhileDo(cond, body).withPos(tree.pos)
+ }
+ def DoWhile(tree: Tree)(body: Tree, cond: Tree) = tree match {
+ case tree: DoWhile if (body eq tree.body) && (cond eq tree.cond) => tree
+ case _ => untpd.DoWhile(body, cond).withPos(tree.pos)
+ }
+ def ForYield(tree: Tree)(enums: List[Tree], expr: Tree) = tree match {
+ case tree: ForYield if (enums eq tree.enums) && (expr eq tree.expr) => tree
+ case _ => untpd.ForYield(enums, expr).withPos(tree.pos)
+ }
+ def ForDo(tree: Tree)(enums: List[Tree], body: Tree) = tree match {
+ case tree: ForDo if (enums eq tree.enums) && (body eq tree.body) => tree
+ case _ => untpd.ForDo(enums, body).withPos(tree.pos)
+ }
+ def GenFrom(tree: Tree)(pat: Tree, expr: Tree) = tree match {
+ case tree: GenFrom if (pat eq tree.pat) && (expr eq tree.expr) => tree
+ case _ => untpd.GenFrom(pat, expr).withPos(tree.pos)
+ }
+ def GenAlias(tree: Tree)(pat: Tree, expr: Tree) = tree match {
+ case tree: GenAlias if (pat eq tree.pat) && (expr eq tree.expr) => tree
+ case _ => untpd.GenAlias(pat, expr).withPos(tree.pos)
+ }
+ def ContextBounds(tree: Tree)(bounds: TypeBoundsTree, cxBounds: List[Tree]) = tree match {
+ case tree: ContextBounds if (bounds eq tree.bounds) && (cxBounds eq tree.cxBounds) => tree
+ case _ => untpd.ContextBounds(bounds, cxBounds).withPos(tree.pos)
+ }
+ def PatDef(tree: Tree)(mods: Modifiers, pats: List[Tree], tpt: Tree, rhs: Tree) = tree match {
+ case tree: PatDef if (mods eq tree.mods) && (pats eq tree.pats) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ case _ => untpd.PatDef(mods, pats, tpt, rhs).withPos(tree.pos)
+ }
+ }
+
+ abstract class UntypedTreeMap(cpy: UntypedTreeCopier = untpd.cpy) extends TreeMap(cpy) {
+ override def transform(tree: Tree)(implicit ctx: Context): Tree = tree match {
+ case ModuleDef(name, impl) =>
+ cpy.ModuleDef(tree)(name, transformSub(impl))
+ case ParsedTry(expr, handler, finalizer) =>
+ cpy.ParsedTry(tree)(transform(expr), transform(handler), transform(finalizer))
+ case SymbolLit(str) =>
+ cpy.SymbolLit(tree)(str)
+ case InterpolatedString(id, segments) =>
+ cpy.InterpolatedString(tree)(id, transform(segments))
+ case Function(args, body) =>
+ cpy.Function(tree)(transform(args), transform(body))
+ case InfixOp(left, op, right) =>
+ cpy.InfixOp(tree)(transform(left), op, transform(right))
+ case PostfixOp(od, op) =>
+ cpy.PostfixOp(tree)(transform(od), op)
+ case PrefixOp(op, od) =>
+ cpy.PrefixOp(tree)(op, transform(od))
+ case Parens(t) =>
+ cpy.Parens(tree)(transform(t))
+ case Tuple(trees) =>
+ cpy.Tuple(tree)(transform(trees))
+ case Throw(expr) =>
+ cpy.Throw(tree)(transform(expr))
+ case WhileDo(cond, body) =>
+ cpy.WhileDo(tree)(transform(cond), transform(body))
+ case DoWhile(body, cond) =>
+ cpy.DoWhile(tree)(transform(body), transform(cond))
+ case ForYield(enums, expr) =>
+ cpy.ForYield(tree)(transform(enums), transform(expr))
+ case ForDo(enums, body) =>
+ cpy.ForDo(tree)(transform(enums), transform(body))
+ case GenFrom(pat, expr) =>
+ cpy.GenFrom(tree)(transform(pat), transform(expr))
+ case GenAlias(pat, expr) =>
+ cpy.GenAlias(tree)(transform(pat), transform(expr))
+ case ContextBounds(bounds, cxBounds) =>
+ cpy.ContextBounds(tree)(transformSub(bounds), transform(cxBounds))
+ case PatDef(mods, pats, tpt, rhs) =>
+ cpy.PatDef(tree)(mods, transform(pats), transform(tpt), transform(rhs))
+ case _ =>
+ super.transform(tree)
+ }
+ }
+
+ abstract class UntypedTreeAccumulator[X] extends TreeAccumulator[X] {
+ override def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = tree match {
+ case ModuleDef(name, impl) =>
+ this(x, impl)
+ case ParsedTry(expr, handler, finalizer) =>
+ this(this(this(x, expr), handler), finalizer)
+ case SymbolLit(str) =>
+ x
+ case InterpolatedString(id, segments) =>
+ this(x, segments)
+ case Function(args, body) =>
+ this(this(x, args), body)
+ case InfixOp(left, op, right) =>
+ this(this(x, left), right)
+ case PostfixOp(od, op) =>
+ this(x, od)
+ case PrefixOp(op, od) =>
+ this(x, od)
+ case Parens(t) =>
+ this(x, t)
+ case Tuple(trees) =>
+ this(x, trees)
+ case Throw(expr) =>
+ this(x, expr)
+ case WhileDo(cond, body) =>
+ this(this(x, cond), body)
+ case DoWhile(body, cond) =>
+ this(this(x, body), cond)
+ case ForYield(enums, expr) =>
+ this(this(x, enums), expr)
+ case ForDo(enums, body) =>
+ this(this(x, enums), body)
+ case GenFrom(pat, expr) =>
+ this(this(x, pat), expr)
+ case GenAlias(pat, expr) =>
+ this(this(x, pat), expr)
+ case ContextBounds(bounds, cxBounds) =>
+ this(this(x, bounds), cxBounds)
+ case PatDef(mods, pats, tpt, rhs) =>
+ this(this(this(x, pats), tpt), rhs)
+ case TypedSplice(tree) =>
+ this(x, tree)
+ case _ =>
+ super.foldOver(x, tree)
+ }
+ }
+
+ /** Fold `f` over all tree nodes, in depth-first, prefix order */
+ class UntypedDeepFolder[X](f: (X, Tree) => X) extends UntypedTreeAccumulator[X] {
+ def apply(x: X, tree: Tree)(implicit ctx: Context): X = foldOver(f(x, tree), tree)
+ }
+}