summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-09-18 07:48:57 -0700
committerPaul Phillips <paulp@improving.org>2013-09-18 12:13:06 -0700
commitf7a315adf63fdac2a7f95f87b88e03d4139af863 (patch)
tree6486f3d8f7bb4a462497b170ab84c65784669b29 /src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
parent1c8bbd7ec5b8859f75abfbc4e70482dede2b7007 (diff)
downloadscala-f7a315adf63fdac2a7f95f87b88e03d4139af863.tar.gz
scala-f7a315adf63fdac2a7f95f87b88e03d4139af863.tar.bz2
scala-f7a315adf63fdac2a7f95f87b88e03d4139af863.zip
SI-7854, SI-6768 better parsing/positioning in parser
The parser hole I found while working on the generated positions serves as the umbrella for a host of improvements. Upgraded positions assigned during some specific challenging situations mostly involving the creation of synthetic trees, e.g. for comprehensions and closures. While doing so improved some error messages. Eliminated some of the most glaring duplication in the parser. It's written like there is some payoff associated with being spectacularly imperative. Not so far.
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala43
1 files changed, 18 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 91ff530e05..976e578afd 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -206,22 +206,21 @@ abstract class TreeBuilder {
}
/** Create tree representing a while loop */
- def makeWhile(startPos: Int, cond: Tree, body: Tree): Tree = {
- val lname = freshTermName(nme.WHILE_PREFIX)
- def default = wrappingPos(List(cond, body)) match {
- case p if p.isDefined => p.endOrPoint
- case _ => startPos
- }
- val continu = atPos(o2p(body.pos pointOrElse default)) { Apply(Ident(lname), Nil) }
- val rhs = If(cond, Block(List(body), continu), Literal(Constant(())))
- LabelDef(lname, Nil, rhs)
+ def makeWhile(cond: Tree, body: Tree): Tree = {
+ val lname = freshTermName(nme.WHILE_PREFIX)
+ val continu = atPos(cond.pos.focus)(Apply(Ident(lname), Nil))
+ val rhs = atPos(cond.pos union body.pos)(If(cond, atPos(body.pos)(Block(body :: Nil, continu)), Literal(Constant(()))))
+
+ atPos(rhs.pos)(LabelDef(lname, Nil, rhs))
}
/** Create tree representing a do-while loop */
def makeDoWhile(lname: TermName, body: Tree, cond: Tree): Tree = {
- val continu = Apply(Ident(lname), Nil)
- val rhs = Block(List(body), If(cond, continu, Literal(Constant(()))))
- LabelDef(lname, Nil, rhs)
+ val continu = atPos(cond.pos.focus)(Apply(Ident(lname), Nil))
+ val condition = atPos(cond.pos)(If(cond, continu, Literal(Constant(()))))
+ val rhs = atPos(cond.pos union body.pos)(Block(body :: Nil, condition))
+
+ atPos(rhs.pos)(LabelDef(lname, Nil, rhs))
}
/** Create block of statements `stats` */
@@ -313,19 +312,13 @@ abstract class TreeBuilder {
* The closure is assigned a transparent position with the point at pos.point and
* the limits given by pat and body.
*/
- def makeClosure(pos: Position, pat: Tree, body: Tree): Tree = {
- def splitpos = wrappingPos(List(pat, body)).withPoint(pos.point).makeTransparent
- matchVarPattern(pat) match {
- case Some((name, tpt)) =>
- Function(
- List(atPos(pat.pos) { ValDef(Modifiers(PARAM), name.toTermName, tpt, EmptyTree) }),
- body) setPos splitpos
- case None =>
- atPos(splitpos) {
- makeVisitor(List(CaseDef(pat, EmptyTree, body)), checkExhaustive = false)
- }
+ def makeClosure(pos: Position, pat: Tree, body: Tree): Tree =
+ atPos((pos union pat.pos union body.pos).makeTransparent) {
+ matchVarPattern(pat) match {
+ case Some((name, tpt)) => Function(atPos(pat.pos)(ValDef(Modifiers(PARAM), name.toTermName, tpt, EmptyTree)) :: Nil, body)
+ case None => makeVisitor(CaseDef(pat, body) :: Nil, checkExhaustive = false)
+ }
}
- }
/* Make an application qual.meth(pat => body) positioned at `pos`.
*/
@@ -503,7 +496,7 @@ abstract class TreeBuilder {
tmp, TypeTree(), matchExpr)
}
var cnt = 0
- val restDefs = for ((vname, tpt, pos) <- vars) yield atPos(pos) {
+ val restDefs = for ((vname, tpt, pos) <- vars) yield atPos(pos.focus) {
cnt += 1
ValDef(mods, vname.toTermName, tpt, Select(Ident(tmp), newTermName("_" + cnt)))
}