mirror of
https://github.com/apple/pkl.git
synced 2026-02-26 04:14:57 +01:00
Don't force multiline interpolation into a single line (#1280)
Also, fixes an issue where forced single-line formatting would break for if/else and let expressions --------- Co-authored-by: Islon Scherer <islonscherer@gmail.com>
This commit is contained in:
@@ -25,7 +25,7 @@ To get started, follow xref:pkl-cli:index.adoc#installation[Installation].#
|
||||
[[formatter]]
|
||||
=== Formatter
|
||||
|
||||
Pkl now has a formatter (https://github.com/apple/pkl/pull/1107[#1107], https://github.com/apple/pkl/pull/1208[#1208], https://github.com/apple/pkl/pull/1211[#1211], https://github.com/apple/pkl/pull/1215[#1215], https://github.com/apple/pkl/pull/1217[#1217], https://github.com/apple/pkl/pull/1235[#1235], https://github.com/apple/pkl/pull/1246[#1246], https://github.com/apple/pkl/pull/1247[#1247], https://github.com/apple/pkl/pull/1252[#1252], https://github.com/apple/pkl/pull/1256[#1256], https://github.com/apple/pkl/pull/1259[#1259], https://github.com/apple/pkl/pull/1260[#1260], https://github.com/apple/pkl/pull/1263[#1263], https://github.com/apple/pkl/pull/1265[#1265], https://github.com/apple/pkl/pull/1266[#1266], https://github.com/apple/pkl/pull/1267[#1267], https://github.com/apple/pkl/pull/1270[#1270], https://github.com/apple/pkl/pull/1271[#1271], https://github.com/apple/pkl/pull/1272[#1272], https://github.com/apple/pkl/pull/1273[#1273], https://github.com/apple/pkl/pull/1274[#1274])!
|
||||
Pkl now has a formatter (https://github.com/apple/pkl/pull/1107[#1107], https://github.com/apple/pkl/pull/1208[#1208], https://github.com/apple/pkl/pull/1211[#1211], https://github.com/apple/pkl/pull/1215[#1215], https://github.com/apple/pkl/pull/1217[#1217], https://github.com/apple/pkl/pull/1235[#1235], https://github.com/apple/pkl/pull/1246[#1246], https://github.com/apple/pkl/pull/1247[#1247], https://github.com/apple/pkl/pull/1252[#1252], https://github.com/apple/pkl/pull/1256[#1256], https://github.com/apple/pkl/pull/1259[#1259], https://github.com/apple/pkl/pull/1260[#1260], https://github.com/apple/pkl/pull/1263[#1263], https://github.com/apple/pkl/pull/1265[#1265], https://github.com/apple/pkl/pull/1266[#1266], https://github.com/apple/pkl/pull/1267[#1267], https://github.com/apple/pkl/pull/1270[#1270], https://github.com/apple/pkl/pull/1271[#1271], https://github.com/apple/pkl/pull/1272[#1272], https://github.com/apple/pkl/pull/1273[#1273], https://github.com/apple/pkl/pull/1274[#1274], https://github.com/apple/pkl/pull/1280[#1280])!
|
||||
|
||||
Pkl's formatter is _canonical_, which means that it has a single set of formatting rules, with (almost) no configuration options.
|
||||
The goal is to eliminate the possibility of formatting debates, which can lead to churn and bike-shedding.
|
||||
|
||||
@@ -39,8 +39,6 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
private var prevNode: Node? = null
|
||||
private var noNewlines = false
|
||||
|
||||
private class CannotAvoidNewline : RuntimeException()
|
||||
|
||||
fun format(node: Node): FormatNode {
|
||||
prevNode = node
|
||||
return when (node.type) {
|
||||
@@ -836,16 +834,10 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
while (cursor.hasNext()) {
|
||||
if (isInStringInterpolation) {
|
||||
val prevNoNewlines = noNewlines
|
||||
noNewlines = true
|
||||
val elems = cursor.takeUntilBefore { it.isTerminal(")") }
|
||||
noNewlines = !elems.isMultiline()
|
||||
getBaseSeparator(prev!!, elems.first())?.let { add(it) }
|
||||
val formatted =
|
||||
try {
|
||||
formatGeneric(elems, null)
|
||||
} catch (_: CannotAvoidNewline) {
|
||||
noNewlines = false
|
||||
formatGeneric(elems, null)
|
||||
}
|
||||
val formatted = formatGeneric(elems, null)
|
||||
addAll(formatted)
|
||||
getBaseSeparator(elems.last(), cursor.peek())?.let { add(it) }
|
||||
noNewlines = prevNoNewlines
|
||||
@@ -872,7 +864,7 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
}
|
||||
|
||||
private fun formatIf(node: Node): FormatNode {
|
||||
val separator = if (node.isMultiline()) forceLine() else spaceOrLine()
|
||||
val separator = if (node.isMultiline()) forceSpaceyLine() else spaceOrLine()
|
||||
val nodes =
|
||||
formatGeneric(node.children) { _, next ->
|
||||
// produce `else if` in the case of nested if.
|
||||
@@ -971,7 +963,7 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
}
|
||||
|
||||
private fun formatLetExpr(node: Node): FormatNode {
|
||||
val separator = if (node.isMultiline()) forceLine() else spaceOrLine()
|
||||
val separator = if (node.isMultiline()) forceSpaceyLine() else spaceOrLine()
|
||||
val endsWithLet = node.children.last().type == NodeType.LET_EXPR
|
||||
val nodes =
|
||||
formatGenericWithGen(
|
||||
@@ -1315,7 +1307,12 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
}
|
||||
|
||||
private fun mustForceLine(): FormatNode {
|
||||
return if (noNewlines) throw CannotAvoidNewline() else ForceLine
|
||||
if (noNewlines) {
|
||||
// should never happen; we do not set `noNewlines` for interpolation blocks that span multiple
|
||||
// lines
|
||||
throw RuntimeException("Tried to render Pkl code as single line")
|
||||
}
|
||||
return ForceLine
|
||||
}
|
||||
|
||||
private fun forceLine(): FormatNode {
|
||||
@@ -1460,6 +1457,9 @@ internal class Builder(sourceText: String, private val grammarVersion: GrammarVe
|
||||
|
||||
private fun Node.isMultiline(): Boolean = span.lineBegin < span.lineEnd
|
||||
|
||||
private fun List<Node>.isMultiline(): Boolean =
|
||||
if (isEmpty()) false else first().span.lineBegin < last().span.lineEnd
|
||||
|
||||
private inline fun <T> List<T>.splitOn(pred: (T) -> Boolean): Pair<List<T>, List<T>> {
|
||||
val index = indexOfFirst { pred(it) }
|
||||
return if (index == -1) {
|
||||
|
||||
@@ -13,7 +13,7 @@ prop3 =
|
||||
\(new {
|
||||
// some comment
|
||||
foo = 1
|
||||
|
||||
|
||||
// some comment
|
||||
bar = 2
|
||||
})
|
||||
@@ -49,3 +49,28 @@ prop7 = "\(
|
||||
)"
|
||||
|
||||
prop8 = "\(new { foo = 1 bar = 2 baz = 3 })"
|
||||
|
||||
prop9 = "\(if (true) 1 else 2)"
|
||||
|
||||
prop10 = "\(
|
||||
if (true) 1
|
||||
else 2
|
||||
)"
|
||||
|
||||
prop11 = "\(
|
||||
new {
|
||||
1;
|
||||
2;
|
||||
3;
|
||||
}
|
||||
)"
|
||||
|
||||
// single line expressions are not broken up
|
||||
prop12 = "Some \(if (true) 1 else 2) reeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallly long string with interpolation"
|
||||
|
||||
// multi-line expressions are preserved
|
||||
prop13 = "Some \(
|
||||
if (true)
|
||||
1
|
||||
else 2
|
||||
) reeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallly long string with interpolation"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
foo =
|
||||
"""
|
||||
asd \(new { bar = 1 }) asd
|
||||
asd \(new {
|
||||
bar = 1
|
||||
}) asd
|
||||
"""
|
||||
|
||||
bar =
|
||||
|
||||
@@ -50,3 +50,29 @@ prop7 =
|
||||
)"
|
||||
|
||||
prop8 = "\(new { foo = 1; bar = 2; baz = 3 })"
|
||||
|
||||
prop9 = "\(if (true) 1 else 2)"
|
||||
|
||||
prop10 =
|
||||
"\(if (true)
|
||||
1
|
||||
else
|
||||
2)"
|
||||
|
||||
prop11 =
|
||||
"\(new {
|
||||
1
|
||||
2
|
||||
3
|
||||
})"
|
||||
|
||||
// single line expressions are not broken up
|
||||
prop12 =
|
||||
"Some \(if (true) 1 else 2) reeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallly long string with interpolation"
|
||||
|
||||
// multi-line expressions are preserved
|
||||
prop13 =
|
||||
"Some \(if (true)
|
||||
1
|
||||
else
|
||||
2) reeeaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaallly long string with interpolation"
|
||||
|
||||
Reference in New Issue
Block a user