summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/ast
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-07-30 07:41:22 +0000
committerMartin Odersky <odersky@gmail.com>2009-07-30 07:41:22 +0000
commitdb045cb8ddbd725fc545da5296bf0cdd722c20ce (patch)
treeba2b4458a1b61e4d90beb917c087458dc117f860 /src/compiler/scala/tools/nsc/ast
parent74a6eeaf0948cbf59e327108c47aa41013c7fb9f (diff)
downloadscala-db045cb8ddbd725fc545da5296bf0cdd722c20ce.tar.gz
scala-db045cb8ddbd725fc545da5296bf0cdd722c20ce.tar.bz2
scala-db045cb8ddbd725fc545da5296bf0cdd722c20ce.zip
rewrite of positions in compiler
Diffstat (limited to 'src/compiler/scala/tools/nsc/ast')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala23
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala105
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/Parsers.scala79
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala101
5 files changed, 140 insertions, 175 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index 2baf578914..edfca57be6 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -244,7 +244,7 @@ abstract class TreeGen
// var m$: T = null; or, if class member: local var m$: T = _;
def mkModuleVarDef(accessor: Symbol) = {
- val mvar = accessor.owner.newVariable(accessor.pos.toSynthetic, nme.moduleVarName(accessor.name))
+ val mvar = accessor.owner.newVariable(accessor.pos.focus, nme.moduleVarName(accessor.name))
.setInfo(accessor.tpe.finalResultType)
.setFlag(MODULEVAR);
if (mvar.owner.isClass) {
@@ -305,11 +305,11 @@ abstract class TreeGen
if (treeInfo.isPureExpr(expr)) {
within(() => expr);
} else {
- val temp = owner.newValue(expr.pos.toSynthetic, unit.fresh.newName(expr.pos, "ev$"))
- .setFlag(SYNTHETIC).setInfo(expr.tpe);
- atPos(expr.pos) {
- Block(List(ValDef(temp, expr)), within(() => Ident(temp) setType expr.tpe))
- }
+ val temp = owner.newValue(expr.pos.makeTransparent, unit.fresh.newName(expr.pos, "ev$"))
+ .setFlag(SYNTHETIC).setInfo(expr.tpe)
+ val containing = within(() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
+ ensureNonOverlapping(containing, List(expr))
+ Block(List(ValDef(temp, expr)), containing) setPos (containing.pos union expr.pos)
}
def evalOnceAll(exprs: List[Tree], owner: Symbol, unit: CompilationUnit)(within: (List[() => Tree]) => Tree): Tree = {
@@ -319,15 +319,16 @@ abstract class TreeGen
if (treeInfo.isPureExpr(expr)) {
exprs1 += (() => expr)
} else {
- val temp = owner.newValue(expr.pos.toSynthetic, unit.fresh.newName(expr.pos))
+ val temp = owner.newValue(expr.pos.makeTransparent, unit.fresh.newName(expr.pos, "ev$"))
.setFlag(SYNTHETIC).setInfo(expr.tpe)
vdefs += ValDef(temp, expr)
- exprs1 += (() => Ident(temp) setType expr.tpe)
+ exprs1 += (() => Ident(temp) setPos temp.pos.focus setType expr.tpe)
}
}
val prefix = vdefs.toList
- val result = within(exprs1.toList)
- if (prefix.isEmpty) result
- else Block(prefix, result) setPos (prefix.head.pos union result.pos)
+ val containing = within(exprs1.toList)
+ ensureNonOverlapping(containing, exprs)
+ if (prefix.isEmpty) containing
+ else Block(prefix, containing) setPos (prefix.head.pos union containing.pos)
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index c005d0690e..b3f54f453d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -105,7 +105,7 @@ trait Trees {
}
val id = nodeCount
- //assert(id != 225)
+// assert(id != 14427)
nodeCount += 1
private var rawpos: Position = NoPosition
@@ -118,19 +118,16 @@ trait Trees {
def tpe_=(t: Type) = rawtpe = t
def setPos(pos: Position): this.type = {
- pos match {
- case SyntheticAliasPosition(orig) => assert(orig != this)
- case _ =>
- } // !!!
- rawpos = pos;
+ rawpos = pos
+/*
+ for (c <- this.children)
+ if (c.pos.isOpaqueRange && !pos.includes(c.pos)) {
+ assert(false, "non-enclosing positions in "+this)
+ }
+*/
this
}
- def setOriginal(tree: Tree): this.type = tree.pos match {
- case SyntheticAliasPosition(orig) => setOriginal(orig)
- case _ => setPos(if (tree.pos.isDefined) SyntheticAliasPosition(tree) else tree.pos)
- }
-
def setType(tp: Type): this.type = {
/*assert(kindingIrrelevant(tp) || !kindStar || !tp.isHigherKinded,
tp+" should not be higher-kinded");*/
@@ -177,7 +174,7 @@ trait Trees {
/** The direct child trees of this tree
* EmptyTrees are always omitted. Lists are collapsed.
*/
- def children(): List[Tree] = {
+ def children: List[Tree] = {
def subtrees(x: Any): List[Tree] = x match {
case EmptyTree => List()
case t: Tree => List(t)
@@ -252,15 +249,16 @@ trait Trees {
} else false
}
+ /** Make a copy of this tree, keeping all attributes,
+ * except that all positions are focussed (so nothing
+ * in this tree will be found when searching by position).
+ */
def duplicate: this.type =
(duplicator transform this).asInstanceOf[this.type]
def shallowDuplicate: this.type =
((new ShallowDuplicator(this)) transform this).asInstanceOf[this.type]
- def syntheticDuplicate: this.type =
- (syntheticDuplicator transform this).asInstanceOf[this.type]
-
def copyAttrs(tree: Tree): this.type = {
rawpos = tree.rawpos
tpe = tree.tpe
@@ -297,13 +295,9 @@ trait Trees {
private lazy val duplicator = new Transformer {
override val treeCopy = new StrictTreeCopier
- }
-
- private lazy val syntheticDuplicator = new Transformer {
- override val treeCopy = new StrictTreeCopier
override def transform(t: Tree) = {
val t1 = super.transform(t)
- if (t1 ne t) t1.setOriginal(t)
+ if ((t1 ne t) && t1.pos.isRange) t1 setPos t.pos.focus
t1
}
}
@@ -436,7 +430,9 @@ trait Trees {
def ValDef(sym: Symbol, rhs: Tree): ValDef =
atPos(sym.pos) {
- ValDef(Modifiers(sym.flags), sym.name, TypeTree(sym.tpe), rhs) setSymbol sym
+ ValDef(Modifiers(sym.flags), sym.name,
+ TypeTree(sym.tpe) setPos sym.pos.focus,
+ rhs) setSymbol sym
}
def ValDef(sym: Symbol): ValDef = ValDef(sym, EmptyTree)
@@ -473,7 +469,7 @@ trait Trees {
sym.name,
sym.typeParams map TypeDef,
vparamss,
- TypeTree(sym.tpe.finalResultType),
+ TypeTree(sym.tpe.finalResultType) setPos sym.pos.focus,
rhs) setSymbol sym
}
@@ -492,9 +488,7 @@ trait Trees {
/** Abstract type, type parameter, or type alias */
case class TypeDef(mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree)
- extends MemberDef {
- def namePos = pos.offset.map(n => n - name.length).getOrElse(-1)
- }
+ extends MemberDef
/** A TypeDef node which defines given `sym' with given tight hand side `rhs'. */
def TypeDef(sym: Symbol, rhs: Tree): TypeDef =
@@ -603,17 +597,20 @@ trait Trees {
// create parameters for <init> as synthetic trees.
var vparamss1 =
vparamss map (vps => vps.map { vd =>
- atPos(vd) {
+ atPos(vd.pos.focus) {
ValDef(
Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM) | PARAM) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.syntheticDuplicate, vd.rhs.syntheticDuplicate)
+ vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
}})
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val (lvdefs, gvdefs) = List.unzip {
evdefs map {
case vdef @ ValDef(mods, name, tpt, rhs) =>
- val fld = treeCopy.ValDef(vdef.syntheticDuplicate, mods, name, TypeTree() setOriginal tpt, EmptyTree)
+ val fld = treeCopy.ValDef(
+ vdef.duplicate, mods, name,
+ atPos(vdef.pos.focus) { TypeTree() setOriginal tpt setPos tpt.pos.focus }, // atPos in case
+ EmptyTree)
val local = treeCopy.ValDef(vdef, Modifiers(PRESUPER), name, tpt, rhs)
(local, fld)
}
@@ -859,10 +856,11 @@ trait Trees {
case class TypeTree() extends TypTree {
override def symbol = if (tpe == null) null else tpe.typeSymbol
- def original: Tree = pos match {
- case SyntheticAliasPosition(orig) => orig
- case _ => null
- }
+ private var orig: Tree = null // should be EmptyTree?
+
+ def original: Tree = orig
+
+ def setOriginal(tree: Tree): this.type = { orig = tree; setPos(tree.pos); this }
override def isEmpty = (tpe eq null) || tpe == NoType
}
@@ -878,10 +876,6 @@ trait Trees {
case class Annotated(annot: Tree, arg: Tree) extends Tree {
override def isType = arg.isType
override def isTerm = arg.isTerm
- override def setPos(pos: Position) : this.type = {
-// assert(pos.start != 27934, this)
- super.setPos(pos)
- }
}
/** Singleton type, eliminated by RefCheck */
@@ -1706,7 +1700,7 @@ trait Trees {
if (tree.tpe ne null) tree.tpe = typeSubst(tree.tpe)
super.traverse(tree)
}
- override def apply[T <: Tree](tree: T): T = super.apply(tree.syntheticDuplicate)
+ override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeTypeSubstituter("+from+","+to+")"
}
@@ -1724,7 +1718,7 @@ trait Trees {
if (tree.hasSymbol) subst(from, to)
super.traverse(tree)
}
- override def apply[T <: Tree](tree: T): T = super.apply(tree.syntheticDuplicate)
+ override def apply[T <: Tree](tree: T): T = super.apply(tree.duplicate)
override def toString() = "TreeSymSubstituter("+from+","+to+")"
}
@@ -1754,29 +1748,12 @@ trait Trees {
}
}
- object syntheticMaker extends Traverser {
- override def traverse(t: Tree) {
- if (!t.pos.isSynthetic) {
- t setPos t.pos.toSynthetic
- super.traverse(t)
- }
- }
- }
-
def atPos[T <: Tree](pos: Position)(tree: T): T = {
posAssigner.pos = pos
posAssigner.traverse(tree)
tree
}
- def atPos[T <: Tree](original: Tree)(tree: T): T =
- atPos(SyntheticAliasPosition(original))(tree)
-
- def makeSynthetic[T <: Tree](tree: T): T = {
- syntheticMaker.traverse(tree)
- tree
- }
-
class ForeachTreeTraverser(f: Tree => Unit) extends Traverser {
override def traverse(t: Tree) {
f(t)
@@ -1851,23 +1828,5 @@ trait Trees {
def hasSymbol : Boolean
def isTop : Boolean
}
-
- /** A position to be used for synthetic trees that correspond to some original tree
- * @note Trees with synthetic positions may not contain trees with real positions inside them!
- */
- case class SyntheticAliasPosition(original: Tree) extends Position {
- override def isDefined: Boolean = true
- override def isSynthetic: Boolean = true
- override def offset: Option[Int] = original.pos.offset
- override def source: Option[SourceFile] = original.pos.source
- override def start: Int = original.pos.start
- override def point: Int = original.pos.point
- override def end: Int = original.pos.end
- override def underlying = original.pos.underlying
- override def focusStart = original.pos.focusStart
- override def focusPoint = original.pos.focusPoint
- override def focusEnd = original.pos.focusEnd
- override def show = "["+ underlying.show +"]"
- }
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 0c1198cdcf..4f5be7cce0 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -150,7 +150,6 @@ self =>
def o2p(offset: Int): Position
def r2p(start: Int, mid: Int, end: Int): Position
- def t2p(tree: Tree): Position = SyntheticAliasPosition(tree)
//private implicit def p2i(pos: Position) = pos.offset.get
/** whether a non-continuable syntax error has been seen */
@@ -220,7 +219,9 @@ self =>
placeholderTypes = List()
var t = op
if (!placeholderTypes.isEmpty && t.isInstanceOf[AppliedTypeTree]) {
- t = atPos(t.pos) { ExistentialTypeTree(t, placeholderTypes.reverse) }
+ val expos = t.pos
+ ensureNonOverlapping(t, placeholderTypes)
+ t = atPos(expos) { ExistentialTypeTree(t, placeholderTypes.reverse) }
placeholderTypes = List()
}
placeholderTypes = placeholderTypes ::: savedPlaceholderTypes
@@ -342,9 +343,9 @@ self =>
ret
}
- def errorTypeTree = TypeTree().setType(ErrorType).setPos(o2p(in.offset).toSynthetic)
- def errorTermTree = Literal(Constant(null)).setPos(o2p(in.offset).toSynthetic)
- def errorPatternTree = Ident(nme.WILDCARD).setPos(o2p(in.offset).toSynthetic)
+ def errorTypeTree = TypeTree().setType(ErrorType).setPos(o2p(in.offset))
+ def errorTermTree = Literal(Constant(null)).setPos(o2p(in.offset))
+ def errorPatternTree = Ident(nme.WILDCARD).setPos(o2p(in.offset))
/** Check that type parameter is not by name T* */
def checkNotByName(t: Tree) = t match {
@@ -451,13 +452,13 @@ self =>
tree match {
case Ident(name) =>
removeAsPlaceholder(name)
- ValDef(Modifiers(Flags.PARAM), name, TypeTree() setPos o2p(tree.pos.end), EmptyTree)
+ ValDef(Modifiers(Flags.PARAM), name, TypeTree() setPos o2p(tree.pos.endOrPoint), EmptyTree)
case Typed(tree @ Ident(name), tpe) if (tpe.isType) => // get the ident!
removeAsPlaceholder(name)
ValDef(Modifiers(Flags.PARAM), name, tpe, EmptyTree)
case _ =>
syntaxError(tree.pos, "not a legal formal parameter", false)
- ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree setPos o2p(tree.pos.end).toSynthetic, EmptyTree)
+ ValDef(Modifiers(Flags.PARAM), nme.ERROR, errorTypeTree setPos o2p(tree.pos.endOrPoint), EmptyTree)
}
}
@@ -536,7 +537,7 @@ self =>
leftAssoc && prec == precedence(opstack.head.operator))) {
val opinfo = opstack.head
opstack = opstack.tail
- top = atPos(opinfo.operand.pos.start, opinfo.offset) {
+ top = atPos(opinfo.operand.pos.startOrPoint, opinfo.offset) {
makeBinop(isExpr, opinfo.operand, opinfo.operator, top)
}
}
@@ -560,7 +561,7 @@ self =>
def selector(t: Tree): Tree = {
val point = in.offset
//assert(t.pos.isDefined, t)
- Select(t, ident(false)) setPos r2p(t.pos.start, point, in.lastOffset)
+ Select(t, ident(false)) setPos r2p(t.pos.startOrPoint, point, in.lastOffset)
}
/** Path ::= StableId
@@ -613,7 +614,7 @@ self =>
def selectors(t: Tree, typeOK: Boolean, dotOffset: Int): Tree =
if (typeOK && in.token == TYPE) {
in.nextToken()
- atPos(t.pos.start, dotOffset) { SingletonTypeTree(t) }
+ atPos(t.pos.startOrPoint, dotOffset) { SingletonTypeTree(t) }
} else {
val t1 = selector(t)
if (in.token == DOT) { selectors(t1, typeOK, in.skipToken()) }
@@ -774,7 +775,7 @@ self =>
val op = ident()
val tycon = atPos(opOffset) { Ident(op.toTypeName) }
newLineOptWhenFollowing(isTypeIntroToken)
- def mkOp(t1: Tree) = atPos(t.pos.start, opOffset) { AppliedTypeTree(tycon, List(t, t1)) }
+ def mkOp(t1: Tree) = atPos(t.pos.startOrPoint, opOffset) { AppliedTypeTree(tycon, List(t, t1)) }
if (leftAssoc)
infixTypeRest(mkOp(compoundType(isPattern)), isPattern, InfixMode.LeftOp)
else
@@ -797,7 +798,7 @@ self =>
in.nextToken(); ts += annotType(isPattern)
}
newLineOptWhenFollowedBy(LBRACE)
- atPos(t.pos.start) {
+ atPos(t.pos.startOrPoint) {
if (in.token == LBRACE) {
// Warn if they are attempting to refine Unit; we can't be certain it's
// scala.Unit they're refining because at this point all we have is an
@@ -853,12 +854,12 @@ self =>
val hashOffset = in.skipToken()
val nameOffset = in.offset
val name = ident(false)
- val sel = atPos(t.pos.start, if (name == nme.ERROR) hashOffset else nameOffset) {
+ val sel = atPos(t.pos.startOrPoint, if (name == nme.ERROR) hashOffset else nameOffset) {
SelectFromTypeTree(t, name.toTypeName)
}
simpleTypeRest(sel, isPattern)
} else if (in.token == LBRACKET) {
- simpleTypeRest(atPos(t.pos.start) { AppliedTypeTree(t, typeArgs(isPattern, false)) }, isPattern)
+ simpleTypeRest(atPos(t.pos.startOrPoint) { AppliedTypeTree(t, typeArgs(isPattern, false)) }, isPattern)
} else {
t
}
@@ -1046,7 +1047,7 @@ self =>
if (in.token == EQUALS) {
t match {
case Ident(_) | Select(_, _) | Apply(_, _) =>
- t = atPos(t.pos.start, in.skipToken()) { makeAssign(t, expr()) }
+ t = atPos(t.pos.startOrPoint, in.skipToken()) { makeAssign(t, expr()) }
case _ =>
}
} else if (in.token == COLON) {
@@ -1057,7 +1058,7 @@ self =>
val uscorePos = in.skipToken()
if (isIdent && in.name == nme.STAR) {
in.nextToken()
- t = atPos(t.pos.start, colonPos) {
+ t = atPos(t.pos.startOrPoint, colonPos) {
Typed(t, atPos(uscorePos) { Ident(nme.WILDCARD_STAR.toTypeName) })
}
} else {
@@ -1066,13 +1067,13 @@ self =>
} else if (in.token == AT) {
t = (t /: annotations(false, false)) (makeAnnotated)
} else {
- t = atPos(t.pos.start, colonPos) {
+ t = atPos(t.pos.startOrPoint, colonPos) {
val tpt =
if (location == Local) typ() else infixType(false, InfixMode.FirstOp)
if (isWildcard(t))
(placeholderParams: @unchecked) match {
case (vd @ ValDef(mods, name, _, _)) :: rest =>
- placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.syntheticDuplicate, EmptyTree) :: rest
+ placeholderParams = treeCopy.ValDef(vd, mods, name, tpt.duplicate, EmptyTree) :: rest
}
// this does not correspond to syntax, but is necessary to
// accept closures. We might restrict closures to be between {...} only.
@@ -1080,7 +1081,7 @@ self =>
}
}
} else if (in.token == MATCH) {
- t = atPos(t.pos.start, in.skipToken()) {
+ t = atPos(t.pos.startOrPoint, in.skipToken()) {
Match(stripParens(t), surround(LBRACE, RBRACE)(caseClauses(), Nil))
}
}
@@ -1093,7 +1094,7 @@ self =>
case _ => false
}
if (in.token == ARROW && (location != InTemplate || lhsIsTypedParamList)) {
- t = atPos(t.pos.start, in.skipToken()) {
+ t = atPos(t.pos.startOrPoint, in.skipToken()) {
Function(convertToParams(t), if (location != InBlock) expr() else block())
}
}
@@ -1119,7 +1120,7 @@ self =>
val topinfo = opstack.head
opstack = opstack.tail
val od = stripParens(reduceStack(true, base, topinfo.operand, 0, true))
- return atPos(od.pos.start, topinfo.offset) {
+ return atPos(od.pos.startOrPoint, topinfo.offset) {
Select(od, topinfo.operator.encode)
}
}
@@ -1174,9 +1175,9 @@ self =>
case USCORE =>
val start = in.offset
val pname = freshName(o2p(start), "x$")
- val id = atPos(start) (Ident(pname))
in.nextToken()
- val param = atPos(t2p(id)){ makeSyntheticParam(pname) }
+ val id = atPos(start) (Ident(pname))
+ val param = atPos(id.pos.focus){ makeSyntheticParam(pname) }
placeholderParams = param :: placeholderParams
id
case LPAREN =>
@@ -1213,7 +1214,7 @@ self =>
val t1 = stripParens(t)
t1 match {
case Ident(_) | Select(_, _) =>
- val tapp = atPos(t1.pos.start, in.offset) {
+ val tapp = atPos(t1.pos.startOrPoint, in.offset) {
TypeApply(t1, typeArgs(false, true))
}
simpleExprRest(tapp, true)
@@ -1221,7 +1222,7 @@ self =>
t1
}
case LPAREN | LBRACE if (canApply) =>
- val app = atPos(t.pos.start, in.offset) {
+ val app = atPos(t.pos.startOrPoint, in.offset) {
// look for anonymous function application like (f _)(x) and
// translate to (f _).apply(x), bug #460
val sel = t match {
@@ -1234,7 +1235,7 @@ self =>
}
simpleExprRest(app, true)
case USCORE =>
- atPos(t.pos.start, in.skipToken()) {
+ atPos(t.pos.startOrPoint, in.skipToken()) {
Typed(stripParens(t), Function(List(), EmptyTree))
}
case _ =>
@@ -1360,7 +1361,7 @@ self =>
if (in.token == IF) enums += makeFilter(in.offset, guard())
}
- def makeFilter(start: Int, tree: Tree) = Filter(r2p(start, tree.pos.point, tree.pos.end), tree)
+ def makeFilter(start: Int, tree: Tree) = Filter(r2p(start, tree.pos.point, tree.pos.endOrPoint), tree)
/* -------- PATTERNS ------------------------------------------- */
@@ -1398,7 +1399,7 @@ self =>
val p = pattern2(seqOK)
p match {
case Ident(name) if (treeInfo.isVarPattern(p) && in.token == COLON) =>
- atPos(p.pos.start, in.skipToken()) { Typed(p, compoundType(true)) }
+ atPos(p.pos.startOrPoint, in.skipToken()) { Typed(p, compoundType(true)) }
case _ =>
p
}
@@ -1419,7 +1420,7 @@ self =>
pattern3(seqOK)
} else if (treeInfo.isVarPattern(p)) {
in.nextToken()
- atPos(p.pos.start) { Bind(name, pattern3(seqOK)) }
+ atPos(p.pos.startOrPoint) { Bind(name, pattern3(seqOK)) }
} else {
p
}
@@ -1438,7 +1439,7 @@ self =>
val base = opstack
var top = simplePattern(seqOK)
if (seqOK && isIdent && in.name == STAR)
- return atPos(top.pos.start, in.skipToken())(Star(stripParens(top)))
+ return atPos(top.pos.startOrPoint, in.skipToken())(Star(stripParens(top)))
while (isIdent && in.name != BAR) {
top = reduceStack(
@@ -1498,7 +1499,7 @@ self =>
else t
case USCORE =>
in.nextToken()
- atPos(start) { Ident(nme.WILDCARD) }
+ atPos(start, start) { Ident(nme.WILDCARD) }
case CHARLIT | INTLIT | LONGLIT | FLOATLIT | DOUBLELIT |
STRINGLIT | SYMBOLLIT | TRUE | FALSE | NULL =>
atPos(start) { literal(false) }
@@ -1762,7 +1763,7 @@ self =>
val t = typ()
if (isIdent && in.name == STAR) {
in.nextToken()
- atPos(t.pos.start, t.pos.point) {
+ atPos(t.pos.startOrPoint, t.pos.point) {
AppliedTypeTree(
rootScalaDot(nme.REPEATED_PARAM_CLASS_NAME.toTypeName), List(t))
}
@@ -1834,7 +1835,7 @@ self =>
def bound(tok: Int, default: Name): Tree =
if (in.token == tok) { in.nextToken(); typ() }
- else atPos(o2p(in.lastOffset).toSynthetic) { rootScalaDot(default.toTypeName) }
+ else atPos(o2p(in.lastOffset)) { rootScalaDot(default.toTypeName) }
/* -------- DEFS ------------------------------------------- */
@@ -2008,7 +2009,7 @@ self =>
}
trees
}
- (lhs.toList.init flatMap (mkDefs(_, tp.syntheticDuplicate, rhs.syntheticDuplicate))) ::: mkDefs(lhs.last, tp, rhs)
+ (lhs.toList.init flatMap (mkDefs(_, tp.duplicate, rhs.duplicate))) ::: mkDefs(lhs.last, tp, rhs)
}
/** VarDef ::= PatDef
@@ -2047,7 +2048,7 @@ self =>
val start = in.skipToken()
if (in.token == THIS) {
atPos(start, in.skipToken()) {
- val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.syntheticDuplicate), false)
+ val vparamss = paramClauses(nme.CONSTRUCTOR, implicitClassViews map (_.duplicate), false)
newLineOptWhenFollowedBy(LBRACE)
val rhs = if (in.token == LBRACE) {
atPos(in.offset) { constrBlock(vparamss) }
@@ -2184,7 +2185,7 @@ self =>
val implicitViewBuf = new ListBuffer[Tree]
val tparams = typeParamClauseOpt(name, implicitViewBuf)
implicitClassViews = implicitViewBuf.toList
- val tstart = (in.offset::implicitClassViews.map(_.pos.start)).min
+ val tstart = (in.offset::implicitClassViews.map(_.pos.startOrPoint)).min
if (!implicitClassViews.isEmpty && mods.hasFlag(Flags.TRAIT)) {
syntaxError("traits cannot have type parameters with <% bounds", false)
implicitClassViews = List()
@@ -2301,7 +2302,7 @@ self =>
if (mods.hasFlag(Flags.CASE)) parents = parents ::: List(productConstr)
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
atPos(tstart0) {
- Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart).toSynthetic)
+ Template(parents, self, constrMods, vparamss, argss, body, o2p(tstart))
}
}
@@ -2362,7 +2363,7 @@ self =>
def makePackageObject(start: Int, objDef: ModuleDef): PackageDef = objDef match {
case ModuleDef(mods, name, impl) =>
makePackaging(
- start, atPos(o2p(objDef.pos.start)){ Ident(name) }, List(ModuleDef(mods, nme.PACKAGEkw, impl)))
+ start, atPos(o2p(objDef.pos.startOrPoint)){ Ident(name) }, List(ModuleDef(mods, nme.PACKAGEkw, impl)))
}
/** Packaging ::= package QualId [nl] `{' TopStatSeq `}'
@@ -2520,7 +2521,7 @@ self =>
stats ++= localDef
if (in.token == RBRACE || in.token == CASE) {
syntaxError("block must end in result expression, not in definition", false)
- stats += Literal(()).setPos(o2p(in.offset).toSynthetic)
+ stats += Literal(()).setPos(o2p(in.offset))
} else acceptStatSep()
} else if (isStatSep) {
in.nextToken()
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
index d8f43cae2b..100ba462a4 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala
@@ -24,11 +24,8 @@ abstract class SyntaxAnalyzer extends SubComponent with Parsers with MarkupParse
unit.body =
if (unit.source.file.name.endsWith(".java")) new JavaUnitParser(unit).parse()
else if (!global.reporter.incompleteHandled) new UnitParser(unit).smartParse()
- else {
- val result = new UnitParser(unit).parse()
- if (global.settings.Yrangepos.value) global.validatePositions(unit.body)
- result
- }
+ else new UnitParser(unit).parse()
+ if (global.settings.Yrangepos.value) global.validatePositions(unit.body)
}
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index fe06b663b2..fc18cfb195 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -9,7 +9,7 @@ package ast.parser
import symtab.Flags._
import scala.collection.mutable.ListBuffer
-import scala.tools.nsc.util.{Position, SyntheticOffsetPosition}
+import scala.tools.nsc.util.Position
/** Methods for building trees, used in the parser. All the trees
* returned by this class must be untyped.
@@ -39,7 +39,7 @@ abstract class TreeBuilder {
private object patvarTransformer extends Transformer {
override def transform(tree: Tree): Tree = tree match {
case Ident(name) if (treeInfo.isVarPattern(tree) && name != nme.WILDCARD) =>
- atPos(tree.pos)(Bind(name, atPos(tree) (Ident(nme.WILDCARD))))
+ atPos(tree.pos)(Bind(name, atPos(tree.pos.focus) (Ident(nme.WILDCARD))))
case Typed(id @ Ident(name), tpt) if (treeInfo.isVarPattern(id) && name != nme.WILDCARD) =>
atPos(tree.pos.withPoint(id.pos.point)) {
Bind(name, atPos(tree.pos.withStart(tree.pos.point)) {
@@ -61,40 +61,47 @@ abstract class TreeBuilder {
}
}
- /** Traverse pattern and collect all variable names with their types in buffer */
+ /** Traverse pattern and collect all variable names with their types in buffer
+ * The variables keep their positions; whereas the pattern is converted to be synthetic
+ * for all nodes that contain a variable position.
+ */
private object getvarTraverser extends Traverser {
val buf = new ListBuffer[(Name, Tree, Position)]
def init: Traverser = { buf.clear; this }
- override def traverse(tree: Tree): Unit = tree match {
- case Bind(name, Typed(tree1, tpt)) =>
- if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
- buf += ((name, if (treeInfo.mayBeTypePat(tpt)) TypeTree() else tpt, tree.pos))
- }
- traverse(tree1)
- case Bind(name, tree1) =>
- if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
- // can assume only name range as position, as otherwise might overlap
- // with binds embedded in pattern tree1
- val start = tree.pos.start
- val end = start + name.decode.length
-
- // if the name range does overlap the bind we assume it is
- // a fresh name (ie. generated from for(... ; (a, b) <- (1, 2) ...))
- // make it transparent
- val namePos0 = r2p(start, start, end)
- val namePos = if (namePos0 overlaps tree.pos) makeTransparent(namePos0) else namePos0
- buf += ((name, TypeTree(), namePos))
- }
- traverse(tree1)
- case _ =>
- super.traverse(tree)
+ def namePos(tree: Tree, name: Name): Position =
+ if (!tree.pos.isRange || name.toString.contains('$')) tree.pos.focus
+ else {
+ val start = tree.pos.start
+ val end = start + name.decode.length
+ r2p(start, start, end)
+ }
+ override def traverse(tree: Tree): Unit = {
+ val bl = buf.length
+ tree match {
+ case Bind(name, Typed(tree1, tpt)) =>
+ if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
+ buf += ((name, if (treeInfo.mayBeTypePat(tpt)) TypeTree() else tpt.duplicate, namePos(tree, name)))
+ }
+ traverse(tree1)
+ case Bind(name, tree1) =>
+ if ((name != nme.WILDCARD) && (buf.iterator forall (name !=))) {
+ // can assume only name range as position, as otherwise might overlap
+ // with binds embedded in pattern tree1
+ buf += ((name, TypeTree(), namePos(tree, name)))
+ //println("found var "+name+" at "+namePos.show) //DEBUG
+ }
+ traverse(tree1)
+ case _ =>
+ super.traverse(tree)
+ }
+ if (buf.length > bl) tree setPos tree.pos.makeTransparent
}
}
/** Returns list of all pattern variables, possibly with their types,
* without duplicates
*/
- private def getVariables(tree: Tree): List[(Name, Tree,Position)] = {
+ private def getVariables(tree: Tree): List[(Name, Tree, Position)] = {
getvarTraverser.init.traverse(tree)
getvarTraverser.buf.toList
}
@@ -158,7 +165,7 @@ abstract class TreeBuilder {
/** Create positioned tree representing an object creation <new parents { stats }
* @param npos the position of the new
- * @param cpos the position of the anonymous class startig with parents
+ * @param cpos the position of the anonymous class starting with parents
*/
def makeNew(parents: List[Tree], self: ValDef, stats: List[Tree], argss: List[List[Tree]],
npos: Position, cpos: Position): Tree =
@@ -174,11 +181,11 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, List(Nil), argss, stats, cpos.toSynthetic))
+ Template(parents, self, NoMods, List(Nil), argss, stats, cpos.focus))
}),
atPos(npos) {
New(
- Ident(x) setPos npos.toSynthetic,
+ Ident(x) setPos npos.focus,
List(Nil))
}
)
@@ -200,7 +207,7 @@ abstract class TreeBuilder {
/** Create tree representing a while loop */
def makeWhile(lname: Name, cond: Tree, body: Tree): Tree = {
- val continu = atPos(o2p(body.pos.end)) { Apply(Ident(lname), Nil) }
+ val continu = atPos(o2p(body.pos.endOrPoint)) { Apply(Ident(lname), Nil) }
val rhs = If(cond, Block(List(body), continu), Literal(()))
LabelDef(lname, Nil, rhs)
}
@@ -234,7 +241,7 @@ abstract class TreeBuilder {
List(
makeVisitor(
List(
- CaseDef(pat1.syntheticDuplicate, EmptyTree, Literal(true)),
+ CaseDef(pat1.duplicate, EmptyTree, Literal(true)),
CaseDef(Ident(nme.WILDCARD), EmptyTree, Literal(false))),
false,
nme.CHECK_IF_REFUTABLE_STRING
@@ -310,7 +317,7 @@ abstract class TreeBuilder {
* the limits given by pat and body.
*/
def makeClosure(pos: Position, pat: Tree, body: Tree): Tree = {
- def splitpos = makeTransparent(wrappingPos(List(pat, body)).withPoint(pos.point))
+ def splitpos = wrappingPos(List(pat, body)).withPoint(pos.point).makeTransparent
matchVarPattern(pat) match {
case Some((name, tpt)) =>
Function(
@@ -345,12 +352,12 @@ abstract class TreeBuilder {
/** A reference to the name bound in Bind `pat`.
*/
def makeValue(pat: Tree): Tree = pat match {
- case Bind(name, _) => Ident(name) setPos pat.pos.toSynthetic
+ case Bind(name, _) => Ident(name) setPos pat.pos.focus
}
/** The position of the closure that starts with generator at position `genpos`.
*/
- def closurePos(genpos: Position) = r2p(genpos.start, genpos.point, body.pos.end)
+ def closurePos(genpos: Position) = r2p(genpos.startOrPoint, genpos.point, body.pos.endOrPoint)
// val result =
enums match {
@@ -361,7 +368,7 @@ abstract class TreeBuilder {
makeFor(mapName, flatMapName, rest, body))
case ValFrom(pos, pat, rhs) :: Filter(_, test) :: rest =>
makeFor(mapName, flatMapName,
- ValFrom(pos, pat, makeCombination(rhs.pos union test.pos, nme.filter, rhs, pat.syntheticDuplicate, test)) :: rest,
+ ValFrom(pos, pat, makeCombination(rhs.pos union test.pos, nme.filter, rhs, pat.duplicate, test)) :: rest,
body)
case ValFrom(pos, pat, rhs) :: rest =>
val valeqs = rest.take(definitions.MaxTupleArity - 1).takeWhile(_.isInstanceOf[ValEq]);
@@ -376,8 +383,8 @@ abstract class TreeBuilder {
val rhs1 = makeForYield(
List(ValFrom(pos, defpat1, rhs)),
Block(pdefs, atPos(wrappingPos(ids)) { makeTupleTerm(ids, true) }) setPos wrappingPos(pdefs))
- val allpats = (pat :: pats) map (_.syntheticDuplicate)
- val vfrom1 = ValFrom(r2p(pos.start, pos.point, rhs1.pos.end), atPos(wrappingPos(allpats)) { makeTuple(allpats, false) } , rhs1)
+ val allpats = (pat :: pats) map (_.duplicate)
+ val vfrom1 = ValFrom(r2p(pos.startOrPoint, pos.point, rhs1.pos.endOrPoint), atPos(wrappingPos(allpats)) { makeTuple(allpats, false) } , rhs1)
makeFor(mapName, flatMapName, vfrom1 :: rest1, body)
case _ =>
EmptyTree //may happen for erroneous input
@@ -428,8 +435,9 @@ abstract class TreeBuilder {
def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean): Tree =
makeVisitor(cases, checkExhaustive, "x$")
- private def makeUnchecked(expr: Tree): Tree =
+ private def makeUnchecked(expr: Tree): Tree = atPos(expr.pos) {
Annotated(New(scalaDot(definitions.UncheckedClass.name), List(Nil)), expr)
+ }
/** Create visitor <x => x match cases> */
def makeVisitor(cases: List[CaseDef], checkExhaustive: Boolean, prefix: String): Tree = {
@@ -465,25 +473,24 @@ abstract class TreeBuilder {
// val/var x_N = t$._N
val pat1 = patvarTransformer.transform(pat)
val vars = getVariables(pat1)
- val matchExpr = atPos(rhs.pos){
+ val matchExpr = atPos((pat1.pos union rhs.pos).makeTransparent) {
Match(
makeUnchecked(rhs),
List(
- makeSynthetic(
- atPos(rhs.pos) {
- CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
- })))
-
+ atPos(pat1.pos) {
+ CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
+ }
+ ))
}
vars match {
case List((vname, tpt, pos)) =>
- List(atPos(pat.pos union rhs.pos) {
+ List(atPos(pat.pos union pos union rhs.pos) {
ValDef(mods, vname, tpt, matchExpr)
})
case _ =>
val tmp = freshName()
val firstDef =
- atPos(rhs.pos) {
+ atPos(matchExpr.pos) {
ValDef(Modifiers(PRIVATE | LOCAL | SYNTHETIC | (mods.flags & LAZY)),
tmp, TypeTree(), matchExpr)
}