summaryrefslogtreecommitdiffstats
path: root/lib/Format/BreakableToken.cpp
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2017-11-29 14:29:43 +0000
committerManuel Klimek <klimek@google.com>2017-11-29 14:29:43 +0000
commit64d42a2fb85ece5987111ffb908c6bc7f7431dd4 (patch)
treeeb216380b5c2dc08a6cc649aa9cb215342f8922c /lib/Format/BreakableToken.cpp
parentdd9e3a32396ac1f1807e7c14084e1233f36d3918 (diff)
Restructure how we break tokens.
This fixes some bugs in the reflowing logic and splits out the concerns of reflowing from BreakableToken. Things to do after this patch: - Refactor the breakProtrudingToken function possibly into a class, so we can split it up into methods that operate on the common state. - Optimize whitespace compression when reflowing by using the next possible split point instead of the latest possible split point. - Retry different strategies for reflowing (strictly staying below the column limit vs. allowing excess characters if possible). Differential Revision: https://reviews.llvm.org/D40310 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@319314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Format/BreakableToken.cpp')
-rw-r--r--lib/Format/BreakableToken.cpp437
1 files changed, 171 insertions, 266 deletions
diff --git a/lib/Format/BreakableToken.cpp b/lib/Format/BreakableToken.cpp
index d2064acee0..db350b9a5a 100644
--- a/lib/Format/BreakableToken.cpp
+++ b/lib/Format/BreakableToken.cpp
@@ -67,6 +67,8 @@ static BreakableToken::Split getCommentSplit(StringRef Text,
unsigned ColumnLimit,
unsigned TabWidth,
encoding::Encoding Encoding) {
+ DEBUG(llvm::dbgs() << "Comment split: \"" << Text << ", " << ColumnLimit
+ << "\", Content start: " << ContentStartColumn << "\n");
if (ColumnLimit <= ContentStartColumn + 1)
return BreakableToken::Split(StringRef::npos, 0);
@@ -171,7 +173,7 @@ bool switchesFormatting(const FormatToken &Token) {
}
unsigned
-BreakableToken::getLineLengthAfterCompression(unsigned RemainingTokenColumns,
+BreakableToken::getLengthAfterCompression(unsigned RemainingTokenColumns,
Split Split) const {
// Example: consider the content
// lala lala
@@ -181,50 +183,58 @@ BreakableToken::getLineLengthAfterCompression(unsigned RemainingTokenColumns,
// We compute the number of columns when the split is compressed into a single
// space, like:
// lala lala
+ //
+ // FIXME: Correctly measure the length of whitespace in Split.second so it
+ // works with tabs.
return RemainingTokenColumns + 1 - Split.second;
}
-unsigned BreakableSingleLineToken::getLineCount() const { return 1; }
+unsigned BreakableStringLiteral::getLineCount() const { return 1; }
-unsigned BreakableSingleLineToken::getLineLengthAfterSplit(
- unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- return StartColumn + Prefix.size() + Postfix.size() +
- encoding::columnWidthWithTabs(Line.substr(TailOffset, Length),
- StartColumn + Prefix.size(),
- Style.TabWidth, Encoding);
+unsigned BreakableStringLiteral::getRangeLength(unsigned LineIndex,
+ unsigned Offset,
+ StringRef::size_type Length,
+ unsigned StartColumn) const {
+ assert(false &&
+ "Getting the length of a part of the string literal indicates that "
+ "the code tries to reflow it.");
}
-BreakableSingleLineToken::BreakableSingleLineToken(
+unsigned
+BreakableStringLiteral::getRemainingLength(unsigned LineIndex, unsigned Offset,
+ unsigned StartColumn) const {
+ return UnbreakableTailLength + Postfix.size() +
+ encoding::columnWidthWithTabs(Line.substr(Offset, StringRef::npos),
+ StartColumn, Style.TabWidth, Encoding);
+}
+
+unsigned BreakableStringLiteral::getContentStartColumn(unsigned LineIndex,
+ bool Break) const {
+ return StartColumn + Prefix.size();
+}
+
+BreakableStringLiteral::BreakableStringLiteral(
const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
const FormatStyle &Style)
: BreakableToken(Tok, InPPDirective, Encoding, Style),
- StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix) {
+ StartColumn(StartColumn), Prefix(Prefix), Postfix(Postfix),
+ UnbreakableTailLength(Tok.UnbreakableTailLength) {
assert(Tok.TokenText.startswith(Prefix) && Tok.TokenText.endswith(Postfix));
Line = Tok.TokenText.substr(
Prefix.size(), Tok.TokenText.size() - Prefix.size() - Postfix.size());
}
-BreakableStringLiteral::BreakableStringLiteral(
- const FormatToken &Tok, unsigned StartColumn, StringRef Prefix,
- StringRef Postfix, bool InPPDirective, encoding::Encoding Encoding,
- const FormatStyle &Style)
- : BreakableSingleLineToken(Tok, StartColumn, Prefix, Postfix, InPPDirective,
- Encoding, Style) {}
-
-BreakableToken::Split
-BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
- unsigned ColumnLimit,
- llvm::Regex &CommentPragmasRegex) const {
- return getStringSplit(Line.substr(TailOffset),
- StartColumn + Prefix.size() + Postfix.size(),
- ColumnLimit, Style.TabWidth, Encoding);
+BreakableToken::Split BreakableStringLiteral::getSplit(
+ unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+ unsigned ContentStartColumn, llvm::Regex &CommentPragmasRegex) const {
+ return getStringSplit(Line.substr(TailOffset), ContentStartColumn,
+ ColumnLimit - Postfix.size(), Style.TabWidth, Encoding);
}
void BreakableStringLiteral::insertBreak(unsigned LineIndex,
unsigned TailOffset, Split Split,
- WhitespaceManager &Whitespaces) {
+ WhitespaceManager &Whitespaces) const {
Whitespaces.replaceWhitespaceInToken(
Tok, Prefix.size() + TailOffset + Split.first, Split.second, Postfix,
Prefix, InPPDirective, 1, StartColumn);
@@ -241,19 +251,19 @@ unsigned BreakableComment::getLineCount() const { return Lines.size(); }
BreakableToken::Split
BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset,
- unsigned ColumnLimit,
+ unsigned ColumnLimit, unsigned ContentStartColumn,
llvm::Regex &CommentPragmasRegex) const {
// Don't break lines matching the comment pragmas regex.
if (CommentPragmasRegex.match(Content[LineIndex]))
return Split(StringRef::npos, 0);
return getCommentSplit(Content[LineIndex].substr(TailOffset),
- getContentStartColumn(LineIndex, TailOffset),
- ColumnLimit, Style.TabWidth, Encoding);
+ ContentStartColumn, ColumnLimit, Style.TabWidth,
+ Encoding);
}
-void BreakableComment::compressWhitespace(unsigned LineIndex,
- unsigned TailOffset, Split Split,
- WhitespaceManager &Whitespaces) {
+void BreakableComment::compressWhitespace(
+ unsigned LineIndex, unsigned TailOffset, Split Split,
+ WhitespaceManager &Whitespaces) const {
StringRef Text = Content[LineIndex].substr(TailOffset);
// Text is relative to the content line, but Whitespaces operates relative to
// the start of the corresponding token, so compute the start of the Split
@@ -267,44 +277,6 @@ void BreakableComment::compressWhitespace(unsigned LineIndex,
/*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
}
-BreakableToken::Split
-BreakableComment::getReflowSplit(StringRef Text, StringRef ReflowPrefix,
- unsigned PreviousEndColumn,
- unsigned ColumnLimit) const {
- unsigned ReflowStartColumn = PreviousEndColumn + ReflowPrefix.size();
- StringRef TrimmedText = Text.rtrim(Blanks);
- // This is the width of the resulting line in case the full line of Text gets
- // reflown up starting at ReflowStartColumn.
- unsigned FullWidth = ReflowStartColumn + encoding::columnWidthWithTabs(
- TrimmedText, ReflowStartColumn,
- Style.TabWidth, Encoding);
- // If the full line fits up, we return a reflow split after it,
- // otherwise we compute the largest piece of text that fits after
- // ReflowStartColumn.
- Split ReflowSplit =
- FullWidth <= ColumnLimit
- ? Split(TrimmedText.size(), Text.size() - TrimmedText.size())
- : getCommentSplit(Text, ReflowStartColumn, ColumnLimit,
- Style.TabWidth, Encoding);
-
- // We need to be extra careful here, because while it's OK to keep a long line
- // if it can't be broken into smaller pieces (like when the first word of a
- // long line is longer than the column limit), it's not OK to reflow that long
- // word up. So we recompute the size of the previous line after reflowing and
- // only return the reflow split if that's under the line limit.
- if (ReflowSplit.first != StringRef::npos &&
- // Check if the width of the newly reflown line is under the limit.
- PreviousEndColumn + ReflowPrefix.size() +
- encoding::columnWidthWithTabs(Text.substr(0, ReflowSplit.first),
- PreviousEndColumn +
- ReflowPrefix.size(),
- Style.TabWidth, Encoding) <=
- ColumnLimit) {
- return ReflowSplit;
- }
- return Split(StringRef::npos, 0);
-}
-
const FormatToken &BreakableComment::tokenAt(unsigned LineIndex) const {
return Tokens[LineIndex] ? *Tokens[LineIndex] : Tok;
}
@@ -501,30 +473,44 @@ void BreakableBlockComment::adjustWhitespace(unsigned LineIndex,
IndentDelta;
}
-unsigned BreakableBlockComment::getLineLengthAfterSplit(
- unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- unsigned ContentStartColumn = getContentStartColumn(LineIndex, TailOffset);
+unsigned BreakableBlockComment::getRangeLength(unsigned LineIndex,
+ unsigned Offset,
+ StringRef::size_type Length,
+ unsigned StartColumn) const {
unsigned LineLength =
- ContentStartColumn + encoding::columnWidthWithTabs(
- Content[LineIndex].substr(TailOffset, Length),
- ContentStartColumn, Style.TabWidth, Encoding);
+ encoding::columnWidthWithTabs(Content[LineIndex].substr(Offset, Length),
+ StartColumn, Style.TabWidth, Encoding);
+ // FIXME: This should go into getRemainingLength instead, but we currently
+ // break tests when putting it there. Investigate how to fix those tests.
// The last line gets a "*/" postfix.
if (LineIndex + 1 == Lines.size()) {
LineLength += 2;
// We never need a decoration when breaking just the trailing "*/" postfix.
// Note that checking that Length == 0 is not enough, since Length could
// also be StringRef::npos.
- if (Content[LineIndex].substr(TailOffset, Length).empty()) {
+ if (Content[LineIndex].substr(Offset, StringRef::npos).empty()) {
LineLength -= Decoration.size();
}
}
return LineLength;
}
+unsigned BreakableBlockComment::getRemainingLength(unsigned LineIndex,
+ unsigned Offset,
+ unsigned StartColumn) const {
+ return getRangeLength(LineIndex, Offset, StringRef::npos, StartColumn);
+}
+
+unsigned BreakableBlockComment::getContentStartColumn(unsigned LineIndex,
+ bool Break) const {
+ if (Break)
+ return IndentAtLineBreak;
+ return std::max(0, ContentColumn[LineIndex]);
+}
+
void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
Split Split,
- WhitespaceManager &Whitespaces) {
+ WhitespaceManager &Whitespaces) const {
StringRef Text = Content[LineIndex].substr(TailOffset);
StringRef Prefix = Decoration;
// We need this to account for the case when we have a decoration "* " for all
@@ -550,59 +536,14 @@ void BreakableBlockComment::insertBreak(unsigned LineIndex, unsigned TailOffset,
/*Spaces=*/LocalIndentAtLineBreak - Prefix.size());
}
-BreakableToken::Split BreakableBlockComment::getSplitBefore(
- unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
- llvm::Regex &CommentPragmasRegex) const {
+BreakableToken::Split
+BreakableBlockComment::getReflowSplit(unsigned LineIndex,
+ llvm::Regex &CommentPragmasRegex) const {
if (!mayReflow(LineIndex, CommentPragmasRegex))
return Split(StringRef::npos, 0);
- StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
- Split Result = getReflowSplit(TrimmedContent, ReflowPrefix, PreviousEndColumn,
- ColumnLimit);
- // Result is relative to TrimmedContent. Adapt it relative to
- // Content[LineIndex].
- if (Result.first != StringRef::npos)
- Result.first += Content[LineIndex].size() - TrimmedContent.size();
- return Result;
-}
-unsigned
-BreakableBlockComment::getReflownColumn(StringRef Content, unsigned LineIndex,
- unsigned PreviousEndColumn) const {
- unsigned StartColumn = PreviousEndColumn + ReflowPrefix.size();
- // If this is the last line, it will carry around its '*/' postfix.
- unsigned PostfixLength = (LineIndex + 1 == Lines.size() ? 2 : 0);
- // The line is composed of previous text, reflow prefix, reflown text and
- // postfix.
- unsigned ReflownColumn = StartColumn +
- encoding::columnWidthWithTabs(
- Content, StartColumn, Style.TabWidth, Encoding) +
- PostfixLength;
- return ReflownColumn;
-}
-
-unsigned BreakableBlockComment::getLineLengthAfterSplitBefore(
- unsigned LineIndex, unsigned TailOffset, unsigned PreviousEndColumn,
- unsigned ColumnLimit, Split SplitBefore) const {
- if (SplitBefore.first == StringRef::npos ||
- // Block comment line contents contain the trailing whitespace after the
- // decoration, so the need of left trim. Note that this behavior is
- // consistent with the breaking of block comments where the indentation of
- // a broken line is uniform across all the lines of the block comment.
- SplitBefore.first + SplitBefore.second <
- Content[LineIndex].ltrim().size()) {
- // A piece of line, not the whole, gets reflown.
- return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
- } else {
- // The whole line gets reflown, need to check if we need to insert a break
- // for the postfix or not.
- StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
- unsigned ReflownColumn =
- getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
- if (ReflownColumn <= ColumnLimit) {
- return ReflownColumn;
- }
- return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
- }
+ size_t Trimmed = Content[LineIndex].find_first_not_of(Blanks);
+ return Split(0, Trimmed != StringRef::npos ? Trimmed : 0);
}
bool BreakableBlockComment::introducesBreakBeforeToken() const {
@@ -611,49 +552,39 @@ bool BreakableBlockComment::introducesBreakBeforeToken() const {
Lines[0].substr(1).find_first_not_of(Blanks) != StringRef::npos;
}
-void BreakableBlockComment::replaceWhitespaceBefore(
- unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
- Split SplitBefore, WhitespaceManager &Whitespaces) {
+void BreakableBlockComment::reflow(unsigned LineIndex,
+ WhitespaceManager &Whitespaces) const {
+ StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
+ // Here we need to reflow.
+ assert(Tokens[LineIndex - 1] == Tokens[LineIndex] &&
+ "Reflowing whitespace within a token");
+ // This is the offset of the end of the last line relative to the start of
+ // the token text in the token.
+ unsigned WhitespaceOffsetInToken = Content[LineIndex - 1].data() +
+ Content[LineIndex - 1].size() -
+ tokenAt(LineIndex).TokenText.data();
+ unsigned WhitespaceLength = TrimmedContent.data() -
+ tokenAt(LineIndex).TokenText.data() -
+ WhitespaceOffsetInToken;
+ Whitespaces.replaceWhitespaceInToken(
+ tokenAt(LineIndex), WhitespaceOffsetInToken,
+ /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"",
+ /*CurrentPrefix=*/ReflowPrefix, InPPDirective, /*Newlines=*/0,
+ /*Spaces=*/0);
+}
+
+void BreakableBlockComment::adaptStartOfLine(
+ unsigned LineIndex, WhitespaceManager &Whitespaces) const {
if (LineIndex == 0) {
if (DelimitersOnNewline) {
- // Since we're breaking af index 1 below, the break position and the
+ // Since we're breaking at index 1 below, the break position and the
// break length are the same.
size_t BreakLength = Lines[0].substr(1).find_first_not_of(Blanks);
- if (BreakLength != StringRef::npos) {
+ if (BreakLength != StringRef::npos)
insertBreak(LineIndex, 0, Split(1, BreakLength), Whitespaces);
- DelimitersOnNewline = true;
- }
}
return;
}
- StringRef TrimmedContent = Content[LineIndex].ltrim(Blanks);
- if (SplitBefore.first != StringRef::npos) {
- // Here we need to reflow.
- assert(Tokens[LineIndex - 1] == Tokens[LineIndex] &&
- "Reflowing whitespace within a token");
- // This is the offset of the end of the last line relative to the start of
- // the token text in the token.
- unsigned WhitespaceOffsetInToken = Content[LineIndex - 1].data() +
- Content[LineIndex - 1].size() -
- tokenAt(LineIndex).TokenText.data();
- unsigned WhitespaceLength = TrimmedContent.data() -
- tokenAt(LineIndex).TokenText.data() -
- WhitespaceOffsetInToken;
- Whitespaces.replaceWhitespaceInToken(
- tokenAt(LineIndex), WhitespaceOffsetInToken,
- /*ReplaceChars=*/WhitespaceLength, /*PreviousPostfix=*/"",
- /*CurrentPrefix=*/ReflowPrefix, InPPDirective, /*Newlines=*/0,
- /*Spaces=*/0);
- // Check if we need to also insert a break at the whitespace range.
- // Note that we don't need a penalty for this break, since it doesn't change
- // the total number of lines.
- unsigned ReflownColumn =
- getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
- if (ReflownColumn > ColumnLimit)
- insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
- return;
- }
-
// Here no reflow with the previous line will happen.
// Fix the decoration of the line at LineIndex.
StringRef Prefix = Decoration;
@@ -689,8 +620,7 @@ void BreakableBlockComment::replaceWhitespaceBefore(
}
BreakableToken::Split
-BreakableBlockComment::getSplitAfterLastLine(unsigned TailOffset,
- unsigned ColumnLimit) const {
+BreakableBlockComment::getSplitAfterLastLine(unsigned TailOffset) const {
if (DelimitersOnNewline) {
// Replace the trailing whitespace of the last line with a newline.
// In case the last line is empty, the ending '*/' is already on its own
@@ -716,15 +646,6 @@ bool BreakableBlockComment::mayReflow(unsigned LineIndex,
!switchesFormatting(tokenAt(LineIndex));
}
-unsigned
-BreakableBlockComment::getContentStartColumn(unsigned LineIndex,
- unsigned TailOffset) const {
- // If we break, we always break at the predefined indent.
- if (TailOffset != 0)
- return IndentAtLineBreak;
- return std::max(0, ContentColumn[LineIndex]);
-}
-
BreakableLineCommentSection::BreakableLineCommentSection(
const FormatToken &Token, unsigned StartColumn,
unsigned OriginalStartColumn, bool FirstInLine, bool InPPDirective,
@@ -813,20 +734,25 @@ BreakableLineCommentSection::BreakableLineCommentSection(
}
}
-unsigned BreakableLineCommentSection::getLineLengthAfterSplit(
- unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- unsigned ContentStartColumn =
- (TailOffset == 0 ? ContentColumn[LineIndex]
- : OriginalContentColumn[LineIndex]);
- return ContentStartColumn + encoding::columnWidthWithTabs(
- Content[LineIndex].substr(TailOffset, Length),
- ContentStartColumn, Style.TabWidth, Encoding);
+unsigned
+BreakableLineCommentSection::getRangeLength(unsigned LineIndex, unsigned Offset,
+ StringRef::size_type Length,
+ unsigned StartColumn) const {
+ return encoding::columnWidthWithTabs(
+ Content[LineIndex].substr(Offset, Length), StartColumn, Style.TabWidth,
+ Encoding);
+}
+
+unsigned BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex,
+ bool Break) const {
+ if (Break)
+ return OriginalContentColumn[LineIndex];
+ return ContentColumn[LineIndex];
}
-void BreakableLineCommentSection::insertBreak(unsigned LineIndex,
- unsigned TailOffset, Split Split,
- WhitespaceManager &Whitespaces) {
+void BreakableLineCommentSection::insertBreak(
+ unsigned LineIndex, unsigned TailOffset, Split Split,
+ WhitespaceManager &Whitespaces) const {
StringRef Text = Content[LineIndex].substr(TailOffset);
// Compute the offset of the split relative to the beginning of the token
// text.
@@ -845,34 +771,42 @@ void BreakableLineCommentSection::insertBreak(unsigned LineIndex,
/*Spaces=*/IndentAtLineBreak - Prefix[LineIndex].size());
}
-BreakableComment::Split BreakableLineCommentSection::getSplitBefore(
- unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
- llvm::Regex &CommentPragmasRegex) const {
+BreakableComment::Split BreakableLineCommentSection::getReflowSplit(
+ unsigned LineIndex, llvm::Regex &CommentPragmasRegex) const {
if (!mayReflow(LineIndex, CommentPragmasRegex))
return Split(StringRef::npos, 0);
- return getReflowSplit(Content[LineIndex], ReflowPrefix, PreviousEndColumn,
- ColumnLimit);
-}
-
-unsigned BreakableLineCommentSection::getLineLengthAfterSplitBefore(
- unsigned LineIndex, unsigned TailOffset, unsigned PreviousEndColumn,
- unsigned ColumnLimit, Split SplitBefore) const {
- if (SplitBefore.first == StringRef::npos ||
- SplitBefore.first + SplitBefore.second < Content[LineIndex].size()) {
- // A piece of line, not the whole line, gets reflown.
- return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
- } else {
- // The whole line gets reflown.
- unsigned StartColumn = PreviousEndColumn + ReflowPrefix.size();
- return StartColumn +
- encoding::columnWidthWithTabs(Content[LineIndex], StartColumn,
- Style.TabWidth, Encoding);
- }
-}
-void BreakableLineCommentSection::replaceWhitespaceBefore(
- unsigned LineIndex, unsigned PreviousEndColumn, unsigned ColumnLimit,
- Split SplitBefore, WhitespaceManager &Whitespaces) {
+ size_t Trimmed = Content[LineIndex].find_first_not_of(Blanks);
+
+ // In a line comment section each line is a separate token; thus, after a
+ // split we replace all whitespace before the current line comment token
+ // (which does not need to be included in the split), plus the start of the
+ // line up to where the content starts.
+ return Split(0, Trimmed != StringRef::npos ? Trimmed : 0);
+}
+
+void BreakableLineCommentSection::reflow(unsigned LineIndex,
+ WhitespaceManager &Whitespaces) const {
+ // Reflow happens between tokens. Replace the whitespace between the
+ // tokens by the empty string.
+ Whitespaces.replaceWhitespace(
+ *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0,
+ /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false);
+ // Replace the indent and prefix of the token with the reflow prefix.
+ unsigned WhitespaceLength =
+ Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data();
+ Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex],
+ /*Offset=*/0,
+ /*ReplaceChars=*/WhitespaceLength,
+ /*PreviousPostfix=*/"",
+ /*CurrentPrefix=*/ReflowPrefix,
+ /*InPPDirective=*/false,
+ /*Newlines=*/0,
+ /*Spaces=*/0);
+}
+
+void BreakableLineCommentSection::adaptStartOfLine(
+ unsigned LineIndex, WhitespaceManager &Whitespaces) const {
// If this is the first line of a token, we need to inform Whitespace Manager
// about it: either adapt the whitespace range preceding it, or mark it as an
// untouchable token.
@@ -880,44 +814,25 @@ void BreakableLineCommentSection::replaceWhitespaceBefore(
// // line 1 \
// // line 2
if (LineIndex > 0 && Tokens[LineIndex] != Tokens[LineIndex - 1]) {
- if (SplitBefore.first != StringRef::npos) {
- // Reflow happens between tokens. Replace the whitespace between the
- // tokens by the empty string.
- Whitespaces.replaceWhitespace(
- *Tokens[LineIndex], /*Newlines=*/0, /*Spaces=*/0,
- /*StartOfTokenColumn=*/StartColumn, /*InPPDirective=*/false);
- // Replace the indent and prefix of the token with the reflow prefix.
- unsigned WhitespaceLength =
- Content[LineIndex].data() - tokenAt(LineIndex).TokenText.data();
- Whitespaces.replaceWhitespaceInToken(*Tokens[LineIndex],
- /*Offset=*/0,
- /*ReplaceChars=*/WhitespaceLength,
- /*PreviousPostfix=*/"",
- /*CurrentPrefix=*/ReflowPrefix,
- /*InPPDirective=*/false,
- /*Newlines=*/0,
- /*Spaces=*/0);
- } else {
- // This is the first line for the current token, but no reflow with the
- // previous token is necessary. However, we still may need to adjust the
- // start column. Note that ContentColumn[LineIndex] is the expected
- // content column after a possible update to the prefix, hence the prefix
- // length change is included.
- unsigned LineColumn =
- ContentColumn[LineIndex] -
- (Content[LineIndex].data() - Lines[LineIndex].data()) +
- (OriginalPrefix[LineIndex].size() - Prefix[LineIndex].size());
-
- // We always want to create a replacement instead of adding an untouchable
- // token, even if LineColumn is the same as the original column of the
- // token. This is because WhitespaceManager doesn't align trailing
- // comments if they are untouchable.
- Whitespaces.replaceWhitespace(*Tokens[LineIndex],
- /*Newlines=*/1,
- /*Spaces=*/LineColumn,
- /*StartOfTokenColumn=*/LineColumn,
- /*InPPDirective=*/false);
- }
+ // This is the first line for the current token, but no reflow with the
+ // previous token is necessary. However, we still may need to adjust the
+ // start column. Note that ContentColumn[LineIndex] is the expected
+ // content column after a possible update to the prefix, hence the prefix
+ // length change is included.
+ unsigned LineColumn =
+ ContentColumn[LineIndex] -
+ (Content[LineIndex].data() - Lines[LineIndex].data()) +
+ (OriginalPrefix[LineIndex].size() - Prefix[LineIndex].size());
+
+ // We always want to create a replacement instead of adding an untouchable
+ // token, even if LineColumn is the same as the original column of the
+ // token. This is because WhitespaceManager doesn't align trailing
+ // comments if they are untouchable.
+ Whitespaces.replaceWhitespace(*Tokens[LineIndex],
+ /*Newlines=*/1,
+ /*Spaces=*/LineColumn,
+ /*StartOfTokenColumn=*/LineColumn,
+ /*InPPDirective=*/false);
}
if (OriginalPrefix[LineIndex] != Prefix[LineIndex]) {
// Adjust the prefix if necessary.
@@ -930,13 +845,6 @@ void BreakableLineCommentSection::replaceWhitespaceBefore(
tokenAt(LineIndex), OriginalPrefix[LineIndex].size(), 0, "", "",
/*InPPDirective=*/false, /*Newlines=*/0, /*Spaces=*/1);
}
- // Add a break after a reflow split has been introduced, if necessary.
- // Note that this break doesn't need to be penalized, since it doesn't change
- // the number of lines.
- if (SplitBefore.first != StringRef::npos &&
- SplitBefore.first + SplitBefore.second < Content[LineIndex].size()) {
- insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
- }
}
void BreakableLineCommentSection::updateNextToken(LineState &State) const {
@@ -953,20 +861,17 @@ bool BreakableLineCommentSection::mayReflow(
if (Lines[LineIndex].startswith("//")) {
IndentContent = Lines[LineIndex].substr(2);
}
+ // FIXME: Decide whether we want to reflow non-regular indents:
+ // Currently, we only reflow when the OriginalPrefix[LineIndex] matches the
+ // OriginalPrefix[LineIndex-1]. That means we don't reflow
+ // // text that protrudes
+ // // into text with different indent
+ // We do reflow in that case in block comments.
return LineIndex > 0 && !CommentPragmasRegex.match(IndentContent) &&
mayReflowContent(Content[LineIndex]) && !Tok.Finalized &&
!switchesFormatting(tokenAt(LineIndex)) &&
OriginalPrefix[LineIndex] == OriginalPrefix[LineIndex - 1];
}
-unsigned
-BreakableLineCommentSection::getContentStartColumn(unsigned LineIndex,
- unsigned TailOffset) const {
- if (TailOffset != 0) {
- return OriginalContentColumn[LineIndex];
- }
- return ContentColumn[LineIndex];
-}
-
} // namespace format
} // namespace clang