aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/parsing/TreeBuilder.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-30 18:02:10 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-30 18:02:10 +0200
commitad80e82469b6fe298a5cbdb0beac736fc01ec5fb (patch)
tree8a60eecfed1bb89708c8fda16e59c846b8f3f6a1 /src/dotty/tools/dotc/parsing/TreeBuilder.scala
parent273873d09c2e0e5080612a7f8a40cab138b41daa (diff)
downloaddotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.tar.gz
dotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.tar.bz2
dotty-ad80e82469b6fe298a5cbdb0beac736fc01ec5fb.zip
New tree organization, with untyped trees that closely model source.
Diffstat (limited to 'src/dotty/tools/dotc/parsing/TreeBuilder.scala')
-rw-r--r--src/dotty/tools/dotc/parsing/TreeBuilder.scala127
1 files changed, 60 insertions, 67 deletions
diff --git a/src/dotty/tools/dotc/parsing/TreeBuilder.scala b/src/dotty/tools/dotc/parsing/TreeBuilder.scala
index 772849e98..0a008af9d 100644
--- a/src/dotty/tools/dotc/parsing/TreeBuilder.scala
+++ b/src/dotty/tools/dotc/parsing/TreeBuilder.scala
@@ -11,20 +11,20 @@ import TreeInfo._
/** Methods for building trees, used in the parser. All the trees
* returned by this class must be untyped.
*/
-class TreeBuilder()(implicit ctx: Context) {
+class TreeBuilder(implicit ctx: Context) {
import untpd._
- def scalaDot(name: Name)(implicit cpos: Position): Select =
+ def scalaDot(name: Name): Select =
Select(new TypedSplice(tpd.Ident(defn.ScalaPackageVal.termRef)), name)
- def scalaAnyRefConstr(implicit cpos: Position) = scalaDot(tpnme.AnyRef)
- def scalaAnyValConstr(implicit cpos: Position) = scalaDot(tpnme.AnyVal)
- def scalaAnyConstr(implicit cpos: Position) = scalaDot(tpnme.Any)
- def scalaUnitConstr(implicit cpos: Position) = scalaDot(tpnme.Unit)
- def productConstr(implicit cpos: Position) = scalaDot(tpnme.Product)
- def productConstrN(n: Int)(implicit cpos: Position) = scalaDot(("Product" + n).toTypeName)
- def serializableConstr(implicit cpos: Position) = scalaDot(tpnme.Serializable)
+ def scalaAnyRefConstr = scalaDot(tpnme.AnyRef)
+ def scalaAnyValConstr = scalaDot(tpnme.AnyVal)
+ def scalaAnyConstr = scalaDot(tpnme.Any)
+ def scalaUnitConstr = scalaDot(tpnme.Unit)
+ def productConstr = scalaDot(tpnme.Product)
+ def productConstrN(n: Int) = scalaDot(("Product" + n).toTypeName)
+ def serializableConstr = scalaDot(tpnme.Serializable)
def convertToTypeName(t: Tree): Tree = ???
@@ -40,16 +40,16 @@ class TreeBuilder()(implicit ctx: Context) {
override def transform(tree: Tree): Tree = tree match {
case Ident(name) if isVarPattern(tree) && name != nme.WILDCARD =>
Bind(
- name, Ident(nme.WILDCARD)(tree.pos.focus)
- )(tree.pos)
+ name, Ident(nme.WILDCARD).withPos(tree.pos.focus)
+ ).withPos(tree.pos)
case Typed(id @ Ident(name), tpt) if isVarPattern(id) && name != nme.WILDCARD =>
Bind(
name,
Typed(
- Ident(nme.WILDCARD)(tree.pos.focus),
+ Ident(nme.WILDCARD).withPos(tree.pos.focus),
transform(tpt)
- )(tree.pos.withStart(tree.pos.point))
- )(tree.pos.withPoint(id.pos.point))
+ ).withPos(tree.pos.withStart(tree.pos.point))
+ ).withPos(tree.pos.withPoint(id.pos.point))
case Apply(fn @ Apply(_, _), args) =>
tree.derivedApply(transform(fn), transform(args))
case Apply(fn, args) =>
@@ -109,15 +109,13 @@ class TreeBuilder()(implicit ctx: Context) {
private def getVariables(tree: Tree): List[VariableInfo] =
getVars(new ListBuffer[VariableInfo], tree).toList
- def byNameApplication(tpe: Tree)(implicit cpos: Position): Tree =
+ def byNameApplication(tpe: Tree): Tree =
AppliedTypeTree(scalaDot(tpnme.BYNAME_PARAM_CLASS), List(tpe))
- def repeatedApplication(tpe: Tree)(implicit cpos: Position): Tree =
+ def repeatedApplication(tpe: Tree): Tree =
AppliedTypeTree(scalaDot(tpnme.REPEATED_PARAM_CLASS), List(tpe))
- def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = {
- val endPos = cpos.endPos
+ def makeTuple(trees: List[Tree])(implicit cpos: Position): Tree = {
def mkPair(t1: Tree, t2: Tree) = {
- implicit val cpos = endPos
if (t1.isType) AppliedTypeTree(scalaDot(tpnme.Pair), List(t1, t2))
else Pair(t1, t2)
}
@@ -129,7 +127,7 @@ class TreeBuilder()(implicit ctx: Context) {
case _ => t
}
- def makeSelfDef(name: TermName, tpt: Tree)(implicit cpos: Position): ValDef =
+ def makeSelfDef(name: TermName, tpt: Tree): ValDef =
ValDef(Modifiers(Private), name, tpt, EmptyTree())
/** If tree is a variable pattern, return its variable info.
@@ -153,7 +151,7 @@ class TreeBuilder()(implicit ctx: Context) {
def makeBinop(isExpr: Boolean, left: Tree, op: TermName, right: Tree, opPos: Position): Tree = {
def mkNamed(args: List[Tree]) =
if (isExpr) args map {
- case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs)(arg.pos)
+ case arg @ Assign(Ident(name), rhs) => NamedArg(name, rhs).withPos(arg.pos)
case arg => arg
} else args
val arguments = right match {
@@ -162,20 +160,20 @@ class TreeBuilder()(implicit ctx: Context) {
}
if (isExpr) {
if (isLeftAssoc(op)) {
- Apply(Select(stripParens(left), op.encode)(opPos), arguments)
+ Apply(Select(stripParens(left), op.encode).withPos(opPos), arguments)
} else {
val x = ctx.freshName().toTermName
Block(
List(ValDef(Modifiers(Synthetic), x, TypeTree(), stripParens(left))),
- Apply(Select(stripParens(right), op.encode)(opPos), List(Ident(x)(left.pos))))
+ Apply(Select(stripParens(right), op.encode).withPos(opPos), List(Ident(x).withPos(left.pos))))
}
} else {
- Apply(Ident(op.encode)(opPos), stripParens(left) :: arguments)
+ Apply(Ident(op.encode).withPos(opPos), stripParens(left) :: arguments)
}
}
/** tpt.<init> */
- def SelectConstructor(tpt: Tree)(implicit cpos: Position): Tree =
+ def SelectConstructor(tpt: Tree): Tree =
Select(tpt, nme.CONSTRUCTOR)
private def splitArgss(constr: Tree, outerArgss: List[List[Tree]]): (Tree, List[List[Tree]]) = constr match {
@@ -186,14 +184,14 @@ class TreeBuilder()(implicit ctx: Context) {
/** new tpt(argss_1)...(argss_n)
* @param npos the position spanning <new tpt>, without any arguments
*/
- def makeNew(parentConstr: Tree)(implicit cpos: Position) = {
+ def makeNew(parentConstr: Tree) = {
val (tpt, argss) = splitArgss(parentConstr, Nil)
New(tpt, argss)
}
/** Create positioned tree representing an object creation <new parents { self => stats }
*/
- def makeNew(templ: Template)(implicit cpos: Position): Tree = {
+ def makeNew(templ: Template): Tree = {
val x = tpnme.ANON_CLASS
val nu = makeNew(Ident(x))
val clsDef = {
@@ -206,26 +204,26 @@ class TreeBuilder()(implicit ctx: Context) {
/** Create positioned tree representing an object creation <new parents { self => stats }
* @param cpos the position of the new, focus should be the first parent's start.
*/
- def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree])(implicit cpos: Position): Tree = {
+ def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree]): Tree = {
val newPos = Position(cpos.start, cpos.point)
val clsPos = Position(cpos.point, cpos.end)
if (parents.isEmpty)
- makeNew(List(scalaAnyRefConstr(newPos.endPos)), self, stats)
+ makeNew(List(scalaAnyRefConstr.withPos(newPos.endPos)), self, stats)
else if (parents.tail.isEmpty && stats.isEmpty)
makeNew(parents.head)
else {
val x = tpnme.ANON_CLASS
- val nu = makeNew(Ident(x)(newPos))(newPos)
+ val nu = makeNew(Ident(x).withPos(newPos)).withPos(newPos)
val clsDef = {
implicit val cpos = clsPos
- ClassDef(Modifiers(Final), x, Nil, Template(parents, self, stats))
+ ClassDef(Modifiers(Final), x, Nil, Template(???, parents, self, stats))
}
Block(clsDef, nu)
}
}
/** Create a tree representing an assignment <lhs = rhs> */
- def makeAssign(lhs: Tree, rhs: Tree)(implicit cpos: Position): Tree = lhs match {
+ def makeAssign(lhs: Tree, rhs: Tree): Tree = lhs match {
case Apply(fn, args) =>
Apply(Select(fn, nme.update), args :+ rhs)
case _ =>
@@ -237,35 +235,35 @@ class TreeBuilder()(implicit ctx: Context) {
if (tps.tail.isEmpty) tps.head
else CompoundTypeTree(Template(tps, emptyValDef, Nil))*/
- private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree)(implicit cpos: Position) = {
- val ldef = DefDef(Modifiers(Label)(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs)
+ private def labelDefAndCall(lname: TermName, rhs: Tree, call: Tree) = {
+ val ldef = DefDef(Modifiers(Label).withPos(cpos.startPos), lname, Nil, ListOfNil, TypeTree(), rhs)
Block(ldef, call)
}
- private def labelCall(lname: TermName)(implicit cpos: Position): Apply =
+ private def labelCall(lname: TermName): Apply =
Apply(Ident(lname), Nil)
/** Create tree representing a while loop */
- def makeWhile(lname: TermName, cond: Tree, body: Tree)(implicit cpos: Position): Tree = {
- val continu = labelCall(lname)((cond.pos union body.pos).endPos)
+ def makeWhile(lname: TermName, cond: Tree, body: Tree): Tree = {
+ val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos)
val rhs = {
implicit val cpos = NoPosition
- If(cond, Block(body, continu), Literal(Constant())(continu.pos))
+ If(cond, Block(body, continu), Literal(Constant()).withPos(continu.pos))
}
labelDefAndCall(lname, rhs, continu)
}
/** Create tree representing a do-while loop */
- def makeDoWhile(lname: TermName, body: Tree, cond: Tree)(implicit cpos: Position): Tree = {
- val continu = labelCall(lname)((cond.pos union body.pos).endPos)
- val rhs = Block(body, If(cond, continu, Literal(Constant())(continu.pos)))
+ def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = {
+ val continu = labelCall(lname).withPos((cond.pos union body.pos).endPos)
+ val rhs = Block(body, If(cond, continu, Literal(Constant()).withPos(continu.pos)))
labelDefAndCall(lname, rhs, continu)
}
/** Create block of statements `stats` */
- def makeBlock(stats: List[Tree])(implicit cpos: Position): Tree =
+ def makeBlock(stats: List[Tree]): Tree =
if (stats.isEmpty) Literal(Constant())
- else if (!stats.last.isTerm) Block(stats, Literal(Constant())(cpos.endPos))
+ else if (!stats.last.isTerm) Block(stats, Literal(Constant()).withPos(cpos.endPos))
else if (stats.length == 1) stats.head
else Block(stats.init, stats.last)
@@ -282,29 +280,24 @@ class TreeBuilder()(implicit ctx: Context) {
}
/** Create tree for for-comprehension generator <pat <- rhs> or <pat = rhs> */
- def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree)(implicit cpos: Position): Enumerator = {
+ def makeGenerator(pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = {
val pat1 = patvarTransformer.transform(pat)
- if (valeq) ValEq(pat1, rhs)(cpos)
- else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true))(cpos)
+ if (valeq) ValEq(pat1, rhs)
+ else ValFrom(pat1, makePatFilter(rhs, pat1, canDrop = true))
}
- def makeParam(pname: TermName, tpe: Tree)(implicit cpos: Position) =
- ValDef(Modifiers(Param)(cpos.startPos), pname, tpe, EmptyTree())
-
- def makeSyntheticParam(pname: TermName)(implicit cpos: Position) =
- ValDef(Modifiers(SyntheticTermParam)(cpos.startPos), pname, TypeTree(), EmptyTree())
/*
def makeSyntheticTypeParam(pname: TypeName, bounds: Tree) =
TypeDef(Modifiers(DEFERRED | SYNTHETIC), pname, Nil, bounds)
*/
abstract class Enumerator { def pos: Position }
- case class ValFrom(pat: Tree, rhs: Tree)(implicit cpos: Position) extends Enumerator {
+ case class ValFrom(pat: Tree, rhs: Tree) extends Enumerator {
val pos = cpos union pat.pos union rhs.pos
}
- case class ValEq(pat: Tree, rhs: Tree)(implicit cpos: Position) extends Enumerator {
+ case class ValEq(pat: Tree, rhs: Tree) extends Enumerator {
val pos = cpos union pat.pos union rhs.pos
}
- case class Filter(test: Tree)(implicit cpos: Position) extends Enumerator {
+ case class Filter(test: Tree) extends Enumerator {
val pos = cpos union test.pos
}
@@ -362,18 +355,18 @@ class TreeBuilder()(implicit ctx: Context) {
* The closure is assigned a transparent position with the point at pos.point and
* the limits given by pat and body.
*/
- def makeClosure(pat: Tree, body: Tree)(implicit cpos: Position): Tree =
+ def makeClosure(pat: Tree, body: Tree): Tree =
matchVarPattern(pat) match {
case Some(VariableInfo(name, tpt, pos)) =>
- Function(ValDef(Modifiers(Param)(cpos.startPos), name.toTermName, tpt, EmptyTree())(pos), body)
+ Function(ValDef(Modifiers(Param).withPos(cpos.startPos), name.toTermName, tpt, EmptyTree()).withPos(pos), body)
case None =>
makeVisitor(List(CaseDef(pat, EmptyTree(), body)), checkExhaustive = false)
}
/** Make an application qual.meth(pat => body) positioned at `pos`.
*/
- def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree)(implicit cpos: Position): Tree =
- Apply(Select(qual, meth)(NoPosition), makeClosure(pat, body))
+ def makeCombination(meth: TermName, qual: Tree, pat: Tree, body: Tree): Tree =
+ Apply(Select(qual, meth).withPos(NoPosition), makeClosure(pat, body))
/** Optionally, if pattern is a `Bind`, the bound name, otherwise None.
*/
@@ -392,18 +385,18 @@ class TreeBuilder()(implicit ctx: Context) {
/** A reference to the name bound in Bind `pat`.
*/
def makeValue(pat: Tree): Tree = pat match {
- case Bind(name, _) => Ident(name)(pat.pos.focus)
+ case Bind(name, _) => Ident(name).withPos(pat.pos.focus)
}
enums match {
case (enum @ ValFrom(pat, rhs)) :: Nil =>
- makeCombination(mapName, rhs, pat, body)(enum.pos)
+ makeCombination(mapName, rhs, pat, body).withPos(enum.pos)
case ValFrom(pat, rhs) :: (rest @ (ValFrom( _, _) :: _)) =>
makeCombination(flatMapName, rhs, pat,
makeFor(mapName, flatMapName, rest, body))
case (enum @ ValFrom(pat, rhs)) :: Filter(test) :: rest =>
makeFor(mapName, flatMapName,
- ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test))(enum.pos) :: rest,
+ ValFrom(pat, makeCombination(nme.withFilter, rhs, pat, test)) :: rest,
body)
case (enum @ ValFrom(pat, rhs)) :: rest =>
val (valeqs, rest1) = rest.span(_.isInstanceOf[ValEq])
@@ -416,7 +409,7 @@ class TreeBuilder()(implicit ctx: Context) {
val ids = (defpat1 :: defpats) map makeValue
val rhs1 = makeForYield(ValFrom(defpat1, rhs) :: Nil, Block(pdefs, makeTuple(ids)))
val allpats = pat :: pats
- val vfrom1 = ValFrom(makeTuple(allpats), rhs1)(enum.pos)
+ val vfrom1 = ValFrom(makeTuple(allpats), rhs1)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
case _ =>
EmptyTree() //may happen for erroneous input
@@ -450,7 +443,7 @@ class TreeBuilder()(implicit ctx: Context) {
if (canDrop) mkAnnotated(defn.DropIfRedundantAnnot, id)
else if (!checkExhaustive) mkAnnotated(defn.UncheckedAnnot, id)
else id
- Function(List(makeSyntheticParam(x)), Match(sel, cases))
+ Function(List(untpd.syntheticParameter(x)), Match(sel, cases))
}
/** Create tree for case definition <case pat if guard => rhs> */
@@ -464,7 +457,7 @@ class TreeBuilder()(implicit ctx: Context) {
/** Create tree for pattern definition <mods val pat0 = rhs> */
def makePatDef(mods: Modifiers, pat: Tree, rhs: Tree, varsArePatterns: Boolean = false): List[Tree] = matchVarPattern(pat) match {
case Some(VariableInfo(name, tpt, pos)) if varsArePatterns =>
- ValDef(mods, name.toTermName, tpt, rhs)(pos) :: Nil // point comes from pat.pos
+ ValDef(mods, name.toTermName, tpt, rhs).withPos(pos) :: Nil // point comes from pat.pos
case _ =>
// in case there is exactly one variable x_1 in pattern
@@ -494,7 +487,7 @@ class TreeBuilder()(implicit ctx: Context) {
(ok, rhsUnchecked)
}
val vars = getVariables(pat1)
- val ids = vars map (v => Ident(v.name)(v.pos))
+ val ids = vars map (v => Ident(v.name).withPos(v.pos))
val caseDef = CaseDef(pat1, EmptyTree(), makeTuple(ids))
val matchExpr = Match(rhs1, caseDef :: Nil)
vars match {
@@ -511,14 +504,14 @@ class TreeBuilder()(implicit ctx: Context) {
implicit val cpos = pos.focus
Select(Ident(tmpName), ("_" + n).toTermName)
}
- ValDef(mods, vname.toTermName, tpt, rhs)(pos)
+ ValDef(mods, vname.toTermName, tpt, rhs).withPos(pos)
}
firstDef :: restDefs
}
}
/** Create a tree representing the function type (argtpes) => restpe */
- def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree)(implicit cpos: Position): Tree =
+ def makeFunctionTypeTree(argtpes: List[Tree], restpe: Tree): Tree =
AppliedTypeTree(scalaDot(("Function" + argtpes.length).toTypeName), argtpes ::: List(restpe))
/** Append implicit parameter section if `contextBounds` nonempty */