[cfe-commits] [PATCH] "<<" alignment for clang-format
Daniel Jasper
djasper at google.com
Thu Dec 6 01:38:20 PST 2012
Added a small fix for the initialization of the state with the first token.
Hi klimek,
http://llvm-reviews.chandlerc.com/D177
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D177?vs=437&id=447#toc
Files:
lib/Format/Format.cpp
unittests/Format/FormatTest.cpp
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -92,16 +92,21 @@
}
void format() {
+ // Format first token and initialize indent.
unsigned Indent = formatFirstToken();
+
+ // Initialize state dependent on indent.
IndentState State;
- State.Column = Indent + Line.Tokens[0].Tok.getLength();
+ State.Column = Indent;
State.CtorInitializerOnNewLine = false;
State.InCtorInitializer = false;
- State.ConsumedTokens = 1;
-
- //State.UsedIndent.push_back(Line.Level * 2);
+ State.ConsumedTokens = 0;
State.Indent.push_back(Indent + 4);
State.LastSpace.push_back(Indent);
+ State.LessLessPos.push_back(0);
+
+ // The first token has already been indented and thus consumed.
+ moveStateToNextToken(State);
// Start iterating at 1 as we have correctly formatted of Token #0 above.
for (unsigned i = 1, n = Line.Tokens.size(); i != n; ++i) {
@@ -126,8 +131,19 @@
/// indented.
std::vector<unsigned> Indent;
+ /// \brief The position of the last space on each level.
+ ///
+ /// Used e.g. to break like:
+ /// functionCall(Parameter, otherCall(
+ /// OtherParameter));
std::vector<unsigned> LastSpace;
+ /// \brief The position the first "<<" operator encountered on each level.
+ ///
+ /// Used to align "<<" operators. 0 if no such operator has been encountered
+ /// on a level.
+ std::vector<unsigned> LessLessPos;
+
bool CtorInitializerOnNewLine;
bool InCtorInitializer;
@@ -149,6 +165,12 @@
if (Other.LastSpace[i] != LastSpace[i])
return Other.LastSpace[i] > LastSpace[i];
}
+ if (Other.LessLessPos.size() != LessLessPos.size())
+ return Other.LessLessPos.size() > LessLessPos.size();
+ for (int i = 0, e = LessLessPos.size(); i != e; ++i) {
+ if (Other.LessLessPos[i] != LessLessPos[i])
+ return Other.LessLessPos[i] > LessLessPos[i];
+ }
return false;
}
};
@@ -171,6 +193,9 @@
if (Current.Tok.is(tok::string_literal) &&
Previous.Tok.is(tok::string_literal))
State.Column = State.Column - Previous.Tok.getLength();
+ else if (Current.Tok.is(tok::lessless) &&
+ State.LessLessPos[ParenLevel] != 0)
+ State.Column = State.LessLessPos[ParenLevel];
else if (Previous.Tok.is(tok::equal) && ParenLevel != 0)
// Indent and extra 4 spaces after '=' as it continues an expression.
// Don't do that on the top level, as we already indent 4 there.
@@ -181,7 +206,6 @@
if (!DryRun)
replaceWhitespace(Current, 1, State.Column);
- State.Column += Current.Tok.getLength();
State.LastSpace[ParenLevel] = State.Indent[ParenLevel];
if (Current.Tok.is(tok::colon) &&
Annotations[Index].Type != TokenAnnotation::TT_ConditionalExpr) {
@@ -205,9 +229,9 @@
State.InCtorInitializer = true;
}
// Top-level spaces are exempt as that mostly leads to better results.
+ State.Column += Spaces;
if (Spaces > 0 && ParenLevel != 0)
- State.LastSpace[ParenLevel] = State.Column + Spaces;
- State.Column += Current.Tok.getLength() + Spaces;
+ State.LastSpace[ParenLevel] = State.Column;
}
moveStateToNextToken(State);
}
@@ -217,21 +241,29 @@
void moveStateToNextToken(IndentState &State) {
unsigned Index = State.ConsumedTokens;
const FormatToken &Current = Line.Tokens[Index];
+ unsigned ParenLevel = State.Indent.size() - 1;
+
+ State.Column += Current.Tok.getLength();
+
+ if (Current.Tok.is(tok::lessless) && State.LessLessPos[ParenLevel] == 0)
+ State.LessLessPos[ParenLevel] = State.Column - 2;
// If we encounter an opening (, [ or <, we add a level to our stacks to
// prepare for the following tokens.
if (Current.Tok.is(tok::l_paren) || Current.Tok.is(tok::l_square) ||
Annotations[Index].Type == TokenAnnotation::TT_TemplateOpener) {
State.Indent.push_back(4 + State.LastSpace.back());
State.LastSpace.push_back(State.LastSpace.back());
+ State.LessLessPos.push_back(0);
}
// If we encounter a closing ), ] or >, we can remove a level from our
// stacks.
if (Current.Tok.is(tok::r_paren) || Current.Tok.is(tok::r_square) ||
Annotations[Index].Type == TokenAnnotation::TT_TemplateCloser) {
State.Indent.pop_back();
State.LastSpace.pop_back();
+ State.LessLessPos.pop_back();
}
++State.ConsumedTokens;
@@ -687,6 +719,8 @@
return false;
if (isBinaryOperator(Left))
return true;
+ if (Right.Tok.is(tok::lessless))
+ return true;
return Right.Tok.is(tok::colon) || Left.Tok.is(tok::comma) ||
Left.Tok.is(tok::semi) || Left.Tok.is(tok::equal) ||
Left.Tok.is(tok::ampamp) || Left.Tok.is(tok::pipepipe) ||
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -386,6 +386,11 @@
verifyFormat("int a = b * *c;");
}
+TEST_F(FormatTest, LineStartsWithSpecialCharacter) {
+ verifyFormat("(a)->b();");
+ verifyFormat("--a;");
+}
+
TEST_F(FormatTest, HandlesIncludeDirectives) {
EXPECT_EQ("#include <string>\n", format("#include <string>\n"));
EXPECT_EQ("#include \"a/b/string\"\n", format("#include \"a/b/string\"\n"));
@@ -434,5 +439,26 @@
}
+TEST_F(FormatTest, AlignsPipes) {
+ verifyFormat(
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+ verifyFormat(
+ "aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaa\n"
+ " << aaaaaaaaaaaaaaaaaaaa;");
+ verifyFormat(
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+ verifyFormat(
+ "llvm::outs() << \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"\n"
+ " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\"\n"
+ " << \"ccccccccccccccccccccccccccccccccccccccccccccccccc\";");
+ verifyFormat(
+ "aaaaaaaa << (aaaaaaaaaaaaaaaaaaa << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n"
+ " << aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");
+}
+
} // end namespace tooling
} // end namespace clang
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D177.2.patch
Type: text/x-patch
Size: 6743 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121206/3b139798/attachment.bin>
More information about the cfe-commits
mailing list