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;
}
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 bool closingParenBlock = blockText.startsWith(')');
if (!blockText.isEmpty() && !closingParenBlock)
return;
if (blockText.isEmpty() || closingParenBlock) {
//This extra text works for the most cases.
QByteArray extraText("a;");
QByteArray dummyText("a;");
// Search for previous character
QTextBlock prevBlock = block.previous();
while (prevBlock.position() > 0 && prevBlock.text().trimmed().isEmpty())
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(','))
extraText = "int a,";
dummyText = "int a";
if (closingParenBlock) {
if (prevBlock.text().endsWith(','))
extraText = "int a";
dummyText = "int a";
else
extraText = "&& a";
dummyText = "&& a";
}
length += extraText.length();
buffer.insert(offset, extraText);
length += dummyText.length();
buffer.insert(offset, dummyText);
}
if (secondTry) {
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;
@@ -253,11 +267,13 @@ QtReplacements replacements(const Utils::FileName &fileName,
int utf8Length,
const QTextBlock &block,
const QChar &typedChar = QChar::Null,
bool onlyIndention = true)
bool onlyIndention = true,
bool secondTry = false)
{
FormatStyle style = styleForFile(fileName);
int blockOffsetUtf8 = utf8Offset;
int originalOffsetUtf8 = utf8Offset;
int originalLengthUtf8 = utf8Length;
QByteArray originalBuffer = buffer;
int extraOffset = 0;
@@ -282,14 +298,14 @@ QtReplacements replacements(const Utils::FileName &fileName,
adjustFormatStyleForLineBreak(style);
if (typedChar == QChar::Null)
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block);
modifyToIndentEmptyLines(buffer, utf8Offset, utf8Length, block, secondTry);
}
std::vector<Range> ranges{{static_cast<unsigned int>(utf8Offset),
static_cast<unsigned int>(utf8Length)}};
FormattingAttemptStatus status;
ClangReplacements replacements = reformat(style,
ClangReplacements clangReplacements = reformat(style,
buffer.data(),
ranges,
fileName.toString().toStdString(),
@@ -298,11 +314,24 @@ QtReplacements replacements(const Utils::FileName &fileName,
if (!status.FormatComplete)
QtReplacements();
const ClangReplacements filtered = filteredReplacements(replacements,
const ClangReplacements filtered = filteredReplacements(clangReplacements,
utf8Offset,
extraOffset,
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)