aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/clangformat
diff options
context:
space:
mode:
authorArtem Sokolovskii <artem.sokolovskii@qt.io>2022-07-05 16:38:51 +0200
committerArtem Sokolovskii <artem.sokolovskii@qt.io>2022-08-23 09:07:59 +0000
commit17693bc41518ee1c15d673dfee3c3818057b1895 (patch)
treeed7ca3e9853e54506a4af02d8e1284c2184fe488 /src/plugins/clangformat
parent5817bdf87d940d4cfbb02ad62b3304ff12b1de39 (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.cpp49
-rw-r--r--src/plugins/clangformat/tests/clangformat-test.cpp70
-rw-r--r--src/plugins/clangformat/tests/clangformat-test.h2
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 &currentBlock,
- const QTextBlock &previousNonEmptyBlock)
+CharacterContext characterContext(const QTextBlock &currentBlock)
{
+ 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);