diff options
author | Martin Odersky <odersky@gmail.com> | 2009-07-30 07:41:22 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-07-30 07:41:22 +0000 |
commit | db045cb8ddbd725fc545da5296bf0cdd722c20ce (patch) | |
tree | ba2b4458a1b61e4d90beb917c087458dc117f860 /src/compiler/scala/tools/nsc/ast | |
parent | 74a6eeaf0948cbf59e327108c47aa41013c7fb9f (diff) | |
download | scala-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.scala | 23 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/Trees.scala | 105 | ||||
-rwxr-xr-x | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 79 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/SyntaxAnalyzer.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala | 101 |
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) } |