diff options
Diffstat (limited to 'unittests/Format/FormatTestComments.cpp')
-rw-r--r-- | unittests/Format/FormatTestComments.cpp | 523 |
1 files changed, 517 insertions, 6 deletions
diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp index f3c45fac34a99..ed11fbdb1fc0d 100644 --- a/unittests/Format/FormatTestComments.cpp +++ b/unittests/Format/FormatTestComments.cpp @@ -62,6 +62,12 @@ protected: return Style; } + FormatStyle getTextProtoStyleWithColumns(unsigned ColumnLimit) { + FormatStyle Style = getGoogleStyle(FormatStyle::FormatStyle::LK_TextProto); + Style.ColumnLimit = ColumnLimit; + return Style; + } + void verifyFormat(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); @@ -680,8 +686,7 @@ TEST_F(FormatTestComments, SplitsLongCxxComments) { EXPECT_EQ("{\n" " //\n" " //\\\n" - " // long 1 2 3 4\n" - " // 5\n" + " // long 1 2 3 4 5\n" "}", format("{\n" " //\n" @@ -689,6 +694,18 @@ TEST_F(FormatTestComments, SplitsLongCxxComments) { " // long 1 2 3 4 5\n" "}", getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5\n" + " // 6\n" + "}", + format("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5 6\n" + "}", + getLLVMStyleWithColumns(20))); } TEST_F(FormatTestComments, PreservesHangingIndentInCxxComments) { @@ -836,6 +853,67 @@ TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { " int j;\n" "}")); + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "#ifdef A\n" + "int j;\n" + "#endif\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); + // Keep the current level if there is an empty line between the comment and // the preprocessor directive. EXPECT_EQ("void f() {\n" @@ -853,8 +931,95 @@ TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { " int j;\n" "}")); + EXPECT_EQ("void f() {\n" + " int i;\n" + " return i;\n" + "}\n" + "// comment\n" + "\n" + "#ifdef A\n" + "int i;\n" + "#endif // A", + format("void f() {\n" + " int i;\n" + " return i;\n" + "}\n" + "// comment\n" + "\n" + "#ifdef A\n" + "int i;\n" + "#endif // A")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "// comment in else\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "/* comment in else */\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); + // Align with the preprocessor directive if the comment was originally aligned - // with the preprocessor directive. + // with the preprocessor directive and there is no newline between the comment + // and the preprocessor directive. EXPECT_EQ("void f() {\n" " int i;\n" "/* comment */\n" @@ -867,14 +1032,76 @@ TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { "#ifdef A\n" " int j;\n" "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + "// comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + "// comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "// comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + " #ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); + + EXPECT_EQ("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "/* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + format("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + " #ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}")); } TEST_F(FormatTestComments, SplitsLongLinesInComments) { + // FIXME: Do we need to fix up the " */" at the end? + // It doesn't look like any of our current logic triggers this. EXPECT_EQ("/* This is a long\n" " * comment that\n" - " * doesn't\n" - " * fit on one line.\n" - " */", + " * doesn't fit on\n" + " * one line. */", format("/* " "This is a long " "comment that " @@ -1852,6 +2079,22 @@ TEST_F(FormatTestComments, ReflowsComments) { " // longsec\n", getLLVMStyleWithColumns(20))); + // Simple case that correctly handles reflow in parameter lists. + EXPECT_EQ("a = f(/* looooooooong\n" + " * long long\n" + " */\n" + " a);", + format("a = f(/* looooooooong long\n* long\n*/ a);", + getLLVMStyleWithColumns(22))); + // Tricky case that has fewer lines if we reflow the comment, ending up with + // fewer lines. + EXPECT_EQ("a = f(/* loooooong\n" + " * long long\n" + " */\n" + " a);", + format("a = f(/* loooooong long\n* long\n*/ a);", + getLLVMStyleWithColumns(22))); + // Keep empty comment lines. EXPECT_EQ("/**/", format(" /**/", getLLVMStyleWithColumns(20))); EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20))); @@ -1860,6 +2103,85 @@ TEST_F(FormatTestComments, ReflowsComments) { EXPECT_EQ("///", format(" /// ", getLLVMStyleWithColumns(20))); } +TEST_F(FormatTestComments, ReflowsCommentsPrecise) { + // FIXME: This assumes we do not continue compressing whitespace once we are + // in reflow mode. Consider compressing whitespace. + + // Test that we stop reflowing precisely at the column limit. + // After reflowing, "// reflows into foo" does not fit the column limit, + // so we compress the whitespace. + EXPECT_EQ("// some text that\n" + "// reflows into foo\n", + format("// some text that reflows\n" + "// into foo\n", + getLLVMStyleWithColumns(20))); + // Given one more column, "// reflows into foo" does fit the limit, so we + // do not compress the whitespace. + EXPECT_EQ("// some text that\n" + "// reflows into foo\n", + format("// some text that reflows\n" + "// into foo\n", + getLLVMStyleWithColumns(21))); + + // Make sure that we correctly account for the space added in the reflow case + // when making the reflowing decision. + // First, when the next line ends precisely one column over the limit, do not + // reflow. + EXPECT_EQ("// some text that\n" + "// reflows\n" + "// into1234567\n", + format("// some text that reflows\n" + "// into1234567\n", + getLLVMStyleWithColumns(21))); + // Secondly, when the next line ends later, but the first word in that line + // is precisely one column over the limit, do not reflow. + EXPECT_EQ("// some text that\n" + "// reflows\n" + "// into1234567 f\n", + format("// some text that reflows\n" + "// into1234567 f\n", + getLLVMStyleWithColumns(21))); +} + +TEST_F(FormatTestComments, ReflowsCommentsWithExtraWhitespace) { + // Baseline. + EXPECT_EQ("// some text\n" + "// that re flows\n", + format("// some text that\n" + "// re flows\n", + getLLVMStyleWithColumns(16))); + EXPECT_EQ("// some text\n" + "// that re flows\n", + format("// some text that\n" + "// re flows\n", + getLLVMStyleWithColumns(16))); + EXPECT_EQ("/* some text\n" + " * that re flows\n" + " */\n", + format("/* some text that\n" + "* re flows\n" + "*/\n", + getLLVMStyleWithColumns(16))); + // FIXME: We do not reflow if the indent of two subsequent lines differs; + // given that this is different behavior from block comments, do we want + // to keep this? + EXPECT_EQ("// some text\n" + "// that\n" + "// re flows\n", + format("// some text that\n" + "// re flows\n", + getLLVMStyleWithColumns(16))); + // Space within parts of a line that fit. + // FIXME: Use the earliest possible split while reflowing to compress the + // whitespace within the line. + EXPECT_EQ("// some text that\n" + "// does re flow\n" + "// more here\n", + format("// some text that does\n" + "// re flow more here\n", + getLLVMStyleWithColumns(21))); +} + TEST_F(FormatTestComments, IgnoresIf0Contents) { EXPECT_EQ("#if 0\n" "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" @@ -2198,6 +2520,74 @@ TEST_F(FormatTestComments, BlockCommentsAtEndOfLine) { getLLVMStyleWithColumns(15))); } +TEST_F(FormatTestComments, BreaksAfterMultilineBlockCommentsInParamLists) { + EXPECT_EQ("a = f(/* long\n" + " long */\n" + " a);", + format("a = f(/* long long */ a);", getLLVMStyleWithColumns(16))); + EXPECT_EQ("a = f(\n" + " /* long\n" + " long */\n" + " a);", + format("a = f(/* long long */ a);", getLLVMStyleWithColumns(15))); + + EXPECT_EQ("a = f(/* long\n" + " long\n" + " */\n" + " a);", + format("a = f(/* long\n" + " long\n" + " */a);", + getLLVMStyleWithColumns(16))); + + EXPECT_EQ("a = f(/* long\n" + " long\n" + " */\n" + " a);", + format("a = f(/* long\n" + " long\n" + " */ a);", + getLLVMStyleWithColumns(16))); + + EXPECT_EQ("a = f(/* long\n" + " long\n" + " */\n" + " (1 + 1));", + format("a = f(/* long\n" + " long\n" + " */ (1 + 1));", + getLLVMStyleWithColumns(16))); + + EXPECT_EQ( + "a = f(a,\n" + " /* long\n" + " long */\n" + " b);", + format("a = f(a, /* long long */ b);", getLLVMStyleWithColumns(16))); + + EXPECT_EQ( + "a = f(\n" + " a,\n" + " /* long\n" + " long */\n" + " b);", + format("a = f(a, /* long long */ b);", getLLVMStyleWithColumns(15))); + + EXPECT_EQ("a = f(a,\n" + " /* long\n" + " long */\n" + " (1 + 1));", + format("a = f(a, /* long long */ (1 + 1));", + getLLVMStyleWithColumns(16))); + EXPECT_EQ("a = f(\n" + " a,\n" + " /* long\n" + " long */\n" + " (1 + 1));", + format("a = f(a, /* long long */ (1 + 1));", + getLLVMStyleWithColumns(15))); +} + TEST_F(FormatTestComments, IndentLineCommentsInStartOfBlockAtEndOfFile) { verifyFormat("{\n" " // a\n" @@ -2578,6 +2968,127 @@ TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { "* long */", getLLVMStyleWithColumns(20))); } + +TEST_F(FormatTestComments, NoCrash_Bug34236) { + // This is a test case from a crasher reported in: + // https://bugs.llvm.org/show_bug.cgi?id=34236 + // Temporarily disable formatting for readability. + // clang-format off + EXPECT_EQ( +"/* */ /*\n" +" * a\n" +" * b c d*/", + format( +"/* */ /*\n" +" * a b\n" +" * c d*/", + getLLVMStyleWithColumns(80))); + // clang-format on +} + +TEST_F(FormatTestComments, NonTrailingBlockComments) { + verifyFormat("const /** comment comment */ A = B;", + getLLVMStyleWithColumns(40)); + + verifyFormat("const /** comment comment comment */ A =\n" + " B;", + getLLVMStyleWithColumns(40)); + + EXPECT_EQ("const /** comment comment comment\n" + " comment */\n" + " A = B;", + format("const /** comment comment comment comment */\n" + " A = B;", + getLLVMStyleWithColumns(40))); +} + +TEST_F(FormatTestComments, PythonStyleComments) { + // Keeps a space after '#'. + EXPECT_EQ("# comment\n" + "key: value", + format("#comment\n" + "key:value", + getTextProtoStyleWithColumns(20))); + EXPECT_EQ("# comment\n" + "key: value", + format("# comment\n" + "key:value", + getTextProtoStyleWithColumns(20))); + // Breaks long comment. + EXPECT_EQ("# comment comment\n" + "# comment\n" + "key: value", + format("# comment comment comment\n" + "key:value", + getTextProtoStyleWithColumns(20))); + // Indents comments. + EXPECT_EQ("data {\n" + " # comment comment\n" + " # comment\n" + " key: value\n" + "}", + format("data {\n" + "# comment comment comment\n" + "key: value}", + getTextProtoStyleWithColumns(20))); + EXPECT_EQ("data {\n" + " # comment comment\n" + " # comment\n" + " key: value\n" + "}", + format("data {# comment comment comment\n" + "key: value}", + getTextProtoStyleWithColumns(20))); + // Reflows long comments. + EXPECT_EQ("# comment comment\n" + "# comment comment\n" + "key: value", + format("# comment comment comment\n" + "# comment\n" + "key:value", + getTextProtoStyleWithColumns(20))); + // Breaks trailing comments. + EXPECT_EQ("k: val # comment\n" + " # comment\n" + "a: 1", + format("k:val#comment comment\n" + "a:1", + getTextProtoStyleWithColumns(20))); + EXPECT_EQ("id {\n" + " k: val # comment\n" + " # comment\n" + " # line line\n" + " a: 1\n" + "}", + format("id {k:val#comment comment\n" + "# line line\n" + "a:1}", + getTextProtoStyleWithColumns(20))); + // Aligns trailing comments. + EXPECT_EQ("k: val # commen1\n" + " # commen2\n" + " # commen3\n" + "# commen4\n" + "a: 1 # commen5\n" + " # commen6\n" + " # commen7", + format("k:val#commen1 commen2\n" + " # commen3\n" + "# commen4\n" + "a:1#commen5 commen6\n" + " #commen7", + getTextProtoStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, BreaksBeforeTrailingUnbreakableSequence) { + // The end of /* trail */ is exactly at 80 columns, but the unbreakable + // trailing sequence ); after it exceeds the column limit. Make sure we + // correctly break the line in that case. + verifyFormat("int a =\n" + " foo(/* trail */);", + getLLVMStyleWithColumns(23)); +} + } // end namespace } // end namespace format } // end namespace clang |