From e8938acca96f636d545506e45830a61c6d9ca943 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Mon, 3 Jun 2024 15:45:39 +0200 Subject: [PATCH] ClangFormat: Fix indenting 'return' after key words Change-Id: I9e11b4d299c13ffada897b009fb70c3447213500 Reviewed-by: Christian Kandeler --- .../clangformat/clangformatbaseindenter.cpp | 20 +++++++++-- .../clangformat/tests/clangformat-test.cpp | 36 ++++++++++++++++++- 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 4d89ea8aa2e..295c86fcb6f 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -210,6 +210,21 @@ static bool comesDirectlyAfterIf(const QTextDocument *doc, int pos) return pos > 0 && doc->characterAt(pos) == 'f' && doc->characterAt(pos - 1) == 'i'; } +static bool startsWithKeyWord(const QString &keyWord, const QString &text) +{ + if (text.size() <= keyWord.size()) + return false; + + const QChar chAfter = text.at(keyWord.size()); + return text.startsWith(keyWord) && !chAfter.isDigit() && !chAfter.isLetter() && chAfter != '_'; +} + +static bool startsWithKeyWords(const QString &text) +{ + return startsWithKeyWord("if", text) || startsWithKeyWord("while", text) + || startsWithKeyWord("for", text); +} + static CharacterContext characterContext(const QTextBlock ¤tBlock) { QTextBlock previousNonEmptyBlock = reverseFindLastEmptyBlock(currentBlock); @@ -220,8 +235,9 @@ static CharacterContext characterContext(const QTextBlock ¤tBlock) if (prevLineText.isEmpty()) return CharacterContext::NewStatementOrContinuation; - if ((currentBlock.text().trimmed().isEmpty() || currentBlock.text().trimmed().endsWith(")")) - && prevLineText.endsWith("{")) + const QString currentBlockText = currentBlock.text().trimmed(); + if ((currentBlockText.isEmpty() || currentBlockText.endsWith(")")) + && prevLineText.endsWith("{") && !startsWithKeyWords(currentBlockText)) return CharacterContext::BracketAfterFunctionCall; const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock); diff --git a/src/plugins/clangformat/tests/clangformat-test.cpp b/src/plugins/clangformat/tests/clangformat-test.cpp index c52767baa27..6e7cdd367be 100644 --- a/src/plugins/clangformat/tests/clangformat-test.cpp +++ b/src/plugins/clangformat/tests/clangformat-test.cpp @@ -114,8 +114,10 @@ private slots: void testFunctionCallClosingParenthesis(); void testFunctionCallClosingParenthesisEmptyLine(); void testNoIndentationInMiddleOfLine(); - void testIndentationInTheBegginingOfLine(); void testIndentationInMiddleOfLine(); + void testIndentationInTheBegginingOfLine(); + void testIndentationReturnAfterIf(); + void testIndentationReturnAfterIfSomthingFunction(); private: void insertLines(const std::vector &lines); @@ -965,6 +967,38 @@ void ClangFormatTest::testIndentationInTheBegginingOfLine() "}"})); } +void ClangFormatTest::testIndentationReturnAfterIf() +{ + insertLines({"int main()", + "{", + " if (true)", + " return 0;", + "}"}); + m_indenter->indent(*m_cursor, QChar::Null, TextEditor::TabSettings()); + QCOMPARE(documentLines(), + (std::vector{"int main()", + "{", + " if (true)", + " return 0;", + "}"})); +} + +void ClangFormatTest::testIndentationReturnAfterIfSomthingFunction() +{ + insertLines({"int main()", + "{", + " if_somthing()", + " return 0;", + "}"}); + m_indenter->indent(*m_cursor, QChar::Null, TextEditor::TabSettings()); + QCOMPARE(documentLines(), + (std::vector{"int main()", + "{", + " if_somthing()", + " return 0;", + "}"})); +} + QObject *createClangFormatTest() { return new ClangFormatTest;