r186153 - clang-format: Break before/between array subscript expressions.
Daniel Jasper
djasper at google.com
Fri Jul 12 04:19:37 PDT 2013
Author: djasper
Date: Fri Jul 12 06:19:37 2013
New Revision: 186153
URL: http://llvm.org/viewvc/llvm-project?rev=186153&view=rev
Log:
clang-format: Break before/between array subscript expressions.
clang-format used to treat array subscript expressions much like
function call (just replacing () with []). However, this is not really
appropriate especially for expressions with multiple subscripts.
Although it might seem counter-intuitive, the most consistent solution
seems to be to always (if necessary) break before a square bracket,
never after it. Also, multiple subscripts of the same expression should
be aligned if they are on subsequent lines.
Before:
aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa][
bbbbbbbbbbbbbbbbbbbbbbbbb] = c;
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa][
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;
After:
aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa]
[bbbbbbbbbbbbbbbbbbbbbbbbb] = c;
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
[bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;
Modified:
cfe/trunk/lib/Format/Format.cpp
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/Format.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/Format.cpp?rev=186153&r1=186152&r2=186153&view=diff
==============================================================================
--- cfe/trunk/lib/Format/Format.cpp (original)
+++ cfe/trunk/lib/Format/Format.cpp Fri Jul 12 06:19:37 2013
@@ -334,8 +334,8 @@ private:
BreakBeforeClosingBrace(false), QuestionColumn(0),
AvoidBinPacking(AvoidBinPacking), BreakBeforeParameter(false),
NoLineBreak(NoLineBreak), ColonPos(0), StartOfFunctionCall(0),
- NestedNameSpecifierContinuation(0), CallContinuation(0),
- VariablePos(0), ContainsLineBreak(false) {}
+ StartOfArraySubscripts(0), NestedNameSpecifierContinuation(0),
+ CallContinuation(0), VariablePos(0), ContainsLineBreak(false) {}
/// \brief The position to which a specific parenthesis level needs to be
/// indented.
@@ -381,6 +381,10 @@ private:
/// \brief The start of the most recent function in a builder-type call.
unsigned StartOfFunctionCall;
+ /// \brief Contains the start of array subscript expressions, so that they
+ /// can be aligned.
+ unsigned StartOfArraySubscripts;
+
/// \brief If a nested name specifier was broken over multiple lines, this
/// contains the start column of the second line. Otherwise 0.
unsigned NestedNameSpecifierContinuation;
@@ -422,6 +426,8 @@ private:
return ColonPos < Other.ColonPos;
if (StartOfFunctionCall != Other.StartOfFunctionCall)
return StartOfFunctionCall < Other.StartOfFunctionCall;
+ if (StartOfArraySubscripts != Other.StartOfArraySubscripts)
+ return StartOfArraySubscripts < Other.StartOfArraySubscripts;
if (CallContinuation != Other.CallContinuation)
return CallContinuation < Other.CallContinuation;
if (VariablePos != Other.VariablePos)
@@ -571,6 +577,12 @@ private:
State.Column = State.Stack.back().Indent;
State.Stack.back().ColonPos = State.Column + Current.CodePointCount;
}
+ } else if (Current.is(tok::l_square) &&
+ Current.Type != TT_ObjCMethodExpr) {
+ if (State.Stack.back().StartOfArraySubscripts != 0)
+ State.Column = State.Stack.back().StartOfArraySubscripts;
+ else
+ State.Column = ContinuationIndent;
} else if (Current.Type == TT_StartOfName ||
Previous.isOneOf(tok::coloncolon, tok::equal) ||
Previous.Type == TT_ObjCMethodExpr) {
@@ -730,6 +742,9 @@ private:
State.Stack.back().AvoidBinPacking = true;
if (Current.is(tok::lessless) && State.Stack.back().FirstLessLess == 0)
State.Stack.back().FirstLessLess = State.Column;
+ if (Current.is(tok::l_square) &&
+ State.Stack.back().StartOfArraySubscripts == 0)
+ State.Stack.back().StartOfArraySubscripts = State.Column;
if (Current.is(tok::question))
State.Stack.back().QuestionColumn = State.Column;
if (!Current.opensScope() && !Current.closesScope())
@@ -835,6 +850,12 @@ private:
State.Stack.pop_back();
--State.ParenLevel;
}
+ if (Current.is(tok::r_square)) {
+ // If this ends the array subscript expr, reset the corresponding value.
+ const FormatToken *NextNonComment = Current.getNextNonComment();
+ if (NextNonComment && NextNonComment->isNot(tok::l_square))
+ State.Stack.back().StartOfArraySubscripts = 0;
+ }
// Remove scopes created by fake parenthesis.
for (unsigned i = 0, e = Current.FakeRParens; i != e; ++i) {
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=186153&r1=186152&r2=186153&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Jul 12 06:19:37 2013
@@ -1017,6 +1017,8 @@ unsigned TokenAnnotator::splitPenalty(co
return 0;
if (Left.is(tok::comma))
return 1;
+ if (Right.is(tok::l_square))
+ return 150;
if (Right.Type == TT_StartOfName || Right.is(tok::kw_operator)) {
if (Line.First->is(tok::kw_for) && Right.PartOfMultiVariableDeclStmt)
@@ -1296,7 +1298,7 @@ bool TokenAnnotator::canBreakBefore(cons
(Left.is(tok::r_paren) &&
Right.isOneOf(tok::identifier, tok::kw_const, tok::kw___attribute)) ||
(Left.is(tok::l_paren) && !Right.is(tok::r_paren)) ||
- (Left.is(tok::l_square) && !Right.is(tok::r_square));
+ Right.is(tok::l_square);
}
void TokenAnnotator::printDebugInfo(const AnnotatedLine &Line) {
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=186153&r1=186152&r2=186153&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Jul 12 06:19:37 2013
@@ -2121,10 +2121,10 @@ TEST_F(FormatTest, PreventConfusingInden
" aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n"
" aaaaaaaaaaaaaaaaaaaaaaaa);");
verifyFormat(
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[\n"
- " aaaaaaaaaaaaaaaaaaaaaaaa[\n"
- " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa],\n"
- " aaaaaaaaaaaaaaaaaaaaaaaa];");
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [aaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n"
+ " [aaaaaaaaaaaaaaaaaaaaaaaa]];");
verifyFormat(
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n"
" aaaaaaaaaaaaaaaaaaaaaaaa<\n"
@@ -3593,11 +3593,11 @@ TEST_F(FormatTest, FormatsCasts) {
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa *foo = (aaaaaaaaaaaaaaaaa *)\n"
" bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;");
+ // FIXME: The indentation here is not ideal.
verifyFormat(
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[\n"
- " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] =\n"
- " (*cccccccccccccccc)[\n"
- " dddddddddddddddddddddddddddddddddddddddddddddddddddddddd];");
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = (*cccccccccccccccc)\n"
+ " [dddddddddddddddddddddddddddddddddddddddddddddddddddddddd];");
}
TEST_F(FormatTest, FormatsFunctionTypes) {
@@ -3677,6 +3677,22 @@ TEST_F(FormatTest, BreaksLongDeclaration
" int aaaaaaaaaaaaaaaaaaaaaaa);");
}
+TEST_F(FormatTest, FormatsArrays) {
+ verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"
+ " [bbbbbbbbbbbbbbbbbbbbbbbbb] = c;");
+ verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;");
+ verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [a][bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = cccccccc;");
+ verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+ " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]\n"
+ " [bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb] = ccccccccccc;");
+ verifyFormat(
+ "llvm::outs() << \"aaaaaaaaaaaa: \"\n"
+ " << (*aaaaaaaiaaaaaaa)[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"
+ " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+}
+
TEST_F(FormatTest, LineStartsWithSpecialCharacter) {
verifyFormat("(a)->b();");
verifyFormat("--a;");
More information about the cfe-commits
mailing list