mzeren-vmw updated this revision to Diff 130487.
mzeren-vmw added a comment.
Documented CommentAlignment enumerators. Documenting them suggested better
enumerator names.
Added tests for multi-line comments, block comments and trailing comments.
Repository:
rC Clang
https://reviews.llvm.org/D42036
Files:
lib/Format/TokenAnnotator.cpp
lib/Format/TokenAnnotator.h
lib/Format/UnwrappedLineFormatter.cpp
unittests/Format/FormatTest.cpp
Index: unittests/Format/FormatTest.cpp
===================================================================
--- unittests/Format/FormatTest.cpp
+++ unittests/Format/FormatTest.cpp
@@ -2497,7 +2497,6 @@
"code();\n"
"#endif",
Style);
-
// Include guards must cover the entire file.
verifyFormat("code();\n"
"code();\n"
@@ -2593,21 +2592,97 @@
"code();\n"
"#endif",
Style));
- // FIXME: The comment indent corrector in TokenAnnotator gets thrown off by
- // preprocessor indentation.
- EXPECT_EQ("#if 1\n"
- " // comment\n"
- "# define A 0\n"
- "// comment\n"
- "# define B 0\n"
- "#endif",
- format("#if 1\n"
- "// comment\n"
- "# define A 0\n"
- " // comment\n"
- "# define B 0\n"
- "#endif",
- Style));
+ // Comments aligned to macros stay aligned. This test is incompatible with
+ // verifyFormat() because messUp() removes the alignment.
+ {
+ const char *Expected = ""
+ "// Level 0 unaligned comment\n"
+ "// Level 0 unaligned continuation\n"
+ "#ifndef HEADER_H\n"
+ "// Level 0 aligned comment\n"
+ "// Level 0 aligned continuation\n"
+ "#define HEADER_H\n"
+ "#if 1\n"
+ " // aligned comment\n"
+ " // aligned continuation\n"
+ "# define A 0\n"
+ "// un-aligned comment\n"
+ "// un-aligned continuation\n"
+ "# define B 0\n"
+ "// Trailing aligned comment\n"
+ "#endif\n"
+ "#endif";
+ const char *ToFormat = ""
+ " // Level 0 unaligned comment\n"
+ " // Level 0 unaligned continuation\n"
+ "#ifndef HEADER_H\n"
+ "// Level 0 aligned comment\n"
+ "// Level 0 aligned continuation\n"
+ "#define HEADER_H\n"
+ "#if 1\n"
+ " // aligned comment\n"
+ " // aligned continuation\n"
+ "# define A 0\n"
+ " // un-aligned comment\n"
+ " // un-aligned continuation\n"
+ "# define B 0\n"
+ " // Trailing aligned comment\n"
+ "#endif\n"
+ "#endif";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
+ // Same as above, but block comments.
+ {
+ const char *Expected = ""
+ "/*\n"
+ " * Level 0 unaligned block comment\n"
+ " */\n"
+ "#ifndef HEADER_H\n"
+ "/*\n"
+ " * Level 0 aligned comment\n"
+ " */\n"
+ "#define HEADER_H\n"
+ "#if 1\n"
+ " /*\n"
+ " * Aligned comment\n"
+ " */\n"
+ "# define A 0\n"
+ "/*\n"
+ " * Unaligned comment\n"
+ " */\n"
+ "# define B 0\n"
+ "/*\n"
+ " * Trailing aligned comment\n"
+ " */\n"
+ "#endif\n"
+ "#endif";
+ const char *ToFormat = ""
+ " /*\n"
+ " * Level 0 unaligned block comment\n"
+ " */\n"
+ "#ifndef HEADER_H\n"
+ "/*\n"
+ " * Level 0 aligned comment\n"
+ " */\n"
+ "#define HEADER_H\n"
+ "#if 1\n"
+ " /*\n"
+ " * Aligned comment\n"
+ " */\n"
+ "# define A 0\n"
+ " /*\n"
+ " * Unaligned comment\n"
+ " */\n"
+ "# define B 0\n"
+ " /*\n"
+ " * Trailing aligned comment\n"
+ " */\n"
+ "#endif\n"
+ "#endif";
+ EXPECT_EQ(Expected, format(ToFormat, Style));
+ EXPECT_EQ(Expected, format(Expected, Style));
+ }
// Test with tabs.
Style.UseTab = FormatStyle::UT_Always;
Style.IndentWidth = 8;
Index: lib/Format/UnwrappedLineFormatter.cpp
===================================================================
--- lib/Format/UnwrappedLineFormatter.cpp
+++ lib/Format/UnwrappedLineFormatter.cpp
@@ -52,6 +52,7 @@
/// next.
void nextLine(const AnnotatedLine &Line) {
Offset = getIndentOffset(*Line.First);
+ Offset += Line.LevelOffset;
// Update the indent level cache size so that we can rely on it
// having the right size in adjustToUnmodifiedline.
while (IndentForLevel.size() <= Line.Level)
Index: lib/Format/TokenAnnotator.h
===================================================================
--- lib/Format/TokenAnnotator.h
+++ lib/Format/TokenAnnotator.h
@@ -38,7 +38,7 @@
class AnnotatedLine {
public:
AnnotatedLine(const UnwrappedLine &Line)
- : First(Line.Tokens.front().Tok), Level(Line.Level),
+ : First(Line.Tokens.front().Tok), Level(Line.Level), LevelOffset(0),
MatchingOpeningBlockLineIndex(Line.MatchingOpeningBlockLineIndex),
InPPDirective(Line.InPPDirective),
MustBeDeclaration(Line.MustBeDeclaration), MightBeFunctionDecl(false),
@@ -111,6 +111,12 @@
LineType Type;
unsigned Level;
+
+ /// Adjustment to Level based indent. When comments are aligned to the next
+ /// preprocessor line they must use the same offset as the directive,
+ /// typically 1 due to the leading #.
+ unsigned LevelOffset;
+
size_t MatchingOpeningBlockLineIndex;
bool InPPDirective;
bool MustBeDeclaration;
Index: lib/Format/TokenAnnotator.cpp
===================================================================
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -1707,6 +1707,33 @@
FormatToken *Current;
};
+enum CommentAlignment {
+ CA_None, // Comment is not aligned with the next line.
+ CA_First, // Comment is aligned with the first token on the next line.
+ CA_Directive, // Comment is aligned with the indented preprocessor directive
+ // on the next line.
+};
+
+CommentAlignment getCommentAlignment(const AnnotatedLine &Comment,
+ const AnnotatedLine &NextNonComment) {
+ if (NextNonComment.First->NewlinesBefore > 1)
+ return CA_None;
+ // If the next line is an indented preprocessor line look at the directive,
+ // not the #.
+ if ((NextNonComment.Type == LT_PreprocessorDirective ||
+ NextNonComment.Type == LT_ImportStatement) &&
+ NextNonComment.Level > 0 && !Comment.InPPDirective)
+ return NextNonComment.First->Next &&
+ (Comment.First->OriginalColumn ==
+ NextNonComment.First->Next->OriginalColumn)
+ ? CA_Directive
+ : CA_None;
+ else
+ return Comment.First->OriginalColumn == NextNonComment.First->OriginalColumn
+ ? CA_First
+ : CA_None;
+}
+
} // end anonymous namespace
void TokenAnnotator::setCommentLineLevels(
@@ -1723,15 +1750,15 @@
}
}
- 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)
+ // If the comment is aligned with the line immediately following it, that's
+ // probably intentional and we should keep it.
+ if (CommentLine && NextNonCommentLine) {
+ CommentAlignment Alignment =
+ getCommentAlignment(**I, *NextNonCommentLine);
+ if (Alignment != CA_None)
(*I)->Level = NextNonCommentLine->Level;
+ if (Alignment == CA_Directive)
+ (*I)->LevelOffset = 1;
} else {
NextNonCommentLine = (*I)->First->isNot(tok::r_brace) ? (*I) : nullptr;
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits