Skip to content
Snippets Groups Projects
Commit 3b5943f5 authored by Daniel Jasper's avatar Daniel Jasper
Browse files

"<<" alignment for clang-format.

Also, small fix for handling the first token correctly.

Review: http://llvm-reviews.chandlerc.com/D177

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169488 91177308-0d34-0410-b5e6-96231b3b80d8
parent b929f663
No related branches found
No related tags found
No related merge requests found
......@@ -92,16 +92,21 @@ public:
}
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.FirstLessLess.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 @@ private:
/// 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> FirstLessLess;
bool CtorInitializerOnNewLine;
bool InCtorInitializer;
......@@ -149,6 +165,12 @@ private:
if (Other.LastSpace[i] != LastSpace[i])
return Other.LastSpace[i] > LastSpace[i];
}
if (Other.FirstLessLess.size() != FirstLessLess.size())
return Other.FirstLessLess.size() > FirstLessLess.size();
for (int i = 0, e = FirstLessLess.size(); i != e; ++i) {
if (Other.FirstLessLess[i] != FirstLessLess[i])
return Other.FirstLessLess[i] > FirstLessLess[i];
}
return false;
}
};
......@@ -171,6 +193,9 @@ private:
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.FirstLessLess[ParenLevel] != 0)
State.Column = State.FirstLessLess[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 @@ private:
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 @@ private:
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,6 +241,12 @@ private:
void moveStateToNextToken(IndentState &State) {
unsigned Index = State.ConsumedTokens;
const FormatToken &Current = Line.Tokens[Index];
unsigned ParenLevel = State.Indent.size() - 1;
if (Current.Tok.is(tok::lessless) && State.FirstLessLess[ParenLevel] == 0)
State.FirstLessLess[ParenLevel] = State.Column;
State.Column += Current.Tok.getLength();
// If we encounter an opening (, [ or <, we add a level to our stacks to
// prepare for the following tokens.
......@@ -224,6 +254,7 @@ private:
Annotations[Index].Type == TokenAnnotation::TT_TemplateOpener) {
State.Indent.push_back(4 + State.LastSpace.back());
State.LastSpace.push_back(State.LastSpace.back());
State.FirstLessLess.push_back(0);
}
// If we encounter a closing ), ] or >, we can remove a level from our
......@@ -232,6 +263,7 @@ private:
Annotations[Index].Type == TokenAnnotation::TT_TemplateCloser) {
State.Indent.pop_back();
State.LastSpace.pop_back();
State.FirstLessLess.pop_back();
}
++State.ConsumedTokens;
......@@ -687,6 +719,8 @@ private:
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) ||
......
......@@ -386,6 +386,11 @@ TEST_F(FormatTest, UnderstandsUsesOfStar) {
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, IncorrectCodeErrorDetection) {
}
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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment