diff options
author | Artem Sokolovskii <artem.sokolovskii@qt.io> | 2022-07-05 16:38:51 +0200 |
---|---|---|
committer | Artem Sokolovskii <artem.sokolovskii@qt.io> | 2022-08-23 09:07:59 +0000 |
commit | 17693bc41518ee1c15d673dfee3c3818057b1895 (patch) | |
tree | ed7ca3e9853e54506a4af02d8e1284c2184fe488 /src/plugins/clangformat | |
parent | 5817bdf87d940d4cfbb02ad62b3304ff12b1de39 (diff) |
ClangFormat: Fix list declaration
Fixed list declaration indentation.
Fixed function declaration with parameters on the new line.
Added tests for both cases.
Fixes: QTCREATORBUG-25011
Change-Id: Ida4f6ec4f407c5e5b015dc2c0afff110262d9645
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'src/plugins/clangformat')
-rw-r--r-- | src/plugins/clangformat/clangformatbaseindenter.cpp | 49 | ||||
-rw-r--r-- | src/plugins/clangformat/tests/clangformat-test.cpp | 70 | ||||
-rw-r--r-- | src/plugins/clangformat/tests/clangformat-test.h | 2 |
3 files changed, 106 insertions, 15 deletions
diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 4ee5daebdb..8724109bad 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -156,6 +156,16 @@ QTextBlock reverseFindLastEmptyBlock(QTextBlock start) return start; } +QTextBlock reverseFindLastBlockWithSymbol(QTextBlock start, QChar ch) +{ + if (start.position() > 0) { + start = start.previous(); + while (start.position() > 0 && !start.text().contains(ch)) + start = start.previous(); + } + return start; +} + enum class CharacterContext { AfterComma, LastAfterComma, @@ -202,18 +212,30 @@ bool comesDirectlyAfterIf(const QTextDocument *doc, int pos) return pos > 0 && doc->characterAt(pos) == 'f' && doc->characterAt(pos - 1) == 'i'; } -CharacterContext characterContext(const QTextBlock ¤tBlock, - const QTextBlock &previousNonEmptyBlock) +CharacterContext characterContext(const QTextBlock ¤tBlock) { + QTextBlock previousNonEmptyBlock = reverseFindLastEmptyBlock(currentBlock); + if (previousNonEmptyBlock.position() > 0) + previousNonEmptyBlock = previousNonEmptyBlock.previous(); + const QString prevLineText = previousNonEmptyBlock.text().trimmed(); if (prevLineText.isEmpty()) return CharacterContext::NewStatementOrContinuation; const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock); if (prevLineText.endsWith(',')) { - // We don't need to add comma in case it's the last argument. - if (firstNonWhitespaceChar == '}' || firstNonWhitespaceChar == ')') + if (firstNonWhitespaceChar == '}') { + if (reverseFindLastBlockWithSymbol(currentBlock, '{').text().trimmed().last(1) == '{') + return CharacterContext::NewStatementOrContinuation; return CharacterContext::LastAfterComma; + } + + if (firstNonWhitespaceChar == ')') { + if (reverseFindLastBlockWithSymbol(currentBlock, '(').text().trimmed().last(1) == '(') + return CharacterContext::NewStatementOrContinuation; + return CharacterContext::LastAfterComma; + } + return CharacterContext::AfterComma; } @@ -267,6 +289,14 @@ int forceIndentWithExtraText(QByteArray &buffer, if (!block.isValid()) return 0; + auto tmpcharContext = characterContext(block); + if (charContext == CharacterContext::LastAfterComma + && tmpcharContext == CharacterContext::LastAfterComma) { + charContext = CharacterContext::AfterComma; + } else { + charContext = tmpcharContext; + } + const QString blockText = block.text(); int firstNonWhitespace = Utils::indexOf(blockText, [](const QChar &ch) { return !ch.isSpace(); }); @@ -290,17 +320,6 @@ int forceIndentWithExtraText(QByteArray &buffer, // If the next line is also empty it's safer to use a comment line. dummyText = "//"; } else if (firstNonWhitespace < 0 || closingParenBlock || closingBraceBlock) { - if (charContext == CharacterContext::LastAfterComma) { - charContext = CharacterContext::AfterComma; - } else if (charContext == CharacterContext::Unknown || firstNonWhitespace >= 0) { - QTextBlock lastBlock = reverseFindLastEmptyBlock(block); - if (lastBlock.position() > 0) - lastBlock = lastBlock.previous(); - - // If we don't know yet the dummy text, let's guess it and use for this line and before. - charContext = characterContext(block, lastBlock); - } - dummyText = dummyTextForContext(charContext, closingBraceBlock); } diff --git a/src/plugins/clangformat/tests/clangformat-test.cpp b/src/plugins/clangformat/tests/clangformat-test.cpp index 0493eeca97..50a5fe426b 100644 --- a/src/plugins/clangformat/tests/clangformat-test.cpp +++ b/src/plugins/clangformat/tests/clangformat-test.cpp @@ -655,4 +655,74 @@ void ClangFormatTest::testClassIndentStructure() (std::vector<QString>{"class test {", " Q_OBJECT", "public:", "};"})); } +void ClangFormatTest::testIndentInitializeVector() +{ + insertLines({ + "class Test {", + "public:", + " Test();", + "};", + "", + "Test::Test()", + "{", + " QVector<int> list = {", + " 1,", + " 2,", + " 3,", + " };", + " QVector<int> list_2 = {", + " 1,", + " 2,", + " 3,", + " };", + "}", + "", + "int main()", + "{", + "}" + }); + m_indenter->indent(*m_cursor, QChar::Null, TextEditor::TabSettings()); + QCOMPARE(documentLines(), + (std::vector<QString>{ + "class Test {", + "public:", + " Test();", + "};", + "", + "Test::Test()", + "{", + " QVector<int> list = {", + " 1,", + " 2,", + " 3,", + " };", + " QVector<int> list_2 = {", + " 1,", + " 2,", + " 3,", + " };", + "}", + "", + "int main()", + "{", + "}" + })); +} + +void ClangFormatTest::testIndentFunctionArgumentOnNewLine() +{ + insertLines( + {"Bar foo(", + "a,", + ")" + }); + m_indenter->indentBlock(m_doc->findBlockByNumber(1), QChar::Null, TextEditor::TabSettings()); + QCOMPARE(documentLines(), + (std::vector<QString>{ + "Bar foo(", + " a,", + ")" + })); +} + } // namespace ClangFormat::Internal diff --git a/src/plugins/clangformat/tests/clangformat-test.h b/src/plugins/clangformat/tests/clangformat-test.h index 094657d1b0..1793a0cffb 100644 --- a/src/plugins/clangformat/tests/clangformat-test.h +++ b/src/plugins/clangformat/tests/clangformat-test.h @@ -110,6 +110,8 @@ private slots: void testChainedMemberFunctionCalls(); void testCommentBlock(); void testClassIndentStructure(); + void testIndentInitializeVector(); + void testIndentFunctionArgumentOnNewLine(); private: void insertLines(const std::vector<QString> &lines); |