for (SmallVectorImpl<AnnotatedLine *>::reverse_iterator I = Lines.rbegin(),
E = Lines.rend();
I != E; ++I) {
- bool CommentLine = (*I)->First;
+ bool CommentLine = true;
for (const FormatToken *Tok = (*I)->First; Tok; Tok = Tok->Next) {
if (!Tok->is(tok::comment)) {
CommentLine = false;
break;
}
}
- if (NextNonCommentLine && CommentLine)
- (*I)->Level = NextNonCommentLine->Level;
- else
+
+ if (NextNonCommentLine && CommentLine) {
+ // If the comment is currently aligned with the line immediately following
+ // it, that's probably intentional and we should keep it.
+ bool AlignedWithNextLine =
+ NextNonCommentLine->First->NewlinesBefore <= 1 &&
+ NextNonCommentLine->First->OriginalColumn ==
+ (*I)->First->OriginalColumn;
+ if (AlignedWithNextLine)
+ (*I)->Level = NextNonCommentLine->Level;
+ } else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
+ }
setCommentLineLevels((*I)->Children);
}
format("namespace {}\n /* Test */ #define A"));
}
+TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) {
+ // Keep the current level if the comment was originally not aligned with
+ // the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ // Keep the current level if there is an empty line between the comment and
+ // the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ " /* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+
+ // Align with the preprocessor directive if the comment was originally aligned
+ // with the preprocessor directive.
+ EXPECT_EQ("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}",
+ format("void f() {\n"
+ " int i;\n"
+ "/* comment */\n"
+ "#ifdef A\n"
+ " int j;\n"
+ "}"));
+}
+
TEST_F(FormatTestComments, SplitsLongLinesInComments) {
EXPECT_EQ("/* This is a long\n"
" * comment that\n"