ClangFormat: Try to add ')' in case of no indentation

clang-format has problems with unfinished () blocks.
In case when the first formatting try failed it makes sense
to try again after appending ')' to the end of the line.

In case it does not solve the initial issue it does not
make it worse anyways.

Examples where this approach helps:

if (a<press CR>

or

if (a <press CR>&& b

Change-Id: Iacc35af79a7b19c1d512d141423d7549788a1a22
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
This commit is contained in:
Ivan Donchevskii
2019-01-09 16:28:41 +01:00
parent ce0b671d0a
commit 73ac3b928c

View File

@@ -163,32 +163,46 @@ int previousEmptyLinesLength(const QTextBlock &currentBlock)
return length; return length;
} }
void modifyToIndentEmptyLines(QByteArray &buffer, int offset, int &length, const QTextBlock &block) void modifyToIndentEmptyLines(
QByteArray &buffer, int offset, int &length, const QTextBlock &block, bool secondTry)
{ {
const QString blockText = block.text().trimmed(); const QString blockText = block.text().trimmed();
const bool closingParenBlock = blockText.startsWith(')'); const bool closingParenBlock = blockText.startsWith(')');
if (!blockText.isEmpty() && !closingParenBlock) if (blockText.isEmpty() || closingParenBlock) {
return; //This extra text works for the most cases.
QByteArray dummyText("a;");
//This extra text works for the most cases. // Search for previous character
QByteArray extraText("a;"); QTextBlock prevBlock = block.previous();
bool prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
// Search for previous character while (prevBlockIsEmpty) {
QTextBlock prevBlock = block.previous(); prevBlock = prevBlock.previous();
while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty()) prevBlockIsEmpty = prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty();
prevBlock = prevBlock.previous(); }
if (prevBlock.text().endsWith(','))
extraText = "int a,";
if (closingParenBlock) {
if (prevBlock.text().endsWith(',')) if (prevBlock.text().endsWith(','))
extraText = "int a"; dummyText = "int a";
else
extraText = "&& a"; if (closingParenBlock) {
if (prevBlock.text().endsWith(','))
dummyText = "int a";
else
dummyText = "&& a";
}
length += dummyText.length();
buffer.insert(offset, dummyText);
} }
length += extraText.length(); if (secondTry) {
buffer.insert(offset, extraText); int nextLinePos = buffer.indexOf('\n', offset);
if (nextLinePos > 0) {
// If first try was not successful try to put ')' in the end of the line to close possibly
// unclosed parentheses.
// TODO: Does it help to add different endings depending on the context?
buffer.insert(nextLinePos, ')');
length += 1;
}
}
} }
static const int kMaxLinesFromCurrentBlock = 200; static const int kMaxLinesFromCurrentBlock = 200;
@@ -253,11 +267,13 @@ QtReplacements replacements(const Utils::FileName &fileName,
int utf8Length, int utf8Length,
const QTextBlock &block, const QTextBlock &block,
const QChar &typedChar = QChar::Null, const QChar &typedChar = QChar::Null,
bool onlyIndention = true) bool onlyIndention = true,
bool secondTry = false)
{ {
FormatStyle style = styleForFile(fileName); FormatStyle style = styleForFile(fileName);
int blockOffsetUtf8 = utf8Offset; int originalOffsetUtf8 = utf8Offset;
int originalLengthUtf8 = utf8Length;
QByteArray originalBuffer = buffer; QByteArray originalBuffer = buffer;
int extraOffset = 0; int extraOffset = 0;
@@ -282,27 +298,40 @@ QtReplacements replacements(const Utils::FileName &fileName,
adjustFormatStyleForLineBreak(style); adjustFormatStyleForLineBreak(style);
if (typedChar == QChar::Null) if (typedChar == QChar::Null)
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block); modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
} }
std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset), std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset),
static_cast<unsigned int>(utf8Length)}}; static_cast<unsigned int>(utf8Length)}};
FormattingAttemptStatus status; FormattingAttemptStatus status;
ClangReplacements replacements = reformat(style, ClangReplacements clangReplacements = reformat(style,
buffer.data(), buffer.data(),
ranges, ranges,
fileName.toString().toStdString(), fileName.toString().toStdString(),
&status); &status);
if (!status.FormatComplete) if (!status.FormatComplete)
QtReplacements(); QtReplacements();
const ClangReplacements filtered = filteredReplacements(replacements, const ClangReplacements filtered = filteredReplacements(clangReplacements,
utf8Offset, utf8Offset,
extraOffset, extraOffset,
onlyIndention); onlyIndention);
return utf16Replacements(block, blockOffsetUtf8, originalBuffer, filtered);
const bool canTryAgain = onlyIndention && typedChar == QChar::Null && !secondTry;
if (canTryAgain && filtered.empty()) {
return replacements(fileName,
originalBuffer,
originalOffsetUtf8,
originalLengthUtf8,
block,
typedChar,
onlyIndention,
true);
}
return utf16Replacements(block, originalOffsetUtf8, originalBuffer, filtered);
} }
void applyReplacements(const QTextBlock &block, const QtReplacements &replacements) void applyReplacements(const QTextBlock &block, const QtReplacements &replacements)