Skip to content

Commit 0233cac

Browse files
authored
Merge pull request scala#9811 from lrytz/t12490
Fix range positions in selection from parens
2 parents 586302a + 5d53a52 commit 0233cac

File tree

3 files changed

+41
-8
lines changed

3 files changed

+41
-8
lines changed

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

+7-6
Original file line numberDiff line numberDiff line change
@@ -917,8 +917,8 @@ self =>
917917
if (opinfo.targs.nonEmpty)
918918
syntaxError(opinfo.offset, "type application is not allowed for postfix operators")
919919

920-
val od = stripParens(reduceExprStack(base, opinfo.lhs))
921-
makePostfixSelect(start, opinfo.offset, od, opinfo.operator)
920+
val lhs = reduceExprStack(base, opinfo.lhs)
921+
makePostfixSelect(if (lhs.pos.isDefined) lhs.pos.start else start, opinfo.offset, stripParens(lhs), opinfo.operator)
922922
}
923923

924924
def finishBinaryOp(isExpr: Boolean, opinfo: OpInfo, rhs: Tree): Tree = {
@@ -1217,11 +1217,12 @@ self =>
12171217

12181218
def identOrMacro(): Name = if (isMacro) rawIdent() else ident()
12191219

1220-
def selector(t: Tree): Tree = {
1220+
def selector(t0: Tree): Tree = {
1221+
val t = stripParens(t0)
12211222
val point = if (isIdent) in.offset else in.lastOffset //scala/bug#8459
12221223
//assert(t.pos.isDefined, t)
12231224
if (t != EmptyTree)
1224-
Select(t, ident(skipIt = false)) setPos r2p(t.pos.start, point, in.lastOffset)
1225+
Select(t, ident(skipIt = false)) setPos r2p(t0.pos.start, point, in.lastOffset)
12251226
else
12261227
errorTermTree // has already been reported
12271228
}
@@ -1793,14 +1794,14 @@ self =>
17931794
in.token match {
17941795
case DOT =>
17951796
in.nextToken()
1796-
simpleExprRest(selector(stripParens(t)), canApply = true)
1797+
simpleExprRest(selector(t), canApply = true)
17971798
case LBRACKET =>
17981799
val t1 = stripParens(t)
17991800
t1 match {
18001801
case Ident(_) | Select(_, _) | Apply(_, _) =>
18011802
var app: Tree = t1
18021803
while (in.token == LBRACKET)
1803-
app = atPos(app.pos.start, in.offset)(TypeApply(app, exprTypeArgs()))
1804+
app = atPos(t.pos.start, in.offset)(TypeApply(app, exprTypeArgs()))
18041805

18051806
simpleExprRest(app, canApply = true)
18061807
case _ =>

src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala

+1-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ abstract class TreeBuilder {
5656
ValDef(Modifiers(PRIVATE), name, tpt, EmptyTree)
5757

5858
/** Tree for `od op`, start is start0 if od.pos is borked. */
59-
def makePostfixSelect(start0: Int, end: Int, od: Tree, op: Name): Tree = {
60-
val start = if (od.pos.isDefined) od.pos.start else start0
59+
def makePostfixSelect(start: Int, end: Int, od: Tree, op: Name): Tree = {
6160
atPos(r2p(start, end, end + op.length)) { new PostfixSelect(od, op.encode) }
6261
}
6362

test/files/run/t12490.scala

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import scala.tools.partest._
2+
import scala.collection.mutable.LinkedHashMap
3+
4+
object Test extends CompilerTest {
5+
import global._
6+
override def extraSettings = super.extraSettings + " -Yrangepos -Ystop-after:parser"
7+
val tests = LinkedHashMap(
8+
"class A { def t = new C() }" -> (24, 31),
9+
"class B { def t = (new C) }" -> (25, 30),
10+
"class C { def t = new C }" -> (24, 29),
11+
"class D { def t = new C().t }" -> (24, 33),
12+
"class E { def t = (new C).t }" -> (24, 33),
13+
"class F { def t(c: C) = c }" -> (24, 25),
14+
"class G { def t(c: C) = (c) }" -> (25, 26),
15+
"class H { def t(c: C) = c.t }" -> (24, 27),
16+
"class I { def t(c: C) = (c).t }" -> (24, 29),
17+
"class J { def t[T]: C = (x.t)[C] }" -> (24, 32),
18+
"class K { def t(f: F) = (f) t c }" -> (24, 31),
19+
"class L { def t(c: C) = (c) t }" -> (24, 29),
20+
// ^ 24 ^ 33
21+
)
22+
23+
override def sources = tests.toList.map(_._1)
24+
25+
def check(source: String, unit: CompilationUnit): Unit = unit.body foreach {
26+
case dd: DefDef if dd.name.startsWith("t") =>
27+
val pos = dd.rhs.pos
28+
val (start, end) = tests(source)
29+
assert(pos.start == start, pos.start)
30+
assert(pos.end == end, pos.end)
31+
case _ =>
32+
}
33+
}

0 commit comments

Comments
 (0)