From 31d3946adb7ed34bf89eaf0843ceef00c7ad71f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20De=20Canni=C3=A8re?= Date: Wed, 30 Sep 2026 10:52:13 +0200 Subject: qmlformat: Don't add extra commas to holed arrays `[1, 2, 3, 4, , ,]` is parsed with the comma that comes before the trailing holes stored on two different nodes: on the ArrayPattern, and on the list element that wraps those holes. The formatter wrote both, so every pass over the file appended another hole to the array. That changes the semantics of the expression. Store the comma on the ArrayPattern only if it isn't already part of the elision. This also ensures missing spaces between commas in the array. Amends d41f97e86702d8c5ac81a4246e1aab8dd965cbe4 Task-number: QTBUG-151040 Pick-to: 6.12 Change-Id: Ied05c0100210b0b2d06cf69a4fe55ee565239730 Reviewed-by: Fabian Kosmale --- src/qml/parser/qqmljs.g | 3 ++- src/qmldom/qqmldomreformatter.cpp | 12 ++++++++---- .../qml/qmlformat/data/holedArrayExtraCommas.formatted.js | 1 + tests/auto/qml/qmlformat/data/holedArrayExtraCommas.js | 3 +++ tests/auto/qml/qmlformat/tst_qmlformat.cpp | 2 ++ 5 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 tests/auto/qml/qmlformat/data/holedArrayExtraCommas.formatted.js create mode 100644 tests/auto/qml/qmlformat/data/holedArrayExtraCommas.js diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 8f0cfe4fe1..c64e24fa62 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -2115,7 +2115,8 @@ ArrayLiteral: T_LBRACKET ElementList T_COMMA ElisionOpt T_RBRACKET; } AST::ArrayPattern *node = new (pool) AST::ArrayPattern(list->finish()); node->lbracketToken = loc(1); - node->commaToken = loc(3); + if (!sym(4).Elision) + node->commaToken = loc(3); node->rbracketToken = loc(5); sym(1).Node = node; Q_ASSERT(node->isValidArrayLiteral()); diff --git a/src/qmldom/qqmldomreformatter.cpp b/src/qmldom/qqmldomreformatter.cpp index d1c70d47c5..266e075ab1 100644 --- a/src/qmldom/qqmldomreformatter.cpp +++ b/src/qmldom/qqmldomreformatter.cpp @@ -170,8 +170,11 @@ bool ScriptFormatter::visit(PatternElementList *ast) if (isObjectInitializer) ensureNewline(); - if (it->elision) + if (it->elision) { accept(it->elision); + if (it->element) + ensureSpaceIfNoComment(); + } if (it->element) accept(it->element); if (it->next) { @@ -897,10 +900,11 @@ bool ScriptFormatter::visit(FunctionExpression *ast) bool ScriptFormatter::visit(Elision *ast) { for (Elision *it = ast; it; it = it->next) { - if (it->commaToken.isValid()) { - outWithComments(it->commaToken, it); + if (!it->commaToken.isValid()) + continue; + outWithComments(it->commaToken, it); + if (it->next) ensureSpaceIfNoComment(); - } } return false; } diff --git a/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.formatted.js b/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.formatted.js new file mode 100644 index 0000000000..7b79ac117c --- /dev/null +++ b/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.formatted.js @@ -0,0 +1 @@ +[1, , , , [1, 2, 3], ,]; diff --git a/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.js b/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.js new file mode 100644 index 0000000000..78b5ed7b8a --- /dev/null +++ b/tests/auto/qml/qmlformat/data/holedArrayExtraCommas.js @@ -0,0 +1,3 @@ + + +[1, , , , [1, 2, 3], ,]; diff --git a/tests/auto/qml/qmlformat/tst_qmlformat.cpp b/tests/auto/qml/qmlformat/tst_qmlformat.cpp index 0305a2018e..17a2b1cbdc 100644 --- a/tests/auto/qml/qmlformat/tst_qmlformat.cpp +++ b/tests/auto/qml/qmlformat/tst_qmlformat.cpp @@ -119,6 +119,8 @@ void TestQmlformat::plainJS_data() << "longStatementList.formatted.js"; QTest::newRow("elisionCommaConfusion") << "elisionCommaConfusion.js" << "elisionCommaConfusion.formatted.js"; + QTest::newRow("holedArrayExtraCommas") << "holedArrayExtraCommas.js" + << "holedArrayExtraCommas.formatted.js"; } void TestQmlformat::plainJS() -- cgit v1.2.3