Respect newlines in if/else and let expressions (#1259)

Change the formatter to prevent multiline if/else and let expressions
from collapsing into a single line.
This commit is contained in:
Daniel Chao
2025-10-28 11:26:31 -07:00
committed by GitHub
parent fbcf83aa76
commit 825fcf5d1d
5 changed files with 86 additions and 5 deletions

View File

@@ -872,11 +872,14 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
} }
private fun formatIf(node: Node): FormatNode { private fun formatIf(node: Node): FormatNode {
val separator = if (node.isMultiline()) forceLine() else spaceOrLine()
val nodes = val nodes =
formatGeneric(node.children) { _, next -> formatGeneric(node.children) { _, next ->
if (next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR) { // produce `else if` in the case of nested if.
Space // note: don't need to handle if `next.children[0]` is an affix because that can't be
} else spaceOrLine() // emitted as `else if` anyway.
if (next.type == NodeType.IF_ELSE_EXPR && next.children[0].type == NodeType.IF_EXPR) Space
else separator
} }
return Group(newId(), nodes) return Group(newId(), nodes)
} }
@@ -968,10 +971,11 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
} }
private fun formatLetExpr(node: Node): FormatNode { private fun formatLetExpr(node: Node): FormatNode {
val separator = if (node.isMultiline()) forceLine() else spaceOrLine()
val nodes = val nodes =
formatGenericWithGen( formatGenericWithGen(
node.children, node.children,
{ _, next -> if (next.type == NodeType.LET_PARAMETER_DEFINITION) Space else spaceOrLine() }, { _, next -> if (next.type == NodeType.LET_PARAMETER_DEFINITION) Space else separator },
) { node, next -> ) { node, next ->
if (next == null) { if (next == null) {
if (node.type == NodeType.LET_EXPR) { if (node.type == NodeType.LET_EXPR) {
@@ -1323,7 +1327,7 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
} }
private fun hasTrailingAffix(node: Node, next: Node): Boolean { private fun hasTrailingAffix(node: Node, next: Node): Boolean {
if (node.span.lineEnd < next.span.lineBegin) return false if (node.isMultiline()) return false
var n: Node? = next var n: Node? = next
while (n != null) { while (n != null) {
if (n.type.isAffix && node.span.lineEnd == n.span.lineBegin) return true if (n.type.isAffix && node.span.lineEnd == n.span.lineBegin) return true
@@ -1450,6 +1454,8 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
// returns true if this node is not an affix or terminal // returns true if this node is not an affix or terminal
private fun Node.isProper(): Boolean = !type.isAffix && type != NodeType.TERMINAL private fun Node.isProper(): Boolean = !type.isAffix && type != NodeType.TERMINAL
private fun Node.isMultiline(): Boolean = span.lineBegin < span.lineEnd
private inline fun <T> List<T>.splitOn(pred: (T) -> Boolean): Pair<List<T>, List<T>> { private inline fun <T> List<T>.splitOn(pred: (T) -> Boolean): Pair<List<T>, List<T>> {
val index = indexOfFirst { pred(it) } val index = indexOfFirst { pred(it) }
return if (index == -1) { return if (index == -1) {

View File

@@ -5,3 +5,29 @@ foo =
else else
if (someAnotherCondition) 30000 if (someAnotherCondition) 30000
else 4 else 4
foo2 = if (bar) 1 else 2
// respect newlines in if/else if they exist.
// if anything of these wrap, everything wraps.
foo3 =
if (bar)
1 else 2
foo4 =
if (bar) 1 else
2
foo5 =
if (bar) 1
else 2
foo6 =
if (bar)
1
else
2
foo7 =
if /* some comment */ (bar) 1
else 2

View File

@@ -15,3 +15,11 @@ qux = let ( // some comment
bar = 5 bar = 5
) )
bar bar
quzzy =
let (baz = 1) baz + 1
// respect newlines in lets
quzzzy =
let (baz = 1)
baz + 1

View File

@@ -7,3 +7,37 @@ foo =
30000 30000
else else
4 4
foo2 = if (bar) 1 else 2
// respect newlines in if/else if they exist.
// if anything of these wrap, everything wraps.
foo3 =
if (bar)
1
else
2
foo4 =
if (bar)
1
else
2
foo5 =
if (bar)
1
else
2
foo6 =
if (bar)
1
else
2
foo7 =
if /* some comment */ (bar)
1
else
2

View File

@@ -25,3 +25,10 @@ qux =
bar = 5 bar = 5
) )
bar bar
quzzy = let (baz = 1) baz + 1
// respect newlines in lets
quzzzy =
let (baz = 1)
baz + 1