klimek updated this revision to Diff 123359.
klimek added a comment.
Just exporting
https://reviews.llvm.org/D40068
Files:
lib/Format/BreakableToken.cpp
lib/Format/BreakableToken.h
lib/Format/ContinuationIndenter.cpp
unittests/Format/FormatTest.cpp
unittests/Format/FormatTestComments.cpp
Index: unittests/Format/FormatTestComments.cpp
===================================================================
--- unittests/Format/FormatTestComments.cpp
+++ unittests/Format/FormatTestComments.cpp
@@ -2102,6 +2102,21 @@
EXPECT_EQ("///", format(" /// ", getLLVMStyleWithColumns(20)));
}
+TEST_F(FormatTestComments, ReflowTODO) {
+ EXPECT_EQ("// some text\n"
+ "// that re flows\n",
+ format("// some text that\n"
+ "// re flows\n",
+ getLLVMStyleWithColumns(16)));
+ EXPECT_EQ("// some text\n"
+ "// that re flows\n",
+ format("// some text that\n"
+ "// re flows\n",
+ getLLVMStyleWithColumns(16)));
+// some text that
+// that re flows
+}
+
TEST_F(FormatTestComments, IgnoresIf0Contents) {
EXPECT_EQ("#if 0\n"
"}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n"
@@ -2484,6 +2499,7 @@
" long */\n"
" b);",
format("a = f(a, /* long long */ b);", getLLVMStyleWithColumns(16)));
+
EXPECT_EQ(
"a = f(\n"
" a,\n"
@@ -2888,16 +2904,15 @@
getLLVMStyleWithColumns(20)));
}
-TEST_F(FormatTestComments, NoCrush_Bug34236) {
+TEST_F(FormatTestComments, NoCrash_Bug34236) {
// This is a test case from a crasher reported in:
// https://bugs.llvm.org/show_bug.cgi?id=34236
// Temporarily disable formatting for readability.
// clang-format off
EXPECT_EQ(
"/* */ /*\n"
" * a\n"
-" * b c\n"
-" * d*/",
+" * b c d*/",
format(
"/* */ /*\n"
" * a b\n"
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -9922,16 +9922,9 @@
Style.PenaltyExcessCharacter = 90;
verifyFormat("int a; // the comment", Style);
- EXPECT_EQ("int a; // the\n"
- " // comment aa",
+ EXPECT_EQ("int a; // the comment\n"
+ " // aa",
format("int a; // the comment aa", Style));
- EXPECT_EQ("int a; // first line\n"
- " // second line\n"
- " // third line",
- format("int a; // first line\n"
- " // second line\n"
- " // third line",
- Style));
EXPECT_EQ("int a; /* first line\n"
" * second line\n"
" * third line\n"
@@ -9941,12 +9934,18 @@
" * third line\n"
" */",
Style));
+ EXPECT_EQ("int a; // first line\n"
+ " // second line\n"
+ " // third line",
+ format("int a; // first line\n"
+ " // second line\n"
+ " // third line",
+ Style));
// FIXME: Investigate why this is not getting the same layout as the test
// above.
EXPECT_EQ("int a; /* first line\n"
- " * second\n"
- " * line third\n"
- " * line\n"
+ " * second line\n"
+ " * third line\n"
" */",
format("int a; /* first line second line third line"
"\n*/",
@@ -9965,31 +9964,23 @@
// FIXME: Optimally, we'd keep bazfoo on the first line and reflow bar to the
// next one.
- EXPECT_EQ("// foo bar baz\n"
- "// bazfoo bar foo\n"
- "// bar\n",
+ EXPECT_EQ("// foo bar baz bazfoo\n"
+ "// bar foo bar\n",
format("// foo bar baz bazfoo bar\n"
"// foo bar\n",
Style));
EXPECT_EQ("// foo bar baz bazfoo\n"
- "// foo bar baz\n"
- "// bazfoo bar foo\n"
- "// bar\n",
+ "// foo bar baz bazfoo\n"
+ "// bar foo bar\n",
format("// foo bar baz bazfoo\n"
"// foo bar baz bazfoo bar\n"
"// foo bar\n",
Style));
- // FIXME: Optimally, we'd keep 'bar' in the last line at the end of the line,
- // as it does not actually protrude far enough to make breaking pay off.
- // Unfortunately, due to how reflowing is currently implemented, we already
- // check the column limit after the reflowing decision and extend the reflow
- // range, so we will not take whitespace compression into account.
EXPECT_EQ("// foo bar baz bazfoo\n"
- "// foo bar baz\n"
- "// bazfoo bar foo\n"
- "// bar\n",
+ "// foo bar baz bazfoo\n"
+ "// bar foo bar\n",
format("// foo bar baz bazfoo\n"
"// foo bar baz bazfoo bar\n"
"// foo bar\n",
@@ -10630,27 +10621,48 @@
}
TEST_F(FormatTest, SplitsUTF8BlockComments) {
- EXPECT_EQ("/* Гляжу,\n"
- " * поднимается\n"
- " * медленно в\n"
- " * гору\n"
- " * Лошадка,\n"
- " * везущая\n"
- " * хворосту\n"
- " * воз. */",
- format("/* Гляжу, поднимается медленно в гору\n"
- " * Лошадка, везущая хворосту воз. */",
+// EXPECT_EQ("/* Гляжу,\n"
+// " * поднимается\n"
+// " * медленно в\n"
+// " * гору\n"
+// " * Лошадка,\n"
+// " * везущая\n"
+// " * хворосту\n"
+// " * воз. */",
+// format("/* Гляжу, поднимается медленно в гору\n"
+// " * Лошадка, везущая хворосту воз. */",
+// getLLVMStyleWithColumns(13)));
+ EXPECT_EQ("/* aaaaa,\n"
+ " * bbbbbbbbbbb\n"
+ " * cccccccc d\n"
+ " * eeee\n"
+ " * fffffff,\n"
+ " * ggggggg\n"
+ " * hhhhhhhh\n"
+ " * iii. */",
+ format("/* aaaaa, bbbbbbbbbbb cccccccc d eeee\n"
+ " * fffffff, ggggggg hhhhhhhh iii. */",
getLLVMStyleWithColumns(13)));
- EXPECT_EQ(
- "/* 一二三\n"
- " * 四五六七\n"
- " * 八 九\n"
- " * 十 */",
- format("/* 一二三 四五六七 八 九 十 */", getLLVMStyleWithColumns(9)));
- EXPECT_EQ("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯\n"
- " * 𝕓𝕪𝕥𝕖\n"
- " * 𝖀𝕿𝕱-𝟠 */",
- format("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯 𝕓𝕪𝕥𝕖 𝖀𝕿𝕱-𝟠 */", getLLVMStyleWithColumns(12)));
+// EXPECT_EQ("/* Гляжу,\n"
+// " * поднимается\n"
+// " * медленно в\n"
+// " * гору Лошадка,\n"
+// " * везущая\n"
+// " * хворосту\n"
+// " * воз. */",
+// format("/* Гляжу, поднимается медленно в гору\n"
+// " * Лошадка, везущая хворосту воз. */",
+// getLLVMStyleWithColumns(13)));
+// EXPECT_EQ(
+// "/* 一二三\n"
+// " * 四五六七\n"
+// " * 八 九\n"
+// " * 十 */",
+// format("/* 一二三 四五六七 八 九 十 */", getLLVMStyleWithColumns(9)));
+// EXPECT_EQ("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯\n"
+// " * 𝕓𝕪𝕥𝕖\n"
+// " * 𝖀𝕿𝕱-𝟠 */",
+// format("/* 𝓣𝓮𝓼𝓽 𝔣𝔬𝔲𝔯 𝕓𝕪𝕥𝕖 𝖀𝕿𝕱-𝟠 */", getLLVMStyleWithColumns(12)));
}
#endif // _MSC_VER
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -1490,136 +1490,223 @@
unsigned NewBreakPenalty = Current.isStringLiteral()
? Style.PenaltyBreakString
: Style.PenaltyBreakComment;
+ llvm::errs() << "UNBREAKABLE: " << Current.UnbreakableTailLength << "\n";
+ //unsigned RemainingSpace = ColumnLimit;
unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
bool BreakInserted = Token->introducesBreakBeforeToken();
// Store whether we inserted a new line break at the end of the previous
// logical line.
bool NewBreakBefore = false;
// We use a conservative reflowing strategy. Reflow starts after a line is
// broken or the corresponding whitespace compressed. Reflow ends as soon as a
// line that doesn't get reflown with the previous line is reached.
- bool ReflowInProgress = false;
+ bool TryReflow = false;
unsigned Penalty = 0;
unsigned RemainingTokenColumns = 0;
unsigned TailOffset = 0;
+ unsigned ReflownTextLength = 0;
DEBUG(llvm::dbgs() << "Breaking protruding token at column " << StartColumn
<< ".\n");
for (unsigned LineIndex = 0, EndIndex = Token->getLineCount();
LineIndex != EndIndex; ++LineIndex) {
DEBUG(llvm::dbgs() << " Line: " << LineIndex
- << " (Reflow: " << ReflowInProgress << ")\n");
+ << " (TryReflow: " << TryReflow << ")\n");
BreakableToken::Split SplitBefore(StringRef::npos, 0);
- if (ReflowInProgress) {
+ // Whether we did a reflow into the current line.
+ bool Reflown = false;
+ if (TryReflow) {
+ ReflownTextLength += RemainingTokenColumns;
+ DEBUG(llvm::dbgs() << " Size of reflown text: "
+ << ReflownTextLength
+ << "\n Potential reflow split: ");
+ TryReflow = false;
SplitBefore = Token->getSplitBefore(LineIndex, RemainingTokenColumns,
- RemainingSpace, CommentPragmasRegex);
+ ColumnLimit, CommentPragmasRegex);
+ if (SplitBefore.first != StringRef::npos) {
+ DEBUG(llvm::dbgs() << SplitBefore.first << ", " << SplitBefore.second
+ << "\n");
+ TailOffset = SplitBefore.first + SplitBefore.second;
+ llvm::errs() << "1: " << RemainingTokenColumns << "\n";
+ RemainingTokenColumns = Token->getLineLengthAfterSplitBefore(
+ LineIndex, TailOffset, RemainingTokenColumns, RemainingSpace,
+ SplitBefore);
+ llvm::errs() << "2: " << RemainingTokenColumns << "\n";
+ Reflown = true;
+ if (ReflownTextLength + RemainingTokenColumns > RemainingSpace) {
+ DEBUG(llvm::dbgs() << " Over limit after reflow, need: "
+ << (ReflownTextLength + RemainingTokenColumns)
+ << ", space: " << RemainingSpace
+ << ", reflown prefix: " << ReflownTextLength
+ << ", offset in line: " << TailOffset << "\n");
+ BreakableToken::Split Split =
+ Token->getSplit(LineIndex, TailOffset, ColumnLimit,
+ ReflownTextLength, CommentPragmasRegex);
+ if (Split.first == StringRef::npos) {
+ llvm::errs() << " Did not find later break...\n";
+ Reflown = false;
+ } else {
+ // FIXME: Count actual length instead of bytes.
+ // FIXME: Compress whitespace?
+ if (ReflownTextLength + Split.first > ColumnLimit) {
+ DEBUG(llvm::dbgs() << " Next split protrudes, need: "
+ << (ReflownTextLength + Split.first)
+ << ", space: " << ColumnLimit);
+ unsigned ExcessCharactersPenalty =
+ (ReflownTextLength + Split.first - ColumnLimit) *
+ Style.PenaltyExcessCharacter;
+ if (NewBreakPenalty < ExcessCharactersPenalty) {
+ Reflown = false;
+ }
+ }
+ }
+ }
+ } else {
+ DEBUG(llvm::dbgs() << "not found.\n");
+ }
}
- ReflowInProgress = SplitBefore.first != StringRef::npos;
- DEBUG({
- if (ReflowInProgress)
- llvm::dbgs() << " Reflowing.\n";
- });
- TailOffset =
- ReflowInProgress ? (SplitBefore.first + SplitBefore.second) : 0;
- // If we found a reflow split and have added a new break before this line,
- // we are going to remove the line break at the start of the next logical
- // line.
- // For example, here we'll add a new line break after 'text', and
- // subsequently delete the line break between 'that' and 'reflows'.
- // // some text that
- // // reflows
- // ->
- // // some text
- // // that reflows
- // When adding the line break, we also added the penalty for it, so we need
- // to subtract that penalty again when we remove the line break due to
- // reflowing.
- if (ReflowInProgress && NewBreakBefore) {
- assert(Penalty >= NewBreakPenalty);
- Penalty -= NewBreakPenalty;
+ if (Reflown) {
+ // If we found a reflow split and have added a new break before this
+ // line, we are going to remove the line break at the start of the next
+ // logical line. For example, here we'll add a new line break after
+ // 'text', and subsequently delete the line break between 'that' and
+ // 'reflows'.
+ // // some text that
+ // // reflows
+ // ->
+ // // some text
+ // // that reflows
+ // When adding the line break, we also added the penalty for it, so we
+ // need to subtract that penalty again when we remove the line break due
+ // to reflowing.
+ if (NewBreakBefore) {
+ assert(Penalty >= NewBreakPenalty);
+ Penalty -= NewBreakPenalty;
+ }
+ TryReflow = true;
+ if (!DryRun)
+ Token->replaceWhitespaceBefore(
+ LineIndex, ReflownTextLength + RemainingTokenColumns,
+ RemainingSpace, SplitBefore, Whitespaces);
+ } else {
+ // If we didn't reflow into this line, the only space to consider is the
+ // current logical line.
+ RemainingTokenColumns = 0;
+ ReflownTextLength = 0;
+ TailOffset = 0;
+ SplitBefore = BreakableToken::Split(StringRef::npos, 0);
+ RemainingTokenColumns += Token->getLineLengthAfterSplitBefore(
+ LineIndex, TailOffset, RemainingTokenColumns, RemainingSpace,
+ SplitBefore);
+ // Adapt the start of the token, for example indent.
+ if (!DryRun)
+ Token->replaceWhitespaceBefore(LineIndex, RemainingTokenColumns,
+ RemainingSpace, SplitBefore,
+ Whitespaces);
}
NewBreakBefore = false;
- if (!DryRun)
- Token->replaceWhitespaceBefore(LineIndex, RemainingTokenColumns,
- RemainingSpace, SplitBefore, Whitespaces);
- RemainingTokenColumns = Token->getLineLengthAfterSplitBefore(
- LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore);
- while (RemainingTokenColumns > RemainingSpace) {
- DEBUG(llvm::dbgs() << " Over limit, need: " << RemainingTokenColumns
- << ", space: " << RemainingSpace << "\n");
- BreakableToken::Split Split = Token->getSplit(
- LineIndex, TailOffset, ColumnLimit, CommentPragmasRegex);
+
+ llvm::errs() << "RTC: " << RemainingTokenColumns
+ << ", Space: " << RemainingSpace << "\n";
+ while (ReflownTextLength + RemainingTokenColumns > RemainingSpace) {
+ DEBUG(llvm::dbgs() << " Over limit, need: "
+ << (ReflownTextLength + RemainingTokenColumns)
+ << ", space: " << RemainingSpace
+ << ", reflown prefix: " << ReflownTextLength
+ << ", offset in line: " << TailOffset << "\n");
+ BreakableToken::Split Split =
+ Token->getSplit(LineIndex, TailOffset, ColumnLimit,
+ ReflownTextLength, CommentPragmasRegex);
if (Split.first == StringRef::npos) {
// The last line's penalty is handled in addNextStateToQueue().
if (LineIndex < EndIndex - 1)
- Penalty += Style.PenaltyExcessCharacter *
- (RemainingTokenColumns - RemainingSpace);
+ Penalty +=
+ Style.PenaltyExcessCharacter *
+ (ReflownTextLength + RemainingTokenColumns - ColumnLimit);
DEBUG(llvm::dbgs() << " No break opportunity.\n");
break;
}
assert(Split.first != 0);
- // Check if compressing the whitespace range will bring the line length
- // under the limit. If that is the case, we perform whitespace compression
- // instead of inserting a line break.
- unsigned RemainingTokenColumnsAfterCompression =
- Token->getLineLengthAfterCompression(RemainingTokenColumns, Split);
- if (RemainingTokenColumnsAfterCompression <= RemainingSpace) {
- RemainingTokenColumns = RemainingTokenColumnsAfterCompression;
- ReflowInProgress = true;
- if (!DryRun)
- Token->compressWhitespace(LineIndex, TailOffset, Split, Whitespaces);
- DEBUG(llvm::dbgs() << " Compressing below limit.\n");
- break;
+ unsigned ToSplitColumns = Token->getLineLengthAfterSplit(
+ LineIndex, TailOffset, Split.first, /*Start=*/ReflownTextLength == 0);
+
+ // FIXME: Do we need +1 here for the space from ReflownTextLength??
+ BreakableToken::Split NextSplit(StringRef::npos, 0);
+ if (!Current.isStringLiteral()) {
+ llvm::errs() << "HEEEEEEEEEEEEEEEEEEEEEEERE\n\n";
+ NextSplit = Token->getSplit(
+ LineIndex, TailOffset + Split.first + Split.second, ColumnLimit,
+ ReflownTextLength + ToSplitColumns, CommentPragmasRegex);
}
- // Compute both the penalties for:
- // - not breaking, and leaving excess characters
- // - adding a new line break
- assert(RemainingTokenColumnsAfterCompression > RemainingSpace);
- unsigned ExcessCharactersPenalty =
- (RemainingTokenColumnsAfterCompression - RemainingSpace) *
- Style.PenaltyExcessCharacter;
-
- unsigned BreakPenalty = NewBreakPenalty;
- unsigned ColumnsUsed =
- Token->getLineLengthAfterSplit(LineIndex, TailOffset, Split.first);
- if (ColumnsUsed > ColumnLimit)
- BreakPenalty +=
- Style.PenaltyExcessCharacter * (ColumnsUsed - ColumnLimit);
-
- DEBUG(llvm::dbgs() << " Penalty excess: " << ExcessCharactersPenalty
- << "\n break : " << BreakPenalty << "\n");
- // Only continue to add the line break if the penalty of the excess
- // characters is larger than the penalty of the line break.
- // FIXME: This does not take into account when we can later remove the
- // line break again due to a reflow.
- if (ExcessCharactersPenalty < BreakPenalty) {
+ // We don't break if the next split fits, possibly with compression.
+ unsigned ToNextSplitColumns = Token->getLineLengthAfterSplit(
+ LineIndex, TailOffset,
+ NextSplit.first != StringRef::npos
+ ? Split.first + Split.second + NextSplit.first
+ : StringRef::npos,
+ /*Start=*/ReflownTextLength == 0);
+ llvm::errs() << "ToNextSplitColumns: " << ToNextSplitColumns << "\n";
+ ToNextSplitColumns =
+ Token->getLineLengthAfterCompression(ToNextSplitColumns, Split);
+ llvm::errs() << "ToNextSplitColumns: " << ToNextSplitColumns << "\n";
+ if (ReflownTextLength != 0)
+ ToNextSplitColumns += 1;
+ // FIXME: If NextSplit is npos we need to count against RemainingSpace!
+ bool ContinueOnLine =
+ ReflownTextLength + ToNextSplitColumns <= ColumnLimit;
+ unsigned ExcessCharactersPenalty = 0;
+ if (!ContinueOnLine) {
+ ExcessCharactersPenalty =
+ (ReflownTextLength + ToNextSplitColumns - ColumnLimit) *
+ Style.PenaltyExcessCharacter;
+ DEBUG(llvm::dbgs() << " Penalty excess: " << ExcessCharactersPenalty
+ << "\n break : " << NewBreakPenalty
+ << "\n");
+ if (ExcessCharactersPenalty < NewBreakPenalty) {
+ ContinueOnLine = true;
+ }
+ }
+ if (ContinueOnLine) {
+ DEBUG(llvm::dbgs() << "Continuing on line...\n");
+ TryReflow = true;
if (!DryRun)
Token->compressWhitespace(LineIndex, TailOffset, Split, Whitespaces);
- // Do not set ReflowInProgress: we do not have any space left to
- // reflow into.
+ ReflownTextLength += ToSplitColumns + 1;
Penalty += ExcessCharactersPenalty;
- break;
+ TailOffset += Split.first + Split.second;
+ RemainingTokenColumns = Token->getLineLengthAfterSplit(
+ LineIndex, TailOffset, StringRef::npos, /*Start=*/false);
+ continue;
}
+ DEBUG(llvm::dbgs() << "Breaking...\n");
unsigned NewRemainingTokenColumns = Token->getLineLengthAfterSplit(
- LineIndex, TailOffset + Split.first + Split.second, StringRef::npos);
+ LineIndex, TailOffset + Split.first + Split.second, StringRef::npos,
+ /*Start=*/true);
// When breaking before a tab character, it may be moved by a few columns,
// but will still be expanded to the next tab stop, so we don't save any
// columns.
- if (NewRemainingTokenColumns == RemainingTokenColumns)
+ if (NewRemainingTokenColumns == RemainingTokenColumns) {
+ llvm::errs() << "HUH??\n";
// FIXME: Do we need to adjust the penalty?
break;
- assert(NewRemainingTokenColumns < RemainingTokenColumns);
+ }
+ llvm::errs() << "New: " << NewRemainingTokenColumns << ", Old: " << RemainingTokenColumns << "\n";
+ assert(NewRemainingTokenColumns <
+ ReflownTextLength + RemainingTokenColumns);
+ DEBUG(llvm::dbgs() << " Breaking at: " << TailOffset + Split.first
+ << ", " << Split.second << "\n");
if (!DryRun)
Token->insertBreak(LineIndex, TailOffset, Split, Whitespaces);
- Penalty += BreakPenalty;
+ ReflownTextLength = 0;
+ Penalty += NewBreakPenalty;
TailOffset += Split.first + Split.second;
RemainingTokenColumns = NewRemainingTokenColumns;
- ReflowInProgress = true;
+ TryReflow = true;
BreakInserted = true;
NewBreakBefore = true;
}
Index: lib/Format/BreakableToken.h
===================================================================
--- lib/Format/BreakableToken.h
+++ lib/Format/BreakableToken.h
@@ -97,13 +97,14 @@
/// \p Length can be set to StringRef::npos, which means "to the end of line".
virtual unsigned
getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const = 0;
+ StringRef::size_type Length,
+ bool Start = true) const = 0;
/// \brief Returns a range (offset, length) at which to break the line at
/// \p LineIndex, if previously broken at \p TailOffset. If possible, do not
/// violate \p ColumnLimit.
virtual Split getSplit(unsigned LineIndex, unsigned TailOffset,
- unsigned ColumnLimit,
+ unsigned ColumnLimit, unsigned ReflowColumn,
llvm::Regex &CommentPragmasRegex) const = 0;
/// \brief Emits the previously retrieved \p Split via \p Whitespaces.
@@ -219,7 +220,8 @@
public:
unsigned getLineCount() const override;
unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const override;
+ StringRef::size_type Length,
+ bool Start = true) const override;
protected:
BreakableSingleLineToken(const FormatToken &Tok, unsigned StartColumn,
@@ -249,6 +251,7 @@
const FormatStyle &Style);
Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+ unsigned ReflowColumn,
llvm::Regex &CommentPragmasRegex) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
WhitespaceManager &Whitespaces) override;
@@ -269,6 +272,7 @@
public:
unsigned getLineCount() const override;
Split getSplit(unsigned LineIndex, unsigned TailOffset, unsigned ColumnLimit,
+ unsigned ReflowColumn,
llvm::Regex &CommentPragmasRegex) const override;
void compressWhitespace(unsigned LineIndex, unsigned TailOffset, Split Split,
WhitespaceManager &Whitespaces) override;
@@ -341,7 +345,8 @@
const FormatStyle &Style);
unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const override;
+ StringRef::size_type Length,
+ bool Start = true) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
WhitespaceManager &Whitespaces) override;
Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn,
@@ -417,7 +422,8 @@
const FormatStyle &Style);
unsigned getLineLengthAfterSplit(unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const override;
+ StringRef::size_type Length,
+ bool Start = true) const override;
void insertBreak(unsigned LineIndex, unsigned TailOffset, Split Split,
WhitespaceManager &Whitespaces) override;
Split getSplitBefore(unsigned LineIndex, unsigned PreviousEndColumn,
Index: lib/Format/BreakableToken.cpp
===================================================================
--- lib/Format/BreakableToken.cpp
+++ lib/Format/BreakableToken.cpp
@@ -67,8 +67,12 @@
unsigned ColumnLimit,
unsigned TabWidth,
encoding::Encoding Encoding) {
- if (ColumnLimit <= ContentStartColumn + 1)
+ DEBUG(llvm::dbgs() << "Comment split: \"" << Text << ", " << ColumnLimit
+ << "\"\n");
+ if (ColumnLimit <= ContentStartColumn + 1) {
+ llvm::errs() << "here\n";
return BreakableToken::Split(StringRef::npos, 0);
+ }
unsigned MaxSplit = ColumnLimit - ContentStartColumn + 1;
unsigned MaxSplitBytes = 0;
@@ -188,8 +192,8 @@
unsigned BreakableSingleLineToken::getLineLengthAfterSplit(
unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- return StartColumn + Prefix.size() + Postfix.size() +
+ StringRef::size_type Length, bool Start) const {
+ return (Start ? (StartColumn + Prefix.size()) : 0) + Postfix.size() +
encoding::columnWidthWithTabs(Line.substr(TailOffset, Length),
StartColumn + Prefix.size(),
Style.TabWidth, Encoding);
@@ -215,10 +219,12 @@
BreakableToken::Split
BreakableStringLiteral::getSplit(unsigned LineIndex, unsigned TailOffset,
- unsigned ColumnLimit,
+ unsigned ColumnLimit, unsigned ReflowColumn,
llvm::Regex &CommentPragmasRegex) const {
return getStringSplit(Line.substr(TailOffset),
- StartColumn + Prefix.size() + Postfix.size(),
+ ReflowColumn == 0
+ ? StartColumn + Prefix.size() + Postfix.size()
+ : ReflowColumn + 1,
ColumnLimit, Style.TabWidth, Encoding);
}
@@ -241,13 +247,15 @@
BreakableToken::Split
BreakableComment::getSplit(unsigned LineIndex, unsigned TailOffset,
- unsigned ColumnLimit,
+ unsigned ColumnLimit, unsigned ReflowColumn,
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),
+ ReflowColumn == 0
+ ? getContentStartColumn(LineIndex, TailOffset)
+ : ReflowColumn + 1,
ColumnLimit, Style.TabWidth, Encoding);
}
@@ -282,11 +290,14 @@
// 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);
-
+// FullWidth <= ColumnLimit
+ //?
+ Split(TrimmedText.size(), Text.size() - TrimmedText.size())
+// : getCommentSplit(Text, ReflowStartColumn, ColumnLimit,
+// Style.TabWidth, Encoding)
+ ;
+
+ return ReflowSplit;
// 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
@@ -503,8 +514,9 @@
unsigned BreakableBlockComment::getLineLengthAfterSplit(
unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- unsigned ContentStartColumn = getContentStartColumn(LineIndex, TailOffset);
+ StringRef::size_type Length, bool Start) const {
+ unsigned ContentStartColumn =
+ Start ? getContentStartColumn(LineIndex, TailOffset) : 0;
unsigned LineLength =
ContentStartColumn + encoding::columnWidthWithTabs(
Content[LineIndex].substr(TailOffset, Length),
@@ -555,14 +567,18 @@
llvm::Regex &CommentPragmasRegex) const {
if (!mayReflow(LineIndex, CommentPragmasRegex))
return Split(StringRef::npos, 0);
+
+ return Split(0, 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
@@ -583,26 +599,57 @@
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);
+ // FIXME: pull together with getLineLegnthAfterSplit (same as for
+ // BreakableLineCommentSeciotn.
+ unsigned ContentStartColumn = 0;
+ if (SplitBefore.first == StringRef::npos) {
+ ContentStartColumn = getContentStartColumn(LineIndex, TailOffset);
} 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;
+ // One space at the start.
+ ContentStartColumn = 1;
+ }
+ llvm::errs() << "Start: " << ContentStartColumn << "\n";
+ StringRef Text = Content[LineIndex].substr(TailOffset, StringRef::npos);
+ if (SplitBefore.first != StringRef::npos) {
+ // If we reflow, we remove the space at the start of the text.
+ Text = Text.ltrim(Blanks);
+ }
+ unsigned LineLength =
+ ContentStartColumn +
+ encoding::columnWidthWithTabs(
+ Text,
+ ContentStartColumn, Style.TabWidth, Encoding);
+ llvm::errs() << "LL: " << LineLength << "\n";
+ // 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, StringRef::npos).empty()) {
+ LineLength -= Decoration.size();
}
- return getLineLengthAfterSplit(LineIndex, TailOffset, StringRef::npos);
}
+ return LineLength;
+// 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.
+// } 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);
+// }
}
bool BreakableBlockComment::introducesBreakBeforeToken() const {
@@ -647,10 +694,10 @@
// 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);
+// unsigned ReflownColumn =
+// getReflownColumn(TrimmedContent, LineIndex, PreviousEndColumn);
+// if (ReflownColumn > ColumnLimit)
+// insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
return;
}
@@ -815,10 +862,13 @@
unsigned BreakableLineCommentSection::getLineLengthAfterSplit(
unsigned LineIndex, unsigned TailOffset,
- StringRef::size_type Length) const {
- unsigned ContentStartColumn =
- (TailOffset == 0 ? ContentColumn[LineIndex]
- : OriginalContentColumn[LineIndex]);
+ StringRef::size_type Length, bool Start) const {
+ unsigned ContentStartColumn = 0;
+ if (Start)
+ ContentStartColumn = (TailOffset == 0 ? ContentColumn[LineIndex]
+ : OriginalContentColumn[LineIndex]);
+ llvm::errs() << "Start: " << ContentStartColumn << ", Text: \""
+ << Content[LineIndex].substr(TailOffset, Length) << "\n";
return ContentStartColumn + encoding::columnWidthWithTabs(
Content[LineIndex].substr(TailOffset, Length),
ContentStartColumn, Style.TabWidth, Encoding);
@@ -850,24 +900,47 @@
llvm::Regex &CommentPragmasRegex) const {
if (!mayReflow(LineIndex, CommentPragmasRegex))
return Split(StringRef::npos, 0);
- return getReflowSplit(Content[LineIndex], ReflowPrefix, PreviousEndColumn,
- ColumnLimit);
+
+ // 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, 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);
+ // FIXME: Pull together with getLineLengthAfterSplit, as it's really the same
+ // thing.
+ unsigned ContentStartColumn = 0;
+ if (SplitBefore.first == StringRef::npos) {
+ ContentStartColumn = (TailOffset == 0 ? ContentColumn[LineIndex]
+ : OriginalContentColumn[LineIndex]);
} else {
- // The whole line gets reflown.
- unsigned StartColumn = PreviousEndColumn + ReflowPrefix.size();
- return StartColumn +
- encoding::columnWidthWithTabs(Content[LineIndex], StartColumn,
- Style.TabWidth, Encoding);
+ // One space at the start.
+ ContentStartColumn = 1;
}
+ return ContentStartColumn +
+ encoding::columnWidthWithTabs(
+ Content[LineIndex].substr(TailOffset, StringRef::npos),
+ ContentStartColumn, Style.TabWidth, Encoding);
+
+ /*
+ 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(
@@ -880,7 +953,9 @@
// // line 1 \
// // line 2
if (LineIndex > 0 && Tokens[LineIndex] != Tokens[LineIndex - 1]) {
+ llvm::errs() << "h1\n";
if (SplitBefore.first != StringRef::npos) {
+ llvm::errs() << "h2\n";
// Reflow happens between tokens. Replace the whitespace between the
// tokens by the empty string.
Whitespaces.replaceWhitespace(
@@ -933,10 +1008,11 @@
// 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);
- }
+// if (SplitBefore.first != StringRef::npos &&
+// SplitBefore.first + SplitBefore.second < Content[LineIndex].size()) {
+// llvm::errs() << "HUH!!!\n";
+// insertBreak(LineIndex, 0, SplitBefore, Whitespaces);
+// }
}
void BreakableLineCommentSection::updateNextToken(LineState &State) const {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits