clang-format: merge short case labels with trailing comments

Summary:
Allow merging short case labels when they actually end with a comment
(like a comment after the ``break``) and when followed by switch-level
comments (e.g. aligned with next case):

  switch(a) {
  case 0: break; // comment at end of case
  case 1: return value;
  // comment related to next case
  // comment related to next case
  case 2:
  }

Reviewers: krasimir, djasper

Reviewed By: krasimir

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D35557

llvm-svn: 309370
This commit is contained in:
Francois Ferrand 2017-07-28 07:56:18 +00:00
parent a98a95cca7
commit a64ba70183
2 changed files with 92 additions and 2 deletions

View File

@ -382,7 +382,9 @@ private:
return 0;
unsigned NumStmts = 0;
unsigned Length = 0;
bool EndsWithComment = false;
bool InPPDirective = I[0]->InPPDirective;
const unsigned Level = I[0]->Level;
for (; NumStmts < 3; ++NumStmts) {
if (I + 1 + NumStmts == E)
break;
@ -392,9 +394,26 @@ private:
if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
break;
if (Line->First->isOneOf(tok::kw_if, tok::kw_for, tok::kw_switch,
tok::kw_while, tok::comment) ||
Line->Last->is(tok::comment))
tok::kw_while) ||
EndsWithComment)
return 0;
if (Line->First->is(tok::comment)) {
if (Level != Line->Level)
return 0;
SmallVectorImpl<AnnotatedLine *>::const_iterator J = I + 2 + NumStmts;
for (; J != E; ++J) {
Line = *J;
if (Line->InPPDirective != InPPDirective)
break;
if (Line->First->isOneOf(tok::kw_case, tok::kw_default, tok::r_brace))
break;
if (Line->First->isNot(tok::comment) || Level != Line->Level)
return 0;
}
break;
}
if (Line->Last->is(tok::comment))
EndsWithComment = true;
Length += I[1 + NumStmts]->Last->TotalLength + 1; // 1 for the space.
}
if (NumStmts == 0 || NumStmts == 3 || Length > Limit)

View File

@ -906,6 +906,77 @@ TEST_F(FormatTest, ShortCaseLabels) {
"default: y = 1; break;\n"
"}",
Style);
verifyFormat("switch (a) {\n"
"case 0: return; // comment\n"
"case 1: break; // comment\n"
"case 2: return;\n"
"// comment\n"
"case 3: return;\n"
"// comment 1\n"
"// comment 2\n"
"// comment 3\n"
"case 4: break; /* comment */\n"
"case 5:\n"
" // comment\n"
" break;\n"
"case 6: /* comment */ x = 1; break;\n"
"case 7: x = /* comment */ 1; break;\n"
"case 8:\n"
" x = 1; /* comment */\n"
" break;\n"
"case 9:\n"
" break; // comment line 1\n"
" // comment line 2\n"
"}",
Style);
EXPECT_EQ("switch (a) {\n"
"case 1:\n"
" x = 8;\n"
" // fall through\n"
"case 2: x = 8;\n"
"// comment\n"
"case 3:\n"
" return; /* comment line 1\n"
" * comment line 2 */\n"
"case 4: i = 8;\n"
"// something else\n"
"#if FOO\n"
"case 5: break;\n"
"#endif\n"
"}",
format("switch (a) {\n"
"case 1: x = 8;\n"
" // fall through\n"
"case 2:\n"
" x = 8;\n"
"// comment\n"
"case 3:\n"
" return; /* comment line 1\n"
" * comment line 2 */\n"
"case 4:\n"
" i = 8;\n"
"// something else\n"
"#if FOO\n"
"case 5: break;\n"
"#endif\n"
"}",
Style));
EXPECT_EQ("switch (a) {\n" "case 0:\n"
" return; // long long long long long long long long long long long long comment\n"
" // line\n" "}",
format("switch (a) {\n"
"case 0: return; // long long long long long long long long long long long long comment line\n"
"}",
Style));
EXPECT_EQ("switch (a) {\n"
"case 0:\n"
" return; /* long long long long long long long long long long long long comment\n"
" line */\n"
"}",
format("switch (a) {\n"
"case 0: return; /* long long long long long long long long long long long long comment line */\n"
"}",
Style));
verifyFormat("switch (a) {\n"
"#if FOO\n"
"case 0: return 0;\n"