summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2019-03-06 14:05:31 +0100
committerIvan Donchevskii <ivan.donchevskii@qt.io>2019-03-06 14:24:07 +0000
commit7e5e99d551e1c393e3eebb4e952202c6418cd2fa (patch)
treee11703e1c999e84b1222a1b19723d8c424071f54
parent35b0b44b21cd24e76455525c25b0b9ab08349233 (diff)
downloadqt-creator-7e5e99d551e1c393e3eebb4e952202c6418cd2fa.tar.gz
ClangFormat: Add whitespace unit-tests and fix bugs
Check that extra whitespace does not prevent the indentation and that indentation is the same for the consecutive empty lines. Change-Id: I04aa12c4cd31aaf07daf9320c98d2eea7afcc9a8 Reviewed-by: Marco Bubke <marco.bubke@qt.io>
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.cpp52
-rw-r--r--src/plugins/clangformat/clangformatbaseindenter.h1
-rw-r--r--tests/unit/unittest/clangformat-test.cpp30
3 files changed, 60 insertions, 23 deletions
diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp
index c8ab31813c..7f47b418a7 100644
--- a/src/plugins/clangformat/clangformatbaseindenter.cpp
+++ b/src/plugins/clangformat/clangformatbaseindenter.cpp
@@ -129,7 +129,10 @@ void trimRHSWhitespace(const QTextBlock &block)
// Add extra text in case of the empty line or the line starting with ')'.
// Track such extra pieces of text in isInsideModifiedLine().
-int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool secondTry)
+int forceIndentWithExtraText(QByteArray &buffer,
+ QByteArray &dummyText,
+ const QTextBlock &block,
+ bool secondTry)
{
const QString blockText = block.text();
int firstNonWhitespace = Utils::indexOf(blockText,
@@ -144,21 +147,26 @@ int forceIndentWithExtraText(QByteArray &buffer, const QTextBlock &block, bool s
const bool closingParenBlock = firstNonWhitespace >= 0
&& blockText.at(firstNonWhitespace) == ')';
-
int extraLength = 0;
if (firstNonWhitespace < 0 || closingParenBlock) {
- //This extra text works for the most cases.
- QByteArray dummyText("a;a;");
-
- // Search for previous character
- QTextBlock prevBlock = block.previous();
- bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
- while (prevBlockIsEmpty) {
- prevBlock = prevBlock.previous();
- prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
+ if (dummyText.isEmpty()) {
+ // If we don't know yet the dummy text, let's guess it and use for this line and before.
+ // This extra text works for the most cases.
+ dummyText = "a;a;";
+
+ // Search for previous character
+ QTextBlock prevBlock = block.previous();
+ bool prevBlockIsEmpty = prevBlock.position() > 0
+ && prevBlock.text().trimmed().isEmpty();
+ while (prevBlockIsEmpty) {
+ prevBlock = prevBlock.previous();
+ prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
+ }
+ if (prevBlock.text().endsWith(','))
+ dummyText = "&& a,";
+ else if (closingParenBlock)
+ dummyText = "&& a";
}
- if (closingParenBlock || prevBlock.text().endsWith(','))
- dummyText = "&& a,";
buffer.insert(utf8Offset, dummyText);
extraLength += dummyText.length();
@@ -357,8 +365,11 @@ TextEditor::Replacements ClangFormatBaseIndenter::replacements(QByteArray buffer
adjustFormatStyleForLineBreak(style, replacementsToKeep);
if (replacementsToKeep == ReplacementsToKeep::OnlyIndent) {
- for (int index = startBlock.blockNumber(); index <= endBlock.blockNumber(); ++index) {
+ QByteArray dummyText;
+ // Iterate backwards to reuse the same dummy text for all empty lines.
+ for (int index = endBlock.blockNumber(); index >= startBlock.blockNumber(); --index) {
utf8Length += forceIndentWithExtraText(buffer,
+ dummyText,
m_doc->findBlockByNumber(index),
secondTry);
}
@@ -447,7 +458,6 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
- const QByteArray &buffer,
const QChar &typedChar,
int cursorPositionInEditor)
{
@@ -465,6 +475,8 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
cursorPositionInEditor += startBlock.position() - startBlockPosition;
}
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
+
ReplacementsToKeep replacementsToKeep = ReplacementsToKeep::OnlyIndent;
if (formatWhileTyping()
&& (cursorPositionInEditor == -1 || cursorPositionInEditor >= startBlockPosition)
@@ -491,9 +503,7 @@ void ClangFormatBaseIndenter::indentBlocks(const QTextBlock &startBlock,
const QChar &typedChar,
int cursorPositionInEditor)
{
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
- applyReplacements(m_doc,
- indentsFor(startBlock, endBlock, buffer, typedChar, cursorPositionInEditor));
+ applyReplacements(m_doc, indentsFor(startBlock, endBlock, typedChar, cursorPositionInEditor));
}
void ClangFormatBaseIndenter::indent(const QTextCursor &cursor,
@@ -537,15 +547,14 @@ int ClangFormatBaseIndenter::indentFor(const QTextBlock &block,
const TextEditor::TabSettings & /*tabSettings*/,
int cursorPositionInEditor)
{
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
TextEditor::Replacements toReplace = indentsFor(block,
block,
- buffer,
QChar::Null,
cursorPositionInEditor);
if (toReplace.empty())
return -1;
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
return indentationForBlock(toReplace, buffer, block);
}
@@ -557,13 +566,12 @@ TextEditor::IndentationForBlock ClangFormatBaseIndenter::indentationForBlocks(
TextEditor::IndentationForBlock ret;
if (blocks.isEmpty())
return ret;
- const QByteArray buffer = m_doc->toPlainText().toUtf8();
TextEditor::Replacements toReplace = indentsFor(blocks.front(),
blocks.back(),
- buffer,
QChar::Null,
cursorPositionInEditor);
+ const QByteArray buffer = m_doc->toPlainText().toUtf8();
for (const QTextBlock &block : blocks)
ret.insert(block.blockNumber(), indentationForBlock(toReplace, buffer, block));
return ret;
diff --git a/src/plugins/clangformat/clangformatbaseindenter.h b/src/plugins/clangformat/clangformatbaseindenter.h
index b412b57d6d..87b5e0c927 100644
--- a/src/plugins/clangformat/clangformatbaseindenter.h
+++ b/src/plugins/clangformat/clangformatbaseindenter.h
@@ -81,7 +81,6 @@ private:
int cursorPositionInEditor);
TextEditor::Replacements indentsFor(QTextBlock startBlock,
const QTextBlock &endBlock,
- const QByteArray &buffer,
const QChar &typedChar,
int cursorPositionInEditor);
TextEditor::Replacements replacements(QByteArray buffer,
diff --git a/tests/unit/unittest/clangformat-test.cpp b/tests/unit/unittest/clangformat-test.cpp
index 5dbe291b26..43380c8502 100644
--- a/tests/unit/unittest/clangformat-test.cpp
+++ b/tests/unit/unittest/clangformat-test.cpp
@@ -72,6 +72,7 @@ protected:
void insertLines(const std::vector<QString> &lines)
{
+ doc.clear();
cursor.setPosition(0);
for (size_t lineNumber = 1; lineNumber <= lines.size(); ++lineNumber) {
if (lineNumber > 1)
@@ -379,6 +380,17 @@ TEST_F(ClangFormat, IndentOnElectricCharacterButNotRemoveEmptyLinesBefore)
"}"));
}
+TEST_F(ClangFormat, IndentAfterExtraSpaceInpreviousLine)
+{
+ insertLines({"if (a ",
+ "&& b)"});
+
+ indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(documentLines(), ElementsAre("if (a",
+ " && b)"));
+}
+
TEST_F(ClangFormat, IndentFunctionBodyButNotFormatBeforeIt)
{
insertLines({"int foo(int a, int b,",
@@ -520,6 +532,24 @@ TEST_F(ClangFormat, OnlyIndentClosingParenthesis)
" )"));
}
+TEST_F(ClangFormat, EquallyIndentInsideParenthesis)
+{
+ insertLines({"if (a",
+ ")"});
+ extendedIndenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
+ auto linesAfterFirstLineBreak = documentLines();
+ insertLines({"if (a",
+ " ",
+ ")"});
+ extendedIndenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
+
+ ASSERT_THAT(linesAfterFirstLineBreak, ElementsAre("if (a",
+ " )"));
+ ASSERT_THAT(documentLines(), ElementsAre("if (a",
+ " ",
+ " )"));
+}
+
TEST_F(ClangFormat, FormatBasicFile)
{
insertLines({"int main()",