Skip to content

Commit 6bf8eae

Browse files
authored
Allow observing an indent after conditional (#22611)
Normally do not infer NEWLINE within parens, but special case old syntax for conditionals, so that it can observe indented syntax. The mechanism is to inject an Indented region when parsing a parenthesized condition which is within an InParens region, such as an arg list. The effect is not to advance past EOL after `(true)`. Fixes #22608
2 parents a630e9e + a19c14a commit 6bf8eae

File tree

2 files changed

+60
-9
lines changed

2 files changed

+60
-9
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+12-9
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ object Parsers {
105105
private val InCase: Region => Region = Scanners.InCase(_)
106106
private val InCond: Region => Region = Scanners.InParens(LPAREN, _)
107107
private val InFor : Region => Region = Scanners.InBraces(_)
108+
private val InOldCond: Region => Region = // old-style Cond to allow indent when InParens, see #22608
109+
case p: Scanners.InParens => Scanners.Indented(p.indentWidth, p.prefix, p)
110+
case r => r
108111

109112
def unimplementedExpr(using Context): Select =
110113
Select(scalaDot(nme.Predef), nme.???)
@@ -2325,25 +2328,25 @@ object Parsers {
23252328
def condExpr(altToken: Token): Tree =
23262329
val t: Tree =
23272330
if in.token == LPAREN then
2328-
var t: Tree = atSpan(in.offset):
2329-
makeTupleOrParens(inParensWithCommas(commaSeparated(exprInParens)))
2330-
if in.token != altToken then
2331-
if toBeContinued(altToken) then
2332-
t = inSepRegion(InCond) {
2331+
inSepRegion(InOldCond): // allow inferred NEWLINE for observeIndented below
2332+
atSpan(in.offset):
2333+
makeTupleOrParens(inParensWithCommas(commaSeparated(exprInParens)))
2334+
.pipe: t =>
2335+
if in.token == altToken then t
2336+
else if toBeContinued(altToken) then
2337+
inSepRegion(InCond):
23332338
expr1Rest(
23342339
postfixExprRest(
23352340
simpleExprRest(t, Location.ElseWhere),
23362341
Location.ElseWhere),
23372342
Location.ElseWhere)
2338-
}
23392343
else
23402344
if rewriteToNewSyntax(t.span) then
2341-
dropParensOrBraces(t.span.start, s"${tokenString(altToken)}")
2345+
dropParensOrBraces(t.span.start, tokenString(altToken))
23422346
in.observeIndented()
23432347
return t
2344-
t
23452348
else if in.isNestedStart then
2346-
try expr() finally newLinesOpt()
2349+
expr().tap(_ => newLinesOpt())
23472350
else
23482351
inSepRegion(InCond)(expr())
23492352
if rewriteToOldSyntax(t.span.startPos) then revertToParens(t)

tests/pos/i22608.scala

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
def f(i: Int) = i
3+
def g(i: Int, j: Int) = i+j
4+
5+
def t =
6+
val y = f(
7+
if (true)// then
8+
val x = 1
9+
5
10+
else 7
11+
)
12+
y
13+
14+
def u(j: Int) =
15+
val y = g(
16+
if (true)// then
17+
val x = 1
18+
5
19+
else 7,
20+
j
21+
)
22+
y
23+
24+
def b(k: Boolean): Int =
25+
f(
26+
if (
27+
k
28+
&& b(!k) > 0
29+
) then 27
30+
else 42
31+
)
32+
33+
def p(b: Boolean) =
34+
import collection.mutable.ListBuffer
35+
val xs, ys = ListBuffer.empty[String]
36+
(if (b)
37+
xs
38+
else
39+
ys) += "hello, world"
40+
(xs.toString, ys.toString)
41+
42+
def q(b: Boolean) =
43+
import collection.mutable.ListBuffer
44+
val xs, ys = ListBuffer.empty[String]
45+
(if (b)
46+
then xs
47+
else ys) += "hello, world"
48+
(xs.toString, ys.toString)

0 commit comments

Comments
 (0)