From d0d0a8c07ee00ae27edd2f6681b1146c1a2d8ae6 Mon Sep 17 00:00:00 2001 From: Christian Kamm Date: Thu, 21 Apr 2011 12:21:23 +0200 Subject: [PATCH] QmlJS: Fix indent of object literals. Reviewed-by: Roberto Raggi --- src/libs/qmljs/qmljscodeformatter.cpp | 21 +++++++- src/libs/qmljs/qmljscodeformatter.h | 2 + .../qmljstools/qmljsqtstylecodeformatter.cpp | 14 ++++- .../qmlcodeformatter/tst_qmlcodeformatter.cpp | 60 +++++++++++++++++++++- 4 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/libs/qmljs/qmljscodeformatter.cpp b/src/libs/qmljs/qmljscodeformatter.cpp index 3055ac9f33..edd596c5ca 100644 --- a/src/libs/qmljs/qmljscodeformatter.cpp +++ b/src/libs/qmljs/qmljscodeformatter.cpp @@ -295,9 +295,24 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) if (tryInsideExpression()) break; switch (kind) { + case Colon: enter(objectliteral_assignment); break; + case RightBracket: + case RightParenthesis: leave(); continue; // error recovery case RightBrace: leave(); break; } break; + // pretty much like expression, but ends with , or } + case objectliteral_assignment: + if (tryInsideExpression()) + break; + switch (kind) { + case Delimiter: enter(expression_continuation); break; + case RightBracket: + case RightParenthesis: leave(); continue; // error recovery + case RightBrace: leave(); continue; // so we also leave objectliteral_open + case Comma: leave(); break; + } break; + case bracket_element_start: switch (kind) { case Identifier: turnInto(bracket_element_maybe_objectdefinition); break; @@ -451,7 +466,8 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block) int topState = m_currentState.top().type; if (topState == expression - || topState == expression_or_objectdefinition) { + || topState == expression_or_objectdefinition + || topState == objectliteral_assignment) { enter(expression_maybe_continuation); } if (topState != multiline_comment_start @@ -743,7 +759,8 @@ bool CodeFormatter::isExpressionEndState(int type) const type == substatement_open || type == bracket_open || type == paren_open || - type == case_cont; + type == case_cont || + type == objectliteral_open; } const Token &CodeFormatter::tokenAt(int idx) const diff --git a/src/libs/qmljs/qmljscodeformatter.h b/src/libs/qmljs/qmljscodeformatter.h index bb58e36072..a3752ff672 100644 --- a/src/libs/qmljs/qmljscodeformatter.h +++ b/src/libs/qmljs/qmljscodeformatter.h @@ -138,6 +138,8 @@ public: // must be public to make Q_GADGET introspection work bracket_open, // opening [ in expression objectliteral_open, // opening { in expression + objectliteral_assignment, // after : in object literal + bracket_element_start, // after starting bracket_open or after ',' in bracket_open bracket_element_maybe_objectdefinition, // after an identifier in bracket_element_start diff --git a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp index 1455625d69..07d44c5923 100644 --- a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp +++ b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp @@ -117,6 +117,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd break; case binding_assignment: + case objectliteral_assignment: if (lastToken) *indentDepth = *savedIndentDepth + 4; else @@ -203,6 +204,16 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd *indentDepth = *savedIndentDepth + m_indentSize; break; + case objectliteral_open: + if (parentState.type == expression || parentState.type == objectliteral_assignment) { + // undo the continuation indent of the expression + *indentDepth = parentState.savedIndentDepth; + *savedIndentDepth = *indentDepth; + } + *indentDepth += m_indentSize; + break; + + case statement_with_condition: case statement_with_block: case if_statement: @@ -290,7 +301,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList &tokens, int lexerSta const int type = state(i).type; if (type == objectdefinition_open || type == jsblock_open - || type == substatement_open) { + || type == substatement_open + || type == objectliteral_open) { *indentDepth = state(i).savedIndentDepth; break; } diff --git a/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp b/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp index 673cc891a4..e9137b2611 100644 --- a/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp +++ b/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp @@ -83,7 +83,10 @@ private Q_SLOTS: // void gnuStyle(); // void whitesmithsStyle(); void expressionContinuation(); - void objectLiteral(); + void objectLiteral1(); + void objectLiteral2(); + void objectLiteral3(); + void objectLiteral4(); void keywordStatement(); void namespacedObjects(); }; @@ -962,7 +965,7 @@ void tst_QMLCodeFormatter::expressionContinuation() checkIndent(data); } -void tst_QMLCodeFormatter::objectLiteral() +void tst_QMLCodeFormatter::objectLiteral1() { QList data; data << Line("function shuffle() {") @@ -974,6 +977,59 @@ void tst_QMLCodeFormatter::objectLiteral() checkIndent(data); } +void tst_QMLCodeFormatter::objectLiteral2() +{ + QList data; + data << Line("var x = {") + << Line(" \"x\": 12,") + << Line(" \"y\": 34,") + << Line(" z: \"abc\"") + << Line("}") + ; + checkIndent(data); +} + +void tst_QMLCodeFormatter::objectLiteral3() +{ + QList data; + data << Line("var x = {") + << Line(" x: {") + << Line(" y: 12,") + << Line(" z: [1, 3]") + << Line(" },") + << Line(" \"z\": {") + << Line(" a: 1 + 2 + 3,") + << Line(" b: \"12\"") + << Line(" },") + << Line(" a: b") + << Line("}") + ; + checkIndent(data); +} + +void tst_QMLCodeFormatter::objectLiteral4() +{ + QList data; + data << Line("var x = { a: 12, b: 13 }") + << Line("y = {") + << Line(" a: 1 +") + << Line(" 2 + 3") + << Line(" + 4") + << Line("}") + << Line("y = {") + << Line(" a: 1 +") + << Line(" 2 + 3") + << Line(" + 4,") + << Line(" b: {") + << Line(" adef: 1 +") + << Line(" 2 + 3") + << Line(" + 4,") + << Line(" }") + << Line("}") + ; + checkIndent(data); +} + void tst_QMLCodeFormatter::keywordStatement() { QList data; -- 2.11.0