Typz updated this revision to Diff 115051.
Typz added a comment.
Reorder the functions to minimize diff.
https://reviews.llvm.org/D33589
Files:
lib/Format/ContinuationIndenter.cpp
lib/Format/ContinuationIndenter.h
lib/Format/UnwrappedLineFormatter.cpp
unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -9809,6 +9809,60 @@
EXPECT_EQ("#pragma option -C -A", format("#pragma option -C -A"));
}
+TEST_F(FormatTest, OptimizeBreakPenaltyVsExcess) {
+ FormatStyle Style = getLLVMStyle();
+ Style.ColumnLimit = 20;
+
+ verifyFormat("int a; // the\n"
+ " // comment", Style);
+ EXPECT_EQ("int a; /* first line\n"
+ " * second\n"
+ " * line third\n"
+ " * line\n"
+ " */",
+ format("int a; /* first line\n"
+ " * second\n"
+ " * line third\n"
+ " * line\n"
+ " */", Style));
+ EXPECT_EQ("int a; // first line\n"
+ " // second\n"
+ " // line third\n"
+ " // line",
+ format("int a; // first line\n"
+ " // second line\n"
+ " // third line",
+ Style));
+
+ Style.PenaltyExcessCharacter = 90;
+ verifyFormat("int a; // the comment", Style);
+ EXPECT_EQ("int a; // the\n"
+ " // comment aa",
+ format("int a; // the comment aa", Style));
+ EXPECT_EQ("int a; /* first line\n"
+ " * second line\n"
+ " * third line\n"
+ " */",
+ format("int a; /* first line\n"
+ " * second line\n"
+ " * 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));
+ EXPECT_EQ("int a; /* first line\n"
+ " * second\n"
+ " * line third\n"
+ " * line\n"
+ " */",
+ format("int a; /* first line second line third line"
+ "\n*/", Style));
+}
+
#define EXPECT_ALL_STYLES_EQUAL(Styles) \
for (size_t i = 1; i < Styles.size(); ++i) \
EXPECT_EQ(Styles[0], Styles[i]) << "Style #" << i << " of " << Styles.size() \
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -951,6 +951,7 @@
for (std::deque<StateNode *>::iterator I = Path.begin(), E = Path.end();
I != E; ++I) {
unsigned Penalty = 0;
+ State.Reflow = (*I)->State.Reflow;
formatChildren(State, (*I)->NewLine, /*DryRun=*/false, Penalty);
Penalty += Indenter->addTokenToState(State, (*I)->NewLine, false);
Index: lib/Format/ContinuationIndenter.h
===================================================================
--- lib/Format/ContinuationIndenter.h
+++ lib/Format/ContinuationIndenter.h
@@ -27,6 +27,7 @@
namespace format {
class AnnotatedLine;
+class BreakableToken;
struct FormatToken;
struct LineState;
struct ParenState;
@@ -100,6 +101,16 @@
unsigned breakProtrudingToken(const FormatToken &Current, LineState &State,
bool DryRun);
+ /// \brief Perform the reflowing of a BreakableToken.
+ /// If State.Reflow=true, then the function will reflow the token as needed.
+ /// Otherwise, it simply computes the penalty caused by this tokens characters.
+ ///
+ /// \returns The penalty of reflowing the token if State.Reflow=true; otherwise
+ /// the penalty of characters going beyond the column limit.
+ unsigned reflowProtrudingToken(const FormatToken & Current, LineState & State,
+ std::unique_ptr<clang::format::BreakableToken> & Token,
+ unsigned ColumnLimit, bool DryRun);
+
/// \brief Appends the next token to \p State and updates information
/// necessary for indentation.
///
@@ -350,6 +361,11 @@
/// \brief The indent of the first token.
unsigned FirstIndent;
+ /// \brief Indicates if comments are reflown.
+ /// This value is set when breakProtrudingToken() is called with DryRun=true,
+ /// and simply used otherwise.
+ bool Reflow = true;
+
/// \brief The line that is being formatted.
///
/// Does not need to be considered for memoization because it doesn't change.
Index: lib/Format/ContinuationIndenter.cpp
===================================================================
--- lib/Format/ContinuationIndenter.cpp
+++ lib/Format/ContinuationIndenter.cpp
@@ -1313,6 +1313,39 @@
if (Current.UnbreakableTailLength >= ColumnLimit)
return 0;
+ unsigned Penalty = 0;
+ if (!DryRun) {
+ Penalty = reflowProtrudingToken(Current, State, Token, ColumnLimit, DryRun);
+ } else {
+ LineState NoreflowState = State;
+ NoreflowState.Reflow = false;
+ unsigned NoreflowPenalty = reflowProtrudingToken(Current, NoreflowState, Token, ColumnLimit, DryRun);
+
+ if (NoreflowPenalty > 0) {
+ State.Reflow = true;
+ Penalty = reflowProtrudingToken(Current, State, Token, ColumnLimit, DryRun);
+ }
+
+ if (NoreflowPenalty <= Penalty) {
+ State = NoreflowState;
+ Penalty = NoreflowPenalty;
+ }
+ }
+
+ // Do not count the penalty twice, it will be added afterwards
+ if (State.Column > getColumnLimit(State)) {
+ unsigned ExcessCharacters = State.Column - getColumnLimit(State);
+ Penalty -= Style.PenaltyExcessCharacter * ExcessCharacters;
+ }
+
+ return Penalty;
+}
+
+unsigned ContinuationIndenter::reflowProtrudingToken(const FormatToken &Current, LineState &State,
+ std::unique_ptr<BreakableToken> &Token,
+ unsigned ColumnLimit, bool DryRun) {
+ unsigned StartColumn = State.Column - Current.ColumnWidth;
+
unsigned RemainingSpace = ColumnLimit - Current.UnbreakableTailLength;
bool BreakInserted = false;
// We use a conservative reflowing strategy. Reflow starts after a line is
@@ -1337,14 +1370,18 @@
RemainingSpace, SplitBefore, Whitespaces);
RemainingTokenColumns = Token->getLineLengthAfterSplitBefore(
LineIndex, TailOffset, RemainingTokenColumns, ColumnLimit, SplitBefore);
+ if (!State.Reflow) {
+ if (RemainingTokenColumns > RemainingSpace)
+ Penalty += Style.PenaltyExcessCharacter *
+ (RemainingTokenColumns - RemainingSpace);
+ continue;
+ }
while (RemainingTokenColumns > RemainingSpace) {
BreakableToken::Split Split = Token->getSplit(
LineIndex, TailOffset, ColumnLimit, 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 *
+ (RemainingTokenColumns - RemainingSpace);
break;
}
assert(Split.first != 0);
@@ -1400,6 +1437,8 @@
State.Column = RemainingTokenColumns;
if (BreakInserted) {
+ assert(State.Reflow);
+
// If we break the token inside a parameter list, we need to break before
// the next parameter on all levels, so that the next parameter is clearly
// visible. Line comments already introduce a break.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits