diff --git a/src/libs/qmljs/qmljscodeformatter.cpp b/src/libs/qmljs/qmljscodeformatter.cpp index c884e56d5b9..f4ddddb89bb 100644 --- a/src/libs/qmljs/qmljscodeformatter.cpp +++ b/src/libs/qmljs/qmljscodeformatter.cpp @@ -517,10 +517,10 @@ int CodeFormatter::indentForNewLineAfter(const QTextBlock &block) { restoreCurrentState(block); - int lexerState = loadLexerState(block); m_tokens.clear(); m_currentLine.clear(); - adjustIndent(m_tokens, lexerState, &m_indentDepth); + const int startLexerState = loadLexerState(block.previous()); + adjustIndent(m_tokens, startLexerState, &m_indentDepth); return m_indentDepth; } @@ -665,10 +665,11 @@ void CodeFormatter::leave(bool statementDone) void CodeFormatter::correctIndentation(const QTextBlock &block) { - const int lexerState = tokenizeBlock(block); + tokenizeBlock(block); Q_ASSERT(m_currentState.size() >= 1); - adjustIndent(m_tokens, lexerState, &m_indentDepth); + const int startLexerState = loadLexerState(block.previous()); + adjustIndent(m_tokens, startLexerState, &m_indentDepth); } bool CodeFormatter::tryInsideExpression(bool alsoExpression) diff --git a/src/libs/qmljs/qmljscodeformatter.h b/src/libs/qmljs/qmljscodeformatter.h index 7af62d5485f..fdd3a46f36a 100644 --- a/src/libs/qmljs/qmljscodeformatter.h +++ b/src/libs/qmljs/qmljscodeformatter.h @@ -71,7 +71,7 @@ public: protected: virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const = 0; - virtual void adjustIndent(const QList &tokens, int lexerState, int *indentDepth) const = 0; + virtual void adjustIndent(const QList &tokens, int startLexerState, int *indentDepth) const = 0; struct State; class QMLJS_EXPORT BlockData diff --git a/src/plugins/qmljstools/qmljsindenter.cpp b/src/plugins/qmljstools/qmljsindenter.cpp index 13ffc9621ae..b16ae568896 100644 --- a/src/plugins/qmljstools/qmljsindenter.cpp +++ b/src/plugins/qmljstools/qmljsindenter.cpp @@ -70,6 +70,8 @@ void Indenter::indentBlock(QTextDocument *doc, codeFormatter.updateStateUntil(block); const int depth = codeFormatter.indentFor(block); + if (depth == -1) + return; if (isElectricCharacter(typedChar)) { // only reindent the current line when typing electric characters if the diff --git a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp index 176c016b427..3b775f7e26a 100644 --- a/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp +++ b/src/plugins/qmljstools/qmljsqtstylecodeformatter.cpp @@ -289,10 +289,8 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd } } -void QtStyleCodeFormatter::adjustIndent(const QList &tokens, int lexerState, int *indentDepth) const +void QtStyleCodeFormatter::adjustIndent(const QList &tokens, int startLexerState, int *indentDepth) const { - Q_UNUSED(lexerState) - State topState = state(); State previousState = state(1); @@ -304,6 +302,12 @@ void QtStyleCodeFormatter::adjustIndent(const QList &tokens, int lexerSta return; } } + // don't touch multi-line strings at all + if ((startLexerState & Scanner::MultiLineMask) == Scanner::MultiLineStringDQuote + || (startLexerState & Scanner::MultiLineMask) == Scanner::MultiLineStringSQuote) { + *indentDepth = -1; + return; + } const int kind = extendedTokenKind(tokenAt(0)); switch (kind) { diff --git a/src/plugins/qmljstools/qmljsqtstylecodeformatter.h b/src/plugins/qmljstools/qmljsqtstylecodeformatter.h index 9668c498c9a..b5f1d25f3cd 100644 --- a/src/plugins/qmljstools/qmljsqtstylecodeformatter.h +++ b/src/plugins/qmljstools/qmljsqtstylecodeformatter.h @@ -54,7 +54,7 @@ public: protected: virtual void onEnter(int newState, int *indentDepth, int *savedIndentDepth) const; - virtual void adjustIndent(const QList &tokens, int lexerState, int *indentDepth) const; + virtual void adjustIndent(const QList &tokens, int startLexerState, int *indentDepth) const; virtual void saveBlockData(QTextBlock *block, const BlockData &data) const; virtual bool loadBlockData(const QTextBlock &block, BlockData *data) const; diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 56b9d8486bf..0af657472ab 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -69,7 +69,9 @@ public: codeFormatter.updateStateUntil(block); do { - tabSettings.indentLine(block, codeFormatter.indentFor(block)); + const int depth = codeFormatter.indentFor(block); + if (depth != -1) + tabSettings.indentLine(block, depth); codeFormatter.updateLineStateChange(block); block = block.next(); } while (block.isValid() && block != end); diff --git a/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp b/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp index cc90b0b627d..f612b6fc755 100644 --- a/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp +++ b/tests/auto/qml/qmleditor/qmlcodeformatter/tst_qmlcodeformatter.cpp @@ -95,8 +95,11 @@ private Q_SLOTS: void labelledStatements2(); void labelledStatements3(); void multilineTernaryInProperty(); + void multilineString(); }; +enum { DontCheck = -2, DontIndent = -1 }; + struct Line { Line(QString l) : line(l) @@ -139,7 +142,7 @@ void checkIndent(QList data, int style = 0) int i = 0; foreach (const Line &l, data) { QTextBlock b = document.findBlockByLineNumber(i); - if (l.expectedIndent != -1) { + if (l.expectedIndent != DontCheck) { int actualIndent = formatter.indentFor(b); if (actualIndent != l.expectedIndent) { QFAIL(QString("Wrong indent in line %1 with text '%2', expected indent %3, got %4").arg( @@ -727,9 +730,9 @@ void tst_QMLCodeFormatter::strayElse() data << Line("Rectangle {") << Line("onClicked: {", 4) << Line(" while ( true ) {}") - << Line(" else", -1) - << Line(" else {", -1) - << Line(" }", -1) + << Line(" else", DontCheck) + << Line(" else {", DontCheck) + << Line(" }", DontCheck) << Line("}"); checkIndent(data); } @@ -1222,6 +1225,23 @@ void tst_QMLCodeFormatter::multilineTernaryInProperty() checkIndent(data); } +void tst_QMLCodeFormatter::multilineString() +{ + QList data; + data << Line("Item {") + << Line(" a: 'foo") + << Line(" bar", DontIndent) + << Line(" boo boo", DontIndent) + << Line(" end'", DontIndent) + << Line(" a: \"foo") + << Line(" bar", DontIndent) + << Line(" boo boo", DontIndent) + << Line(" end\"", DontIndent) + << Line("}") + ; + checkIndent(data); +} + QTEST_APPLESS_MAIN(tst_QMLCodeFormatter) #include "tst_qmlcodeformatter.moc"