r180253 - Add option to align escaped newlines left.
Daniel Jasper
djasper at google.com
Thu Apr 25 01:56:27 PDT 2013
Author: djasper
Date: Thu Apr 25 03:56:26 2013
New Revision: 180253
URL: http://llvm.org/viewvc/llvm-project?rev=180253&view=rev
Log:
Add option to align escaped newlines left.
This enables formattings like:
#define A \
int aaaa; \
int b; \
int ccc; \
int dddddddddd;
Enabling this for Google/Chromium styles only as I don't know whether it
is desired for Clang/LLVM.
Modified:
cfe/trunk/include/clang/Format/Format.h
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/WhitespaceManager.cpp
cfe/trunk/lib/Format/WhitespaceManager.h
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/include/clang/Format/Format.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Format/Format.h?rev=180253&r1=180252&r2=180253&view=diff
==============================================================================
--- cfe/trunk/include/clang/Format/Format.h (original)
+++ cfe/trunk/include/clang/Format/Format.h Thu Apr 25 03:56:26 2013
@@ -91,6 +91,10 @@ struct FormatStyle {
/// \brief Add a space in front of an Objective-C protocol list, i.e. use
/// Foo <Protocol> instead of Foo<Protocol>.
bool ObjCSpaceBeforeProtocolList;
+
+ /// \brief If \c true, aligns escaped newlines as far left as possible.
+ /// Otherwise puts them into the right-most column.
+ bool AlignEscapedNewlinesLeft;
};
/// \brief Returns a format style complying with the LLVM coding standards:
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=180253&r1=180252&r2=180253&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Thu Apr 25 03:56:26 2013
@@ -51,6 +51,7 @@ FormatStyle getLLVMStyle() {
LLVMStyle.ObjCSpaceBeforeProtocolList = true;
LLVMStyle.PenaltyExcessCharacter = 1000000;
LLVMStyle.PenaltyReturnTypeOnItsOwnLine = 75;
+ LLVMStyle.AlignEscapedNewlinesLeft = false;
return LLVMStyle;
}
@@ -71,6 +72,7 @@ FormatStyle getGoogleStyle() {
GoogleStyle.ObjCSpaceBeforeProtocolList = false;
GoogleStyle.PenaltyExcessCharacter = 1000000;
GoogleStyle.PenaltyReturnTypeOnItsOwnLine = 200;
+ GoogleStyle.AlignEscapedNewlinesLeft = true;
return GoogleStyle;
}
Modified: cfe/trunk/lib/Format/WhitespaceManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.cpp?rev=180253&r1=180252&r2=180253&view=diff
==============================================================================
--- cfe/trunk/lib/Format/WhitespaceManager.cpp (original)
+++ cfe/trunk/lib/Format/WhitespaceManager.cpp Thu Apr 25 03:56:26 2013
@@ -21,6 +21,9 @@ namespace format {
void WhitespaceManager::replaceWhitespace(const AnnotatedToken &Tok,
unsigned NewLines, unsigned Spaces,
unsigned WhitespaceStartColumn) {
+ if (NewLines > 0)
+ alignEscapedNewlines();
+
// 2+ newlines mean an empty line separating logic scopes.
if (NewLines >= 2)
alignComments();
@@ -39,16 +42,14 @@ void WhitespaceManager::replaceWhitespac
Spaces + WhitespaceStartColumn + Tok.FormatTok.TokenLength >
Style.ColumnLimit;
// Align comment with other comments.
- if ((Tok.Parent != NULL || !Comments.empty()) && !LineExceedsColumnLimit) {
- StoredComment Comment;
- Comment.Tok = Tok.FormatTok;
- Comment.Spaces = Spaces;
- Comment.NewLines = NewLines;
- Comment.MinColumn =
+ if ((Tok.Parent != NULL || !Comments.empty()) &&
+ !LineExceedsColumnLimit) {
+ unsigned MinColumn =
NewLines > 0 ? Spaces : WhitespaceStartColumn + Spaces;
- Comment.MaxColumn = Style.ColumnLimit - Tok.FormatTok.TokenLength;
- Comment.Untouchable = false;
- Comments.push_back(Comment);
+ unsigned MaxColumn = Style.ColumnLimit - Tok.FormatTok.TokenLength;
+ Comments.push_back(StoredToken(
+ Tok.FormatTok.WhiteSpaceStart, Tok.FormatTok.WhiteSpaceLength,
+ MinColumn, MaxColumn, NewLines, Spaces));
return;
}
}
@@ -57,14 +58,24 @@ void WhitespaceManager::replaceWhitespac
if (Tok.Children.empty() && !Tok.isTrailingComment())
alignComments();
- storeReplacement(Tok.FormatTok, getNewLineText(NewLines, Spaces));
+ storeReplacement(Tok.FormatTok.WhiteSpaceStart,
+ Tok.FormatTok.WhiteSpaceLength,
+ getNewLineText(NewLines, Spaces));
}
void WhitespaceManager::replacePPWhitespace(const AnnotatedToken &Tok,
unsigned NewLines, unsigned Spaces,
unsigned WhitespaceStartColumn) {
- storeReplacement(Tok.FormatTok,
- getNewLineText(NewLines, Spaces, WhitespaceStartColumn));
+ if (NewLines == 0) {
+ replaceWhitespace(Tok, NewLines, Spaces, WhitespaceStartColumn);
+ } else {
+ // The earliest position for "\" is 2 after the last token.
+ unsigned MinColumn = WhitespaceStartColumn + 2;
+ unsigned MaxColumn = Style.ColumnLimit;
+ EscapedNewlines.push_back(StoredToken(
+ Tok.FormatTok.WhiteSpaceStart, Tok.FormatTok.WhiteSpaceLength,
+ MinColumn, MaxColumn, NewLines, Spaces));
+ }
}
void WhitespaceManager::breakToken(const FormatToken &Tok, unsigned Offset,
@@ -72,20 +83,28 @@ void WhitespaceManager::breakToken(const
StringRef Postfix, bool InPPDirective,
unsigned Spaces,
unsigned WhitespaceStartColumn) {
- std::string NewLineText;
- if (!InPPDirective)
- NewLineText = getNewLineText(1, Spaces);
- else
- NewLineText = getNewLineText(1, Spaces, WhitespaceStartColumn);
- std::string ReplacementText = (Prefix + NewLineText + Postfix).str();
SourceLocation Location =
Tok.getStartOfNonWhitespace().getLocWithOffset(Offset);
- Replaces.insert(
- tooling::Replacement(SourceMgr, Location, ReplaceChars, ReplacementText));
+ if (InPPDirective) {
+ // The earliest position for "\" is 2 after the last token.
+ unsigned MinColumn = WhitespaceStartColumn + 2;
+ unsigned MaxColumn = Style.ColumnLimit;
+ StoredToken StoredTok = StoredToken(Location, ReplaceChars, MinColumn,
+ MaxColumn, /*NewLines=*/ 1, Spaces);
+ StoredTok.Prefix = Prefix;
+ StoredTok.Postfix = Postfix;
+ EscapedNewlines.push_back(StoredTok);
+ } else {
+ std::string ReplacementText =
+ (Prefix + getNewLineText(1, Spaces) + Postfix).str();
+ Replaces.insert(tooling::Replacement(SourceMgr, Location, ReplaceChars,
+ ReplacementText));
+ }
}
const tooling::Replacements &WhitespaceManager::generateReplacements() {
alignComments();
+ alignEscapedNewlines();
return Replaces;
}
@@ -96,11 +115,9 @@ void WhitespaceManager::addReplacement(c
}
void WhitespaceManager::addUntouchableComment(unsigned Column) {
- StoredComment Comment;
- Comment.MinColumn = Column;
- Comment.MaxColumn = Column;
- Comment.Untouchable = true;
- Comments.push_back(Comment);
+ StoredToken Tok = StoredToken(SourceLocation(), 0, Column, Column, 0, 0);
+ Tok.Untouchable = true;
+ Comments.push_back(Tok);
}
std::string WhitespaceManager::getNewLineText(unsigned NewLines,
@@ -110,13 +127,14 @@ std::string WhitespaceManager::getNewLin
std::string WhitespaceManager::getNewLineText(unsigned NewLines,
unsigned Spaces,
- unsigned WhitespaceStartColumn) {
+ unsigned WhitespaceStartColumn,
+ unsigned EscapedNewlineColumn) {
std::string NewLineText;
if (NewLines > 0) {
unsigned Offset =
- std::min<int>(Style.ColumnLimit - 1, WhitespaceStartColumn);
+ std::min<int>(EscapedNewlineColumn - 1, WhitespaceStartColumn);
for (unsigned i = 0; i < NewLines; ++i) {
- NewLineText += std::string(Style.ColumnLimit - Offset - 1, ' ');
+ NewLineText += std::string(EscapedNewlineColumn - Offset - 1, ' ');
NewLineText += "\\\n";
Offset = 0;
}
@@ -127,8 +145,8 @@ std::string WhitespaceManager::getNewLin
void WhitespaceManager::alignComments() {
unsigned MinColumn = 0;
unsigned MaxColumn = UINT_MAX;
- comment_iterator Start = Comments.begin();
- for (comment_iterator I = Start, E = Comments.end(); I != E; ++I) {
+ token_iterator Start = Comments.begin();
+ for (token_iterator I = Start, E = Comments.end(); I != E; ++I) {
if (I->MinColumn > MaxColumn || I->MaxColumn < MinColumn) {
alignComments(Start, I, MinColumn);
MinColumn = I->MinColumn;
@@ -143,26 +161,50 @@ void WhitespaceManager::alignComments()
Comments.clear();
}
-void WhitespaceManager::alignComments(comment_iterator I, comment_iterator E,
+void WhitespaceManager::alignComments(token_iterator I, token_iterator E,
unsigned Column) {
while (I != E) {
if (!I->Untouchable) {
unsigned Spaces = I->Spaces + Column - I->MinColumn;
- storeReplacement(I->Tok, getNewLineText(I->NewLines, Spaces));
+ storeReplacement(I->ReplacementLoc, I->ReplacementLength,
+ getNewLineText(I->NewLines, Spaces));
}
++I;
}
}
-void WhitespaceManager::storeReplacement(const FormatToken &Tok,
+void WhitespaceManager::alignEscapedNewlines() {
+ unsigned MinColumn;
+ if (Style.AlignEscapedNewlinesLeft) {
+ MinColumn = 0;
+ for (token_iterator I = EscapedNewlines.begin(), E = EscapedNewlines.end();
+ I != E; ++I) {
+ if (I->MinColumn > MinColumn)
+ MinColumn = I->MinColumn;
+ }
+ } else {
+ MinColumn = Style.ColumnLimit;
+ }
+
+ for (token_iterator I = EscapedNewlines.begin(), E = EscapedNewlines.end();
+ I != E; ++I) {
+ // I->MinColumn - 2 is the end of the previous token (i.e. the
+ // WhitespaceStartColumn).
+ storeReplacement(
+ I->ReplacementLoc, I->ReplacementLength,
+ I->Prefix + getNewLineText(I->NewLines, I->Spaces, I->MinColumn - 2,
+ MinColumn) + I->Postfix);
+
+ }
+ EscapedNewlines.clear();
+}
+
+void WhitespaceManager::storeReplacement(SourceLocation Loc, unsigned Length,
const std::string Text) {
// Don't create a replacement, if it does not change anything.
- if (StringRef(SourceMgr.getCharacterData(Tok.WhiteSpaceStart),
- Tok.WhiteSpaceLength) == Text)
+ if (StringRef(SourceMgr.getCharacterData(Loc), Length) == Text)
return;
-
- Replaces.insert(tooling::Replacement(SourceMgr, Tok.WhiteSpaceStart,
- Tok.WhiteSpaceLength, Text));
+ Replaces.insert(tooling::Replacement(SourceMgr, Loc, Length, Text));
}
} // namespace format
Modified: cfe/trunk/lib/Format/WhitespaceManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/WhitespaceManager.h?rev=180253&r1=180252&r2=180253&view=diff
==============================================================================
--- cfe/trunk/lib/Format/WhitespaceManager.h (original)
+++ cfe/trunk/lib/Format/WhitespaceManager.h Thu Apr 25 03:56:26 2013
@@ -1,4 +1,4 @@
-//===--- WhitespaceManager.h - Format C++ code ----------------------------===//
+//===--- WhitespaceManager.h - Format C++ code ------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -68,31 +68,45 @@ public:
/// \brief Try to align all stashed comments.
void alignComments();
+ /// \brief Try to align all stashed escaped newlines.
+ void alignEscapedNewlines();
private:
std::string getNewLineText(unsigned NewLines, unsigned Spaces);
std::string getNewLineText(unsigned NewLines, unsigned Spaces,
- unsigned WhitespaceStartColumn);
+ unsigned WhitespaceStartColumn,
+ unsigned EscapedNewlineColumn);
- /// \brief Structure to store a comment for later layout and alignment.
- struct StoredComment {
- FormatToken Tok;
+ /// \brief Structure to store tokens for later layout and alignment.
+ struct StoredToken {
+ StoredToken(SourceLocation ReplacementLoc, unsigned ReplacementLength,
+ unsigned MinColumn, unsigned MaxColumn, unsigned NewLines,
+ unsigned Spaces)
+ : ReplacementLoc(ReplacementLoc), ReplacementLength(ReplacementLength),
+ MinColumn(MinColumn), MaxColumn(MaxColumn), NewLines(NewLines),
+ Spaces(Spaces), Untouchable(false) {}
+ SourceLocation ReplacementLoc;
+ unsigned ReplacementLength;
unsigned MinColumn;
unsigned MaxColumn;
unsigned NewLines;
unsigned Spaces;
bool Untouchable;
+ std::string Prefix;
+ std::string Postfix;
};
- SmallVector<StoredComment, 16> Comments;
- typedef SmallVector<StoredComment, 16>::iterator comment_iterator;
+ SmallVector<StoredToken, 16> Comments;
+ SmallVector<StoredToken, 16> EscapedNewlines;
+ typedef SmallVector<StoredToken, 16>::iterator token_iterator;
/// \brief Put all the comments between \p I and \p E into \p Column.
- void alignComments(comment_iterator I, comment_iterator E, unsigned Column);
+ void alignComments(token_iterator I, token_iterator E, unsigned Column);
/// \brief Stores \p Text as the replacement for the whitespace in front of
/// \p Tok.
- void storeReplacement(const FormatToken &Tok, const std::string Text);
+ void storeReplacement(SourceLocation Loc, unsigned Length,
+ const std::string Text);
SourceManager &SourceMgr;
tooling::Replacements Replaces;
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=180253&r1=180252&r2=180253&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Thu Apr 25 03:56:26 2013
@@ -2974,16 +2974,16 @@ TEST_F(FormatTest, MergeHandlingInTheFac
format("if (true)\nreturn 42;", AllowsMergedIf));
FormatStyle ShortMergedIf = AllowsMergedIf;
ShortMergedIf.ColumnLimit = 25;
- verifyFormat("#define A \\\n"
+ verifyFormat("#define A \\\n"
" if (true) return 42;",
ShortMergedIf);
- verifyFormat("#define A \\\n"
- " f(); \\\n"
+ verifyFormat("#define A \\\n"
+ " f(); \\\n"
" if (true)\n"
"#define B",
ShortMergedIf);
- verifyFormat("#define A \\\n"
- " f(); \\\n"
+ verifyFormat("#define A \\\n"
+ " f(); \\\n"
" if (true)\n"
"g();",
ShortMergedIf);
@@ -3800,6 +3800,15 @@ TEST_F(FormatTest, BreakStringLiterals)
"\"pathat/\"\n"
"\"slashes\"",
format("\"split/pathat/slashes\"", getLLVMStyleWithColumns(10)));
+
+ FormatStyle AlignLeft = getLLVMStyleWithColumns(12);
+ AlignLeft.AlignEscapedNewlinesLeft = true;
+ EXPECT_EQ(
+ "#define A \\\n"
+ " \"some \" \\\n"
+ " \"text \" \\\n"
+ " \"other\";",
+ format("#define A \"some text other\";", AlignLeft));
}
TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) {
More information about the cfe-commits
mailing list