diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:02:28 +0000 |
commit | 7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch) | |
tree | c72b9241553fc9966179aba84f90f17bfa9235c3 /unittests/Format | |
parent | b52119637f743680a99710ce5fdb6646da2772af (diff) |
Notes
Diffstat (limited to 'unittests/Format')
-rw-r--r-- | unittests/Format/CMakeLists.txt | 4 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 1805 | ||||
-rw-r--r-- | unittests/Format/FormatTestComments.cpp | 2373 | ||||
-rw-r--r-- | unittests/Format/FormatTestJS.cpp | 208 | ||||
-rw-r--r-- | unittests/Format/FormatTestJava.cpp | 19 | ||||
-rw-r--r-- | unittests/Format/FormatTestObjC.cpp | 16 | ||||
-rw-r--r-- | unittests/Format/FormatTestProto.cpp | 10 | ||||
-rw-r--r-- | unittests/Format/FormatTestSelective.cpp | 10 | ||||
-rw-r--r-- | unittests/Format/NamespaceEndCommentsFixerTest.cpp | 602 |
9 files changed, 3712 insertions, 1335 deletions
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt index eb7756a0ba56..507d643ba102 100644 --- a/unittests/Format/CMakeLists.txt +++ b/unittests/Format/CMakeLists.txt @@ -5,11 +5,13 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(FormatTests CleanupTest.cpp FormatTest.cpp - FormatTestJava.cpp + FormatTestComments.cpp FormatTestJS.cpp + FormatTestJava.cpp FormatTestObjC.cpp FormatTestProto.cpp FormatTestSelective.cpp + NamespaceEndCommentsFixerTest.cpp SortImportsTestJS.cpp SortIncludesTest.cpp ) diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index b402b5c4a54c..e6ba2230ac6d 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -71,6 +71,13 @@ protected: void verifyFormat(llvm::StringRef Code, const FormatStyle &Style = getLLVMStyle()) { EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); + if (Style.Language == FormatStyle::LK_Cpp) { + // Objective-C++ is a superset of C++, so everything checked for C++ + // needs to be checked for Objective-C++ as well. + FormatStyle ObjCStyle = Style; + ObjCStyle.Language = FormatStyle::LK_ObjC; + EXPECT_EQ(Code.str(), format(test::messUp(Code), ObjCStyle)); + } } void verifyIncompleteFormat(llvm::StringRef Code, @@ -139,6 +146,8 @@ TEST_F(FormatTest, NestedNameSpecifiers) { verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())"); verifyFormat("static constexpr bool Bar = decltype(bar())::value;"); verifyFormat("bool a = 2 < ::SomeFunction();"); + verifyFormat("ALWAYS_INLINE ::std::string getName();"); + verifyFormat("some::string getName();"); } TEST_F(FormatTest, OnlyGeneratesNecessaryReplacements) { @@ -261,6 +270,15 @@ TEST_F(FormatTest, RemovesEmptyLines) { "}")); // FIXME: This is slightly inconsistent. + FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle(); + LLVMWithNoNamespaceFix.FixNamespaceComments = false; + EXPECT_EQ("namespace {\n" + "int i;\n" + "}", + format("namespace {\n" + "int i;\n" + "\n" + "}", LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace {\n" "int i;\n" "}", @@ -866,1061 +884,6 @@ TEST_F(FormatTest, FormatsLabels) { } //===----------------------------------------------------------------------===// -// Tests for comments. -//===----------------------------------------------------------------------===// - -TEST_F(FormatTest, UnderstandsSingleLineComments) { - verifyFormat("//* */"); - verifyFormat("// line 1\n" - "// line 2\n" - "void f() {}\n"); - - verifyFormat("void f() {\n" - " // Doesn't do anything\n" - "}"); - verifyFormat("SomeObject\n" - " // Calling someFunction on SomeObject\n" - " .someFunction();"); - verifyFormat("auto result = SomeObject\n" - " // Calling someFunction on SomeObject\n" - " .someFunction();"); - verifyFormat("void f(int i, // some comment (probably for i)\n" - " int j, // some comment (probably for j)\n" - " int k); // some comment (probably for k)"); - verifyFormat("void f(int i,\n" - " // some comment (probably for j)\n" - " int j,\n" - " // some comment (probably for k)\n" - " int k);"); - - verifyFormat("int i // This is a fancy variable\n" - " = 5; // with nicely aligned comment."); - - verifyFormat("// Leading comment.\n" - "int a; // Trailing comment."); - verifyFormat("int a; // Trailing comment\n" - " // on 2\n" - " // or 3 lines.\n" - "int b;"); - verifyFormat("int a; // Trailing comment\n" - "\n" - "// Leading comment.\n" - "int b;"); - verifyFormat("int a; // Comment.\n" - " // More details.\n" - "int bbbb; // Another comment."); - verifyFormat( - "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n" - "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // comment\n" - "int cccccccccccccccccccccccccccccc; // comment\n" - "int ddd; // looooooooooooooooooooooooong comment\n" - "int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n" - "int bbbbbbbbbbbbbbbbbbbbb; // comment\n" - "int ccccccccccccccccccc; // comment"); - - verifyFormat("#include \"a\" // comment\n" - "#include \"a/b/c\" // comment"); - verifyFormat("#include <a> // comment\n" - "#include <a/b/c> // comment"); - EXPECT_EQ("#include \"a\" // comment\n" - "#include \"a/b/c\" // comment", - format("#include \\\n" - " \"a\" // comment\n" - "#include \"a/b/c\" // comment")); - - verifyFormat("enum E {\n" - " // comment\n" - " VAL_A, // comment\n" - " VAL_B\n" - "};"); - - verifyFormat( - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment"); - verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " // Comment inside a statement.\n" - " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); - verifyFormat("SomeFunction(a,\n" - " // comment\n" - " b + x);"); - verifyFormat("SomeFunction(a, a,\n" - " // comment\n" - " b + x);"); - verifyFormat( - "bool aaaaaaaaaaaaa = // comment\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); - - verifyFormat("int aaaa; // aaaaa\n" - "int aa; // aaaaaaa", - getLLVMStyleWithColumns(20)); - - EXPECT_EQ("void f() { // This does something ..\n" - "}\n" - "int a; // This is unrelated", - format("void f() { // This does something ..\n" - " }\n" - "int a; // This is unrelated")); - EXPECT_EQ("class C {\n" - " void f() { // This does something ..\n" - " } // awesome..\n" - "\n" - " int a; // This is unrelated\n" - "};", - format("class C{void f() { // This does something ..\n" - " } // awesome..\n" - " \n" - "int a; // This is unrelated\n" - "};")); - - EXPECT_EQ("int i; // single line trailing comment", - format("int i;\\\n// single line trailing comment")); - - verifyGoogleFormat("int a; // Trailing comment."); - - verifyFormat("someFunction(anotherFunction( // Force break.\n" - " parameter));"); - - verifyGoogleFormat("#endif // HEADER_GUARD"); - - verifyFormat("const char *test[] = {\n" - " // A\n" - " \"aaaa\",\n" - " // B\n" - " \"aaaaa\"};"); - verifyGoogleFormat( - "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaa); // 81_cols_with_this_comment"); - EXPECT_EQ("D(a, {\n" - " // test\n" - " int a;\n" - "});", - format("D(a, {\n" - "// test\n" - "int a;\n" - "});")); - - EXPECT_EQ("lineWith(); // comment\n" - "// at start\n" - "otherLine();", - format("lineWith(); // comment\n" - "// at start\n" - "otherLine();")); - EXPECT_EQ("lineWith(); // comment\n" - "/*\n" - " * at start */\n" - "otherLine();", - format("lineWith(); // comment\n" - "/*\n" - " * at start */\n" - "otherLine();")); - EXPECT_EQ("lineWith(); // comment\n" - " // at start\n" - "otherLine();", - format("lineWith(); // comment\n" - " // at start\n" - "otherLine();")); - - EXPECT_EQ("lineWith(); // comment\n" - "// at start\n" - "otherLine(); // comment", - format("lineWith(); // comment\n" - "// at start\n" - "otherLine(); // comment")); - EXPECT_EQ("lineWith();\n" - "// at start\n" - "otherLine(); // comment", - format("lineWith();\n" - " // at start\n" - "otherLine(); // comment")); - EXPECT_EQ("// first\n" - "// at start\n" - "otherLine(); // comment", - format("// first\n" - " // at start\n" - "otherLine(); // comment")); - EXPECT_EQ("f();\n" - "// first\n" - "// at start\n" - "otherLine(); // comment", - format("f();\n" - "// first\n" - " // at start\n" - "otherLine(); // comment")); - verifyFormat("f(); // comment\n" - "// first\n" - "// at start\n" - "otherLine();"); - EXPECT_EQ("f(); // comment\n" - "// first\n" - "// at start\n" - "otherLine();", - format("f(); // comment\n" - "// first\n" - " // at start\n" - "otherLine();")); - EXPECT_EQ("f(); // comment\n" - " // first\n" - "// at start\n" - "otherLine();", - format("f(); // comment\n" - " // first\n" - "// at start\n" - "otherLine();")); - EXPECT_EQ("void f() {\n" - " lineWith(); // comment\n" - " // at start\n" - "}", - format("void f() {\n" - " lineWith(); // comment\n" - " // at start\n" - "}")); - EXPECT_EQ("int xy; // a\n" - "int z; // b", - format("int xy; // a\n" - "int z; //b")); - EXPECT_EQ("int xy; // a\n" - "int z; // bb", - format("int xy; // a\n" - "int z; //bb", - getLLVMStyleWithColumns(12))); - - verifyFormat("#define A \\\n" - " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" - " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", - getLLVMStyleWithColumns(60)); - verifyFormat( - "#define A \\\n" - " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" - " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", - getLLVMStyleWithColumns(61)); - - verifyFormat("if ( // This is some comment\n" - " x + 3) {\n" - "}"); - EXPECT_EQ("if ( // This is some comment\n" - " // spanning two lines\n" - " x + 3) {\n" - "}", - format("if( // This is some comment\n" - " // spanning two lines\n" - " x + 3) {\n" - "}")); - - verifyNoCrash("/\\\n/"); - verifyNoCrash("/\\\n* */"); - // The 0-character somehow makes the lexer return a proper comment. - verifyNoCrash(StringRef("/*\\\0\n/", 6)); -} - -TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { - EXPECT_EQ("SomeFunction(a,\n" - " b, // comment\n" - " c);", - format("SomeFunction(a,\n" - " b, // comment\n" - " c);")); - EXPECT_EQ("SomeFunction(a, b,\n" - " // comment\n" - " c);", - format("SomeFunction(a,\n" - " b,\n" - " // comment\n" - " c);")); - EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n" - " c);", - format("SomeFunction(a, b, // comment (unclear relation)\n" - " c);")); - EXPECT_EQ("SomeFunction(a, // comment\n" - " b,\n" - " c); // comment", - format("SomeFunction(a, // comment\n" - " b,\n" - " c); // comment")); - EXPECT_EQ("aaaaaaaaaa(aaaa(aaaa,\n" - " aaaa), //\n" - " aaaa, bbbbb);", - format("aaaaaaaaaa(aaaa(aaaa,\n" - "aaaa), //\n" - "aaaa, bbbbb);")); -} - -TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) { - EXPECT_EQ("// comment", format("// comment ")); - EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment", - format("int aaaaaaa, bbbbbbb; // comment ", - getLLVMStyleWithColumns(33))); - EXPECT_EQ("// comment\\\n", format("// comment\\\n \t \v \f ")); - EXPECT_EQ("// comment \\\n", format("// comment \\\n \t \v \f ")); -} - -TEST_F(FormatTest, UnderstandsBlockComments) { - verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);"); - verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }"); - EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbb);", - format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n" - "/* Trailing comment for aa... */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbb);")); - EXPECT_EQ( - "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);", - format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n" - "/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);")); - EXPECT_EQ( - "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" - "}", - format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaa ,\n" - " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" - "}")); - verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); - - FormatStyle NoBinPacking = getLLVMStyle(); - NoBinPacking.BinPackParameters = false; - verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n" - " /* parameter 2 */ aaaaaa,\n" - " /* parameter 3 */ aaaaaa,\n" - " /* parameter 4 */ aaaaaa);", - NoBinPacking); - - // Aligning block comments in macros. - verifyGoogleFormat("#define A \\\n" - " int i; /*a*/ \\\n" - " int jjj; /*b*/"); -} - -TEST_F(FormatTest, AlignsBlockComments) { - EXPECT_EQ("/*\n" - " * Really multi-line\n" - " * comment.\n" - " */\n" - "void f() {}", - format(" /*\n" - " * Really multi-line\n" - " * comment.\n" - " */\n" - " void f() {}")); - EXPECT_EQ("class C {\n" - " /*\n" - " * Another multi-line\n" - " * comment.\n" - " */\n" - " void f() {}\n" - "};", - format("class C {\n" - "/*\n" - " * Another multi-line\n" - " * comment.\n" - " */\n" - "void f() {}\n" - "};")); - EXPECT_EQ("/*\n" - " 1. This is a comment with non-trivial formatting.\n" - " 1.1. We have to indent/outdent all lines equally\n" - " 1.1.1. to keep the formatting.\n" - " */", - format(" /*\n" - " 1. This is a comment with non-trivial formatting.\n" - " 1.1. We have to indent/outdent all lines equally\n" - " 1.1.1. to keep the formatting.\n" - " */")); - EXPECT_EQ("/*\n" - "Don't try to outdent if there's not enough indentation.\n" - "*/", - format(" /*\n" - " Don't try to outdent if there's not enough indentation.\n" - " */")); - - EXPECT_EQ("int i; /* Comment with empty...\n" - " *\n" - " * line. */", - format("int i; /* Comment with empty...\n" - " *\n" - " * line. */")); - EXPECT_EQ("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment 1 */\n" - "int baz = 0; /* multiline\n" - " comment 2 */\n" - "int bzz = 0; /* multiline\n" - " comment 3 */", - format("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment 1 */\n" - "int baz = 0; /* multiline\n" - " comment 2 */\n" - "int bzz = 0; /* multiline\n" - " comment 3 */")); - EXPECT_EQ("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment */\n" - "int baz = 0; /* multiline\n" - "comment */", - format("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - "comment */\n" - "int baz = 0; /* multiline\n" - "comment */")); -} - -TEST_F(FormatTest, CommentReflowingCanBeTurnedOff) { - FormatStyle Style = getLLVMStyleWithColumns(20); - Style.ReflowComments = false; - verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); - verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); -} - -TEST_F(FormatTest, CorrectlyHandlesLengthOfBlockComments) { - EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */", - format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */")); - EXPECT_EQ( - "void ffffffffffff(\n" - " int aaaaaaaa, int bbbbbbbb,\n" - " int cccccccccccc) { /*\n" - " aaaaaaaaaa\n" - " aaaaaaaaaaaaa\n" - " bbbbbbbbbbbbbb\n" - " bbbbbbbbbb\n" - " */\n" - "}", - format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n" - "{ /*\n" - " aaaaaaaaaa aaaaaaaaaaaaa\n" - " bbbbbbbbbbbbbb bbbbbbbbbb\n" - " */\n" - "}", - getLLVMStyleWithColumns(40))); -} - -TEST_F(FormatTest, DontBreakNonTrailingBlockComments) { - EXPECT_EQ("void ffffffffff(\n" - " int aaaaa /* test */);", - format("void ffffffffff(int aaaaa /* test */);", - getLLVMStyleWithColumns(35))); -} - -TEST_F(FormatTest, SplitsLongCxxComments) { - EXPECT_EQ("// A comment that\n" - "// doesn't fit on\n" - "// one line", - format("// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// A comment that\n" - "/// doesn't fit on\n" - "/// one line", - format("/// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! A comment that\n" - "//! doesn't fit on\n" - "//! one line", - format("//! A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// a b c d\n" - "// e f g\n" - "// h i j k", - format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "// a b c d\n" - "// e f g\n" - "// h i j k", - format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); - EXPECT_EQ("if (true) // A comment that\n" - " // doesn't fit on\n" - " // one line", - format("if (true) // A comment that doesn't fit on one line ", - getLLVMStyleWithColumns(30))); - EXPECT_EQ("// Don't_touch_leading_whitespace", - format("// Don't_touch_leading_whitespace", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// Add leading\n" - "// whitespace", - format("//Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// Add leading\n" - "/// whitespace", - format("///Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! Add leading\n" - "//! whitespace", - format("//!Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle())); - EXPECT_EQ("// Even if it makes the line exceed the column\n" - "// limit", - format("//Even if it makes the line exceed the column limit", - getLLVMStyleWithColumns(51))); - EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle())); - - EXPECT_EQ("// aa bb cc dd", - format("// aa bb cc dd ", - getLLVMStyleWithColumns(15))); - - EXPECT_EQ("// A comment before\n" - "// a macro\n" - "// definition\n" - "#define a b", - format("// A comment before a macro definition\n" - "#define a b", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("void ffffff(\n" - " int aaaaaaaaa, // wwww\n" - " int bbbbbbbbbb, // xxxxxxx\n" - " // yyyyyyyyyy\n" - " int c, int d, int e) {}", - format("void ffffff(\n" - " int aaaaaaaaa, // wwww\n" - " int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n" - " int c, int d, int e) {}", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - getLLVMStyleWithColumns(20))); - EXPECT_EQ( - "#define XXX // a b c d\n" - " // e f g h", - format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22))); - EXPECT_EQ( - "#define XXX // q w e r\n" - " // t y u i", - format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22))); -} - -TEST_F(FormatTest, PreservesHangingIndentInCxxComments) { - EXPECT_EQ("// A comment\n" - "// that doesn't\n" - "// fit on one\n" - "// line", - format("// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// A comment\n" - "/// that doesn't\n" - "/// fit on one\n" - "/// line", - format("/// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); -} - -TEST_F(FormatTest, DontSplitLineCommentsWithEscapedNewlines) { - EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); - EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - getLLVMStyleWithColumns(50))); - // FIXME: One day we might want to implement adjustment of leading whitespace - // of the consecutive lines in this kind of comment: - EXPECT_EQ("double\n" - " a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - getLLVMStyleWithColumns(49))); -} - -TEST_F(FormatTest, DontSplitLineCommentsWithPragmas) { - FormatStyle Pragmas = getLLVMStyleWithColumns(30); - Pragmas.CommentPragmas = "^ IWYU pragma:"; - EXPECT_EQ( - "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", - format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas)); - EXPECT_EQ( - "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", - format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas)); -} - -TEST_F(FormatTest, PriorityOfCommentBreaking) { - EXPECT_EQ("if (xxx ==\n" - " yyy && // aaaaaaaaaaaa bbbbbbbbb\n" - " zzz)\n" - " q();", - format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("if (xxxxxxxxxx ==\n" - " yyy && // aaaaaa bbbbbbbb cccc\n" - " zzz)\n" - " q();", - format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("if (xxxxxxxxxx &&\n" - " yyy || // aaaaaa bbbbbbbb cccc\n" - " zzz)\n" - " q();", - format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("fffffffff(\n" - " &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" - " zzz);", - format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" - " zzz);", - getLLVMStyleWithColumns(40))); -} - -TEST_F(FormatTest, MultiLineCommentsInDefines) { - EXPECT_EQ("#define A(x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - format("#define A(x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - getLLVMStyleWithColumns(17))); - EXPECT_EQ("#define A( \\\n" - " x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - format("#define A( \\\n" - " x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - getLLVMStyleWithColumns(17))); -} - -TEST_F(FormatTest, ParsesCommentsAdjacentToPPDirectives) { - EXPECT_EQ("namespace {}\n// Test\n#define A", - format("namespace {}\n // Test\n#define A")); - EXPECT_EQ("namespace {}\n/* Test */\n#define A", - format("namespace {}\n /* Test */\n#define A")); - EXPECT_EQ("namespace {}\n/* Test */ #define A", - format("namespace {}\n /* Test */ #define A")); -} - -TEST_F(FormatTest, SplitsLongLinesInComments) { - EXPECT_EQ("/* This is a long\n" - " * comment that\n" - " * doesn't\n" - " * fit on one line.\n" - " */", - format("/* " - "This is a long " - "comment that " - "doesn't " - "fit on one line. */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ( - "/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); - EXPECT_EQ("/*\n" - "This is a long\n" - "comment that doesn't\n" - "fit on one line.\n" - "*/", - format("/*\n" - "This is a long " - "comment that doesn't " - "fit on one line. \n" - "*/", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This is a long\n" - " * comment that\n" - " * doesn't fit on\n" - " * one line.\n" - " */", - format("/* \n" - " * This is a long " - " comment that " - " doesn't fit on " - " one line. \n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" - " * so_it_should_be_broken\n" - " * wherever_a_space_occurs\n" - " */", - format("/*\n" - " * This_is_a_comment_with_words_that_dont_fit_on_one_line " - " so_it_should_be_broken " - " wherever_a_space_occurs \n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This_comment_can_not_be_broken_into_lines\n" - " */", - format("/*\n" - " * This_comment_can_not_be_broken_into_lines\n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " /*\n" - " This is another\n" - " long comment that\n" - " doesn't fit on one\n" - " line 1234567890\n" - " */\n" - "}", - format("{\n" - "/*\n" - "This is another " - " long comment that " - " doesn't fit on one" - " line 1234567890\n" - "*/\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " /*\n" - " * This i s\n" - " * another comment\n" - " * t hat doesn' t\n" - " * fit on one l i\n" - " * n e\n" - " */\n" - "}", - format("{\n" - "/*\n" - " * This i s" - " another comment" - " t hat doesn' t" - " fit on one l i" - " n e\n" - " */\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This is a long\n" - " * comment that\n" - " * doesn't fit on\n" - " * one line\n" - " */", - format(" /*\n" - " * This is a long comment that doesn't fit on one line\n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " if (something) /* This is a\n" - " long\n" - " comment */\n" - " ;\n" - "}", - format("{\n" - " if (something) /* This is a long comment */\n" - " ;\n" - "}", - getLLVMStyleWithColumns(30))); - - EXPECT_EQ("/* A comment before\n" - " * a macro\n" - " * definition */\n" - "#define a b", - format("/* A comment before a macro definition */\n" - "#define a b", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("/* some comment\n" - " * a comment\n" - "* that we break\n" - " * another comment\n" - "* we have to break\n" - "* a left comment\n" - " */", - format(" /* some comment\n" - " * a comment that we break\n" - " * another comment we have to break\n" - "* a left comment\n" - " */", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("/**\n" - " * multiline block\n" - " * comment\n" - " *\n" - " */", - format("/**\n" - " * multiline block comment\n" - " *\n" - " */", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("/*\n" - "\n" - "\n" - " */\n", - format(" /* \n" - " \n" - " \n" - " */\n")); - - EXPECT_EQ("/* a a */", - format("/* a a */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* a a bc */", - format("/* a a bc */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* aaa aaa\n" - " * aaaaa */", - format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* aaa aaa\n" - " * aaaaa */", - format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); -} - -TEST_F(FormatTest, SplitsLongLinesInCommentsInPreprocessor) { - EXPECT_EQ("#define X \\\n" - " /* \\\n" - " Test \\\n" - " Macro comment \\\n" - " with a long \\\n" - " line \\\n" - " */ \\\n" - " A + B", - format("#define X \\\n" - " /*\n" - " Test\n" - " Macro comment with a long line\n" - " */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define X \\\n" - " /* Macro comment \\\n" - " with a long \\\n" - " line */ \\\n" - " A + B", - format("#define X \\\n" - " /* Macro comment with a long\n" - " line */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define X \\\n" - " /* Macro comment \\\n" - " * with a long \\\n" - " * line */ \\\n" - " A + B", - format("#define X \\\n" - " /* Macro comment with a long line */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); -} - -TEST_F(FormatTest, CommentsInStaticInitializers) { - EXPECT_EQ( - "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n" - " aaaaaaaaaaaaaaaaaaaa /* comment */,\n" - " /* comment */ aaaaaaaaaaaaaaaaaaaa,\n" - " aaaaaaaaaaaaaaaaaaaa, // comment\n" - " aaaaaaaaaaaaaaaaaaaa};", - format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n" - " aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n" - " /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n" - " aaaaaaaaaaaaaaaaaaaa , // comment\n" - " aaaaaaaaaaaaaaaaaaaa };")); - verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" - " bbbbbbbbbbb, ccccccccccc};"); - verifyFormat("static SomeType type = {aaaaaaaaaaa,\n" - " // comment for bb....\n" - " bbbbbbbbbbb, ccccccccccc};"); - verifyGoogleFormat( - "static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" - " bbbbbbbbbbb, ccccccccccc};"); - verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n" - " // comment for bb....\n" - " bbbbbbbbbbb, ccccccccccc};"); - - verifyFormat("S s = {{a, b, c}, // Group #1\n" - " {d, e, f}, // Group #2\n" - " {g, h, i}}; // Group #3"); - verifyFormat("S s = {{// Group #1\n" - " a, b, c},\n" - " {// Group #2\n" - " d, e, f},\n" - " {// Group #3\n" - " g, h, i}};"); - - EXPECT_EQ("S s = {\n" - " // Some comment\n" - " a,\n" - "\n" - " // Comment after empty line\n" - " b}", - format("S s = {\n" - " // Some comment\n" - " a,\n" - " \n" - " // Comment after empty line\n" - " b\n" - "}")); - EXPECT_EQ("S s = {\n" - " /* Some comment */\n" - " a,\n" - "\n" - " /* Comment after empty line */\n" - " b}", - format("S s = {\n" - " /* Some comment */\n" - " a,\n" - " \n" - " /* Comment after empty line */\n" - " b\n" - "}")); - verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n" - " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" - " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" - " 0x00, 0x00, 0x00, 0x00}; // comment\n"); -} - -TEST_F(FormatTest, IgnoresIf0Contents) { - EXPECT_EQ("#if 0\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f() {}", - format("#if 0\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f( ) { }")); - EXPECT_EQ("#if false\n" - "void f( ) { }\n" - "#endif\n" - "void g() {}\n", - format("#if false\n" - "void f( ) { }\n" - "#endif\n" - "void g( ) { }\n")); - EXPECT_EQ("enum E {\n" - " One,\n" - " Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five\n" - "};", - format("enum E {\n" - " One,Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five};")); - EXPECT_EQ("enum F {\n" - " One,\n" - "#if 1\n" - " Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five\n" - "#endif\n" - "};", - format("enum F {\n" - "One,\n" - "#if 1\n" - "Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - "Five\n" - "#endif\n" - "};")); - EXPECT_EQ("enum G {\n" - " One,\n" - "#if 0\n" - "Two,\n" - "#else\n" - " Three,\n" - "#endif\n" - " Four\n" - "};", - format("enum G {\n" - "One,\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum H {\n" - " One,\n" - "#if 0\n" - "#ifdef Q\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "#endif\n" - " Four\n" - "};", - format("enum H {\n" - "One,\n" - "#if 0\n" - "#ifdef Q\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum I {\n" - " One,\n" - "#if /* test */ 0 || 1\n" - "Two,\n" - "Three,\n" - "#endif\n" - " Four\n" - "};", - format("enum I {\n" - "One,\n" - "#if /* test */ 0 || 1\n" - "Two,\n" - "Three,\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum J {\n" - " One,\n" - "#if 0\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four,\n" - "#endif\n" - " Five\n" - "};", - format("enum J {\n" - "One,\n" - "#if 0\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four,\n" - "#endif\n" - "Five\n" - "};")); -} - -//===----------------------------------------------------------------------===// // Tests for classes, namespaces, etc. //===----------------------------------------------------------------------===// @@ -2066,6 +1029,17 @@ TEST_F(FormatTest, FormatsClasses) { verifyFormat("class ::A::B {};"); } +TEST_F(FormatTest, BreakBeforeInheritanceComma) { + FormatStyle StyleWithInheritanceBreak = getLLVMStyle(); + StyleWithInheritanceBreak.BreakBeforeInheritanceComma = true; + + verifyFormat("class MyClass : public X {};", StyleWithInheritanceBreak); + verifyFormat("class MyClass\n" + " : public X\n" + " , public Y {};", + StyleWithInheritanceBreak); +} + TEST_F(FormatTest, FormatsVariableDeclarationsAfterStructOrClass) { verifyFormat("class A {\n} a, b;"); verifyFormat("struct A {\n} a, b;"); @@ -2243,33 +1217,43 @@ TEST_F(FormatTest, FormatsBitfields) { } TEST_F(FormatTest, FormatsNamespaces) { + FormatStyle LLVMWithNoNamespaceFix = getLLVMStyle(); + LLVMWithNoNamespaceFix.FixNamespaceComments = false; + verifyFormat("namespace some_namespace {\n" "class A {};\n" "void f() { f(); }\n" - "}"); + "}", + LLVMWithNoNamespaceFix); verifyFormat("namespace {\n" "class A {};\n" "void f() { f(); }\n" - "}"); + "}", + LLVMWithNoNamespaceFix); verifyFormat("inline namespace X {\n" "class A {};\n" "void f() { f(); }\n" - "}"); + "}", + LLVMWithNoNamespaceFix); verifyFormat("using namespace some_namespace;\n" "class A {};\n" - "void f() { f(); }"); + "void f() { f(); }", + LLVMWithNoNamespaceFix); // This code is more common than we thought; if we // layout this correctly the semicolon will go into // its own line, which is undesirable. - verifyFormat("namespace {};"); + verifyFormat("namespace {};", + LLVMWithNoNamespaceFix); verifyFormat("namespace {\n" "class A {};\n" - "};"); + "};", + LLVMWithNoNamespaceFix); verifyFormat("namespace {\n" "int SomeVariable = 0; // comment\n" - "} // namespace"); + "} // namespace", + LLVMWithNoNamespaceFix); EXPECT_EQ("#ifndef HEADER_GUARD\n" "#define HEADER_GUARD\n" "namespace my_namespace {\n" @@ -2281,14 +1265,16 @@ TEST_F(FormatTest, FormatsNamespaces) { " namespace my_namespace {\n" "int i;\n" "} // my_namespace\n" - "#endif // HEADER_GUARD")); + "#endif // HEADER_GUARD", + LLVMWithNoNamespaceFix)); EXPECT_EQ("namespace A::B {\n" "class C {};\n" "}", format("namespace A::B {\n" "class C {};\n" - "}")); + "}", + LLVMWithNoNamespaceFix)); FormatStyle Style = getLLVMStyle(); Style.NamespaceIndentation = FormatStyle::NI_All; @@ -2296,14 +1282,14 @@ TEST_F(FormatTest, FormatsNamespaces) { " int i;\n" " namespace in {\n" " int i;\n" - " } // namespace\n" - "} // namespace", + " } // namespace in\n" + "} // namespace out", format("namespace out {\n" "int i;\n" "namespace in {\n" "int i;\n" - "} // namespace\n" - "} // namespace", + "} // namespace in\n" + "} // namespace out", Style)); Style.NamespaceIndentation = FormatStyle::NI_Inner; @@ -2311,14 +1297,14 @@ TEST_F(FormatTest, FormatsNamespaces) { "int i;\n" "namespace in {\n" " int i;\n" - "} // namespace\n" - "} // namespace", + "} // namespace in\n" + "} // namespace out", format("namespace out {\n" "int i;\n" "namespace in {\n" "int i;\n" - "} // namespace\n" - "} // namespace", + "} // namespace in\n" + "} // namespace out", Style)); } @@ -2822,11 +1808,11 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { EXPECT_EQ("SOME_MACRO\n" "namespace {\n" "void f();\n" - "}", + "} // namespace", format("SOME_MACRO\n" " namespace {\n" "void f( );\n" - "}")); + "} // namespace")); // Only if the identifier contains at least 5 characters. EXPECT_EQ("HTTP f();", format("HTTP\nf();")); EXPECT_EQ("MACRO\nf();", format("MACRO\nf();")); @@ -3021,21 +2007,10 @@ TEST_F(FormatTest, EscapedNewlines) { format("#define A \\\nint i;\\\n int j;", getLLVMStyleWithColumns(11))); EXPECT_EQ("#define A\n\nint i;", format("#define A \\\n\n int i;")); EXPECT_EQ("template <class T> f();", format("\\\ntemplate <class T> f();")); - EXPECT_EQ("/* \\ \\ \\\n*/", format("\\\n/* \\ \\ \\\n*/")); + EXPECT_EQ("/* \\ \\ \\\n */", format("\\\n/* \\ \\ \\\n */")); EXPECT_EQ("<a\n\\\\\n>", format("<a\n\\\\\n>")); } -TEST_F(FormatTest, DontCrashOnBlockComments) { - EXPECT_EQ( - "int xxxxxxxxx; /* " - "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" - "zzzzzz\n" - "0*/", - format("int xxxxxxxxx; /* " - "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" - "0*/")); -} - TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) { verifyFormat("#define A \\\n" " int v( \\\n" @@ -3353,9 +2328,10 @@ TEST_F(FormatTest, PreventConfusingIndents) { " aaaaaaaaaaaaaaaaaaaaaaaa<\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>,\n" " aaaaaaaaaaaaaaaaaaaaaaaa>;"); - verifyFormat("int a = bbbb && ccc && fffff(\n" + verifyFormat("int a = bbbb && ccc &&\n" + " fffff(\n" "#define A Just forcing a new line\n" - " ddd);"); + " ddd);"); } TEST_F(FormatTest, LineBreakingInBinaryExpressions) { @@ -3438,6 +2414,12 @@ TEST_F(FormatTest, LineBreakingInBinaryExpressions) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n}", OnePerLine); + + verifyFormat("int i = someFunction(aaaaaaa, 0)\n" + " .aaa(aaaaaaaaaaaaa) *\n" + " aaaaaaa +\n" + " aaaaaaa;", + getLLVMStyleWithColumns(40)); } TEST_F(FormatTest, ExpressionIndentation) { @@ -3463,9 +2445,14 @@ TEST_F(FormatTest, ExpressionIndentation) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}"); verifyFormat("if () {\n" + "} else if (aaaaa && bbbbb > // break\n" + " ccccc) {\n" + "}"); + verifyFormat("if () {\n" "} else if (aaaaa &&\n" " bbbbb > // break\n" - " ccccc) {\n" + " ccccc &&\n" + " ddddd) {\n" "}"); // Presence of a trailing comment used to change indentation of b. @@ -3549,9 +2536,22 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style); } +TEST_F(FormatTest, EnforcedOperatorWraps) { + // Here we'd like to wrap after the || operators, but a comment is forcing an + // earlier wrap. + verifyFormat("bool x = aaaaa //\n" + " || bbbbb\n" + " //\n" + " || cccc;"); +} + TEST_F(FormatTest, NoOperandAlignment) { FormatStyle Style = getLLVMStyle(); Style.AlignOperands = false; + verifyFormat("aaaaaaaaaaaaaa(aaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", + Style); Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; verifyFormat("bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -3570,7 +2570,7 @@ TEST_F(FormatTest, NoOperandAlignment) { Style); verifyFormat("int a = aa\n" " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" - " * cccccccccccccccccccccccccccccccccccc;", + " * cccccccccccccccccccccccccccccccccccc;\n", Style); Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; @@ -4044,8 +3044,9 @@ TEST_F(FormatTest, BreaksDesireably) { " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); verifyFormat( - "aaaaaaaa(aaaaaaaaaaaaa, aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n" + "aaaaaaaa(aaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)),\n" " aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)));"); @@ -4063,6 +3064,11 @@ TEST_F(FormatTest, BreaksDesireably) { verifyFormat( "aaaaaa(aaa, new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa));"); + verifyFormat( + "aaaaaa(aaa,\n" + " new Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa),\n" + " aaaa);"); verifyFormat("aaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); @@ -4541,11 +3547,18 @@ TEST_F(FormatTest, ParenthesesAndOperandAlignment) { TEST_F(FormatTest, BreaksConditionalExpressions) { verifyFormat( - "aaaa(aaaaaaaaaaaaaaaaaaaa,\n" + "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat( + "aaaa(aaaaaaaaaa, aaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat( - "aaaa(aaaaaaaaaaaaaaaaaaaa,\n" + "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat( + "aaaa(aaaaaaaaa, aaaaaaaaa,\n" " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " : aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat( @@ -4620,10 +3633,9 @@ TEST_F(FormatTest, BreaksConditionalExpressions) { " aaaaaaaaaaaaaaaaaaaaa\n" " : aaaaaaaaaa;"); verifyFormat( - "aaaaaa = aaaaaaaaaaaa\n" - " ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " : aaaaaaaaaaaaaaaaaaaaaa\n" - " : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); + "aaaaaa = aaaaaaaaaaaa ? aaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " : aaaaaaaaaaaaaaaaaaaaaa\n" + " : aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); FormatStyle NoBinPacking = getLLVMStyle(); NoBinPacking.BinPackArguments = false; @@ -4677,12 +3689,21 @@ TEST_F(FormatTest, BreaksConditionalExpressionsAfterOperator) { Style.BreakBeforeTernaryOperators = false; Style.ColumnLimit = 70; verifyFormat( - "aaaa(aaaaaaaaaaaaaaaaaaaa,\n" + "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", + Style); + verifyFormat( + "aaaa(aaaaaaaaaa, aaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", Style); verifyFormat( - "aaaa(aaaaaaaaaaaaaaaaaaaa,\n" + "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", + Style); + verifyFormat( + "aaaa(aaaaaaaa, aaaaaaaaaa,\n" " aaaaaaa ? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa :\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", Style); @@ -4823,7 +3844,7 @@ TEST_F(FormatTest, AlignsStringLiterals) { EXPECT_EQ("fun + \"1243\" /* comment */\n" " \"5678\";", format("fun + \"1243\" /* comment */\n" - " \"5678\";", + " \"5678\";", getLLVMStyleWithColumns(28))); EXPECT_EQ( "aaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaa \"\n" @@ -5069,9 +4090,9 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { "c\";", Break)); - // Exempt ObjC strings for now. - EXPECT_EQ("NSString *const kString = @\"aaaa\"\n" - " @\"bbbb\";", + EXPECT_EQ("NSString *const kString =\n" + " @\"aaaa\"\n" + " @\"bbbb\";", format("NSString *const kString = @\"aaaa\"\n" "@\"bbbb\";", Break)); @@ -5111,6 +4132,9 @@ TEST_F(FormatTest, AlignsPipes) { verifyFormat( "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat( + "auto Diag = diag() << aaaaaaaaaaaaaaaa(aaaaaaaaaaaa, aaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat("llvm::outs() << \"aaaaaaaaaaaaaaaa: \"\n" " << aaaaaaaa.aaaaaaaaaaaa(aaa)->aaaaaaaaaaaaaa();"); @@ -5425,6 +4449,44 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) { "};"); } +TEST_F(FormatTest, WrapsTemplateParameters) { + FormatStyle Style = getLLVMStyle(); + Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat( + "template <typename... a> struct q {};\n" + "extern q<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" + " y;", + Style); + Style.AlignAfterOpenBracket = FormatStyle::BAS_DontAlign; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; + verifyFormat( + "template <typename... a> struct r {};\n" + "extern r<aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaa>\n" + " y;", + Style); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat( + "template <typename... a> struct s {};\n" + "extern s<\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n" + " y;", + Style); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; + verifyFormat( + "template <typename... a> struct t {};\n" + "extern t<\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaa>\n" + " y;", + Style); +} + TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) { verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" @@ -5450,8 +4512,9 @@ TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) { " aaaaaaaaaaaaaaaaaaaaaaa);"); verifyFormat( - "aaaaaaaaaaaaaaaaaa(aaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + "aaaaaaaaaaaaaaaaaa(aaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa::\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaa);", getLLVMStyleWithColumns(74)); @@ -5893,10 +4956,17 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyFormat("foo<b & 1>();"); verifyFormat("decltype(*::std::declval<const T &>()) void F();"); verifyFormat( + "template <class T, class = typename std::enable_if<\n" + " std::is_integral<T>::value &&\n" + " (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n" + "void F();", + getLLVMStyleWithColumns(70)); + verifyFormat( "template <class T,\n" " class = typename std::enable_if<\n" " std::is_integral<T>::value &&\n" - " (sizeof(T) > 1 || sizeof(T) < 8)>::type>\n" + " (sizeof(T) > 1 || sizeof(T) < 8)>::type,\n" + " class U>\n" "void F();", getLLVMStyleWithColumns(70)); verifyFormat( @@ -5909,6 +4979,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { verifyIndependentOfContext("MACRO(int *i);"); verifyIndependentOfContext("MACRO(auto *a);"); verifyIndependentOfContext("MACRO(const A *a);"); + verifyIndependentOfContext("MACRO(A *const a);"); verifyIndependentOfContext("MACRO('0' <= c && c <= '9');"); verifyFormat("void f() { f(float{1}, a * a); }"); // FIXME: Is there a way to make this work? @@ -6173,6 +5244,11 @@ TEST_F(FormatTest, BreaksLongVariableDeclarations) { " LoooooooooooooooooooooooooooooooooooooooongVariable({});"); verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" " LoooooooooooooooooooooooooooooooooooooongVariable([A a]);"); + + // Lambdas should not confuse the variable declaration heuristic. + verifyFormat("LooooooooooooooooongType\n" + " variable(nullptr, [](A *a) {});", + getLLVMStyleWithColumns(40)); } TEST_F(FormatTest, BreaksLongDeclarations) { @@ -6264,6 +5340,11 @@ TEST_F(FormatTest, BreaksLongDeclarations) { " vector<aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>>\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + + verifyFormat("template <typename T> // Templates on own line.\n" + "static int // Some comment.\n" + "MyFunction(int a);", + getLLVMStyle()); } TEST_F(FormatTest, FormatsArrays) { @@ -6333,6 +5414,11 @@ TEST_F(FormatTest, HandlesIncludeDirectives) { verifyFormat("#define MY_IMPORT <a/b>"); + verifyFormat("#if __has_include(<a/b>)"); + verifyFormat("#if __has_include_next(<a/b>)"); + verifyFormat("#define F __has_include(<a/b>)"); + verifyFormat("#define F __has_include_next(<a/b>)"); + // Protocol buffer definition or missing "#". verifyFormat("import \"aaaaaaaaaaaaaaaaa/aaaaaaaaaaaaaaa\";", getLLVMStyleWithColumns(30)); @@ -6393,7 +5479,7 @@ TEST_F(FormatTest, IncorrectCodeMissingSemicolon) { EXPECT_EQ("namespace N {\n" "void f() {}\n" "void g()\n" - "}", + "} // namespace N", format("namespace N { void f( ) { } void g( ) }")); } @@ -6453,7 +5539,7 @@ TEST_F(FormatTest, DoesNotTouchUnwrappedLinesWithErrors) { verifyIncompleteFormat("namespace {\n" "class Foo { Foo (\n" "};\n" - "} // comment"); + "} // namespace"); } TEST_F(FormatTest, IncorrectCodeErrorDetection) { @@ -6818,7 +5904,10 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { "};"); // Don't create hanging lists. - verifyFormat("someFunction(Param,\n" + verifyFormat("someFunction(Param, {List1, List2,\n" + " List3});", + getLLVMStyleWithColumns(35)); + verifyFormat("someFunction(Param, Param,\n" " {List1, List2,\n" " List3});", getLLVMStyleWithColumns(35)); @@ -7059,188 +6148,6 @@ TEST_F(FormatTest, MergeHandlingInTheFaceOfPreprocessorDirectives) { ShortMergedIf); } -TEST_F(FormatTest, BlockCommentsInControlLoops) { - verifyFormat("if (0) /* a comment in a strange place */ {\n" - " f();\n" - "}"); - verifyFormat("if (0) /* a comment in a strange place */ {\n" - " f();\n" - "} /* another comment */ else /* comment #3 */ {\n" - " g();\n" - "}"); - verifyFormat("while (0) /* a comment in a strange place */ {\n" - " f();\n" - "}"); - verifyFormat("for (;;) /* a comment in a strange place */ {\n" - " f();\n" - "}"); - verifyFormat("do /* a comment in a strange place */ {\n" - " f();\n" - "} /* another comment */ while (0);"); -} - -TEST_F(FormatTest, BlockComments) { - EXPECT_EQ("/* */ /* */ /* */\n/* */ /* */ /* */", - format("/* *//* */ /* */\n/* *//* */ /* */")); - EXPECT_EQ("/* */ a /* */ b;", format(" /* */ a/* */ b;")); - EXPECT_EQ("#define A /*123*/ \\\n" - " b\n" - "/* */\n" - "someCall(\n" - " parameter);", - format("#define A /*123*/ b\n" - "/* */\n" - "someCall(parameter);", - getLLVMStyleWithColumns(15))); - - EXPECT_EQ("#define A\n" - "/* */ someCall(\n" - " parameter);", - format("#define A\n" - "/* */someCall(parameter);", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("/*\n**\n*/", format("/*\n**\n*/")); - EXPECT_EQ("/*\n" - "*\n" - " * aaaaaa\n" - " * aaaaaa\n" - "*/", - format("/*\n" - "*\n" - " * aaaaaa aaaaaa\n" - "*/", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("/*\n" - "**\n" - "* aaaaaa\n" - "*aaaaaa\n" - "*/", - format("/*\n" - "**\n" - "* aaaaaa aaaaaa\n" - "*/", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " /* line 1\n" - " bbbbbbbbbbbb */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", - format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " /* line 1\n" - " bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", - getLLVMStyleWithColumns(50))); - - FormatStyle NoBinPacking = getLLVMStyle(); - NoBinPacking.BinPackParameters = false; - EXPECT_EQ("someFunction(1, /* comment 1 */\n" - " 2, /* comment 2 */\n" - " 3, /* comment 3 */\n" - " aaaa,\n" - " bbbb);", - format("someFunction (1, /* comment 1 */\n" - " 2, /* comment 2 */ \n" - " 3, /* comment 3 */\n" - "aaaa, bbbb );", - NoBinPacking)); - verifyFormat( - "bool aaaaaaaaaaaaa = /* comment: */ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); - EXPECT_EQ( - "bool aaaaaaaaaaaaa = /* trailing comment */\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;", - format( - "bool aaaaaaaaaaaaa = /* trailing comment */\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;")); - EXPECT_EQ( - "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" - "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" - "int cccccccccccccccccccccccccccccc; /* comment */\n", - format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" - "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" - "int cccccccccccccccccccccccccccccc; /* comment */\n")); - - verifyFormat("void f(int * /* unused */) {}"); - - EXPECT_EQ("/*\n" - " **\n" - " */", - format("/*\n" - " **\n" - " */")); - EXPECT_EQ("/*\n" - " *q\n" - " */", - format("/*\n" - " *q\n" - " */")); - EXPECT_EQ("/*\n" - " * q\n" - " */", - format("/*\n" - " * q\n" - " */")); - EXPECT_EQ("/*\n" - " **/", - format("/*\n" - " **/")); - EXPECT_EQ("/*\n" - " ***/", - format("/*\n" - " ***/")); -} - -TEST_F(FormatTest, BlockCommentsInMacros) { - EXPECT_EQ("#define A \\\n" - " { \\\n" - " /* one line */ \\\n" - " someCall();", - format("#define A { \\\n" - " /* one line */ \\\n" - " someCall();", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define A \\\n" - " { \\\n" - " /* previous */ \\\n" - " /* one line */ \\\n" - " someCall();", - format("#define A { \\\n" - " /* previous */ \\\n" - " /* one line */ \\\n" - " someCall();", - getLLVMStyleWithColumns(20))); -} - -TEST_F(FormatTest, BlockCommentsAtEndOfLine) { - EXPECT_EQ("a = {\n" - " 1111 /* */\n" - "};", - format("a = {1111 /* */\n" - "};", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("a = {\n" - " 1111 /* */\n" - "};", - format("a = {1111 /* */\n" - "};", - getLLVMStyleWithColumns(15))); - - // FIXME: The formatting is still wrong here. - EXPECT_EQ("a = {\n" - " 1111 /* a\n" - " */\n" - "};", - format("a = {1111 /* a */\n" - "};", - getLLVMStyleWithColumns(15))); -} - -TEST_F(FormatTest, IndentLineCommentsInStartOfBlockAtEndOfFile) { - verifyFormat("{\n" - " // a\n" - " // b"); -} - TEST_F(FormatTest, FormatStarDependingOnContext) { verifyFormat("void f(int *a);"); verifyFormat("void f() { f(fint * b); }"); @@ -7252,8 +6159,8 @@ TEST_F(FormatTest, FormatStarDependingOnContext) { " void f() {}\n" " int *a;\n" "};\n" - "}\n" - "}"); + "} // namespace b\n" + "} // namespace a"); } TEST_F(FormatTest, SpecialTokensAtEndOfLine) { @@ -7553,6 +6460,7 @@ TEST_F(FormatTest, BreaksWideAndNSStringLiterals) { EXPECT_EQ("@\"NSString \"\n" "@\"literal\";", format("@\"NSString literal\";", getGoogleStyleWithColumns(19))); + verifyFormat(R"(NSString *s = @"那那那那";)", getLLVMStyleWithColumns(26)); // This input makes clang-format try to split the incomplete unicode escape // sequence, which used to lead to a crasher. @@ -7578,8 +6486,9 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { "_T(\"aaaaaaaaaaaaaa\")\n" "_T(\"aaaaaaaaaaaa\")", format(" _T(\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")", Style)); - EXPECT_EQ("f(x, _T(\"aaaaaaaaa\")\n" - " _T(\"aaaaaa\"),\n" + EXPECT_EQ("f(x,\n" + " _T(\"aaaaaaaaaaaa\")\n" + " _T(\"aaa\"),\n" " z);", format("f(x, _T(\"aaaaaaaaaaaaaaa\"), z);", Style)); @@ -7611,6 +6520,90 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { "_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\"));")); } +TEST_F(FormatTest, BreaksStringLiteralOperands) { + // In a function call with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("func(a, \"long long \"\n" + " \"long long\");", + format("func(a, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the second must be broken with a + // line break before it. + EXPECT_EQ("func(a,\n" + " \"long long long \"\n" + " \"long\",\n" + " c);", + format("func(a, \"long long long long\", c);", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, the third must be broken with a + // line break before it. + EXPECT_EQ("func(a, b,\n" + " \"long long long \"\n" + " \"long\");", + format("func(a, b, \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a function call with three operands, both the second and the third must + // be broken with a line break before them. + EXPECT_EQ("func(a,\n" + " \"long long long \"\n" + " \"long\",\n" + " \"long long long \"\n" + " \"long\");", + format("func(a, \"long long long long\", \"long long long long\");", + getLLVMStyleWithColumns(24))); + // In a chain of << with two operands, the second can be broken with no line + // break before it. + EXPECT_EQ("a << \"line line \"\n" + " \"line\";", + format("a << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it. + EXPECT_EQ("abcde << \"line \"\n" + " \"line line\"\n" + " << c;", + format("abcde << \"line line line\" << c;", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the third must be broken with a line + // break before it. + EXPECT_EQ("a << b\n" + " << \"line line \"\n" + " \"line\";", + format("a << b << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of << with three operands, the second can be broken with no line + // break before it and the third must be broken with a line break before it. + EXPECT_EQ("abcd << \"line line \"\n" + " \"line\"\n" + " << \"line line \"\n" + " \"line\";", + format("abcd << \"line line line\" << \"line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of binary operators with two operands, the second can be broken + // with no line break before it. + EXPECT_EQ("abcd + \"line line \"\n" + " \"line line\";", + format("abcd + \"line line line line\";", + getLLVMStyleWithColumns(20))); + // In a chain of binary operators with three operands, the second must be + // broken with a line break before it. + EXPECT_EQ("abcd +\n" + " \"line line \"\n" + " \"line line\" +\n" + " e;", + format("abcd + \"line line line line\" + e;", + getLLVMStyleWithColumns(20))); + // In a function call with two operands, with AlignAfterOpenBracket enabled, + // the first must be broken with a line break before it. + FormatStyle Style = getLLVMStyleWithColumns(25); + Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; + EXPECT_EQ("someFunction(\n" + " \"long long long \"\n" + " \"long\",\n" + " a);", + format("someFunction(\"long long long long\", a);", Style)); +} + TEST_F(FormatTest, DontSplitStringLiteralsWithEscapedNewlines) { EXPECT_EQ( "aaaaaaaaaaa = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" @@ -8680,12 +7673,11 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { "};", Alignment); - // FIXME: Should align all three assignments verifyFormat( "int i = 1;\n" "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" " loooooooooooooooooooooongParameterB);\n" - "int j = 2;", + "int j = 2;", Alignment); verifyFormat("template <typename T, typename T_0 = very_long_type_name_0,\n" @@ -8700,6 +7692,13 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) { verifyFormat("int aa = ((1 > 2) ? 3 : 4);\n" "float b[1][] = {{3.f}};\n", Alignment); + verifyFormat("for (int i = 0; i < 1; i++)\n" + " int x = 1;\n", + Alignment); + verifyFormat("for (i = 0; i < 1; i++)\n" + " x = 1;\n" + "y = 1;\n", + Alignment); } TEST_F(FormatTest, AlignConsecutiveDeclarations) { @@ -8767,7 +7766,57 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { "unsigned oneTwoThree = 123;\n" "int oneTwo = 12;", Alignment)); + // Function prototype alignment + verifyFormat("int a();\n" + "double b();", + Alignment); + verifyFormat("int a(int x);\n" + "double b();", + Alignment); + unsigned OldColumnLimit = Alignment.ColumnLimit; + // We need to set ColumnLimit to zero, in order to stress nested alignments, + // otherwise the function parameters will be re-flowed onto a single line. + Alignment.ColumnLimit = 0; + EXPECT_EQ("int a(int x,\n" + " float y);\n" + "double b(int x,\n" + " double y);", + format("int a(int x,\n" + " float y);\n" + "double b(int x,\n" + " double y);", + Alignment)); + // This ensures that function parameters of function declarations are + // correctly indented when their owning functions are indented. + // The failure case here is for 'double y' to not be indented enough. + EXPECT_EQ("double a(int x);\n" + "int b(int y,\n" + " double z);", + format("double a(int x);\n" + "int b(int y,\n" + " double z);", + Alignment)); + // Set ColumnLimit low so that we induce wrapping immediately after + // the function name and opening paren. + Alignment.ColumnLimit = 13; + verifyFormat("int function(\n" + " int x,\n" + " bool y);", + Alignment); + Alignment.ColumnLimit = OldColumnLimit; + // Ensure function pointers don't screw up recursive alignment + verifyFormat("int a(int x, void (*fp)(int y));\n" + "double b();", + Alignment); Alignment.AlignConsecutiveAssignments = true; + // Ensure recursive alignment is broken by function braces, so that the + // "a = 1" does not align with subsequent assignments inside the function + // body. + verifyFormat("int func(int a = 1) {\n" + " int b = 2;\n" + " int cc = 3;\n" + "}", + Alignment); verifyFormat("float something = 2000;\n" "double another = 911;\n" "int i = 1, j = 10;\n" @@ -8777,6 +7826,28 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { verifyFormat("int oneTwoThree = {0}; // comment\n" "unsigned oneTwo = 0; // comment", Alignment); + // Make sure that scope is correctly tracked, in the absence of braces + verifyFormat("for (int i = 0; i < n; i++)\n" + " j = i;\n" + "double x = 1;\n", + Alignment); + verifyFormat("if (int i = 0)\n" + " j = i;\n" + "double x = 1;\n", + Alignment); + // Ensure operator[] and operator() are comprehended + verifyFormat("struct test {\n" + " long long int foo();\n" + " int operator[](int a);\n" + " double bar();\n" + "};\n", + Alignment); + verifyFormat("struct test {\n" + " long long int foo();\n" + " int operator()(int a);\n" + " double bar();\n" + "};\n", + Alignment); EXPECT_EQ("void SomeFunction(int parameter = 0) {\n" " int const i = 1;\n" " int * j = 2;\n" @@ -8878,17 +7949,16 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) { Alignment); Alignment.AlignConsecutiveAssignments = false; - // FIXME: Should align all three declarations verifyFormat( "int i = 1;\n" "SomeType a = SomeFunction(looooooooooooooooooooooongParameterA,\n" " loooooooooooooooooooooongParameterB);\n" - "int j = 2;", + "int j = 2;", Alignment); // Test interactions with ColumnLimit and AlignConsecutiveAssignments: // We expect declarations and assignments to align, as long as it doesn't - // exceed the column limit, starting a new alignemnt sequence whenever it + // exceed the column limit, starting a new alignment sequence whenever it // happens. Alignment.AlignConsecutiveAssignments = true; Alignment.ColumnLimit = 30; @@ -8987,6 +8057,7 @@ TEST_F(FormatTest, LinuxBraceBreaking) { TEST_F(FormatTest, MozillaBraceBreaking) { FormatStyle MozillaBraceStyle = getLLVMStyle(); MozillaBraceStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla; + MozillaBraceStyle.FixNamespaceComments = false; verifyFormat("namespace a {\n" "class A\n" "{\n" @@ -9045,7 +8116,7 @@ TEST_F(FormatTest, StroustrupBraceBreaking) { "struct B {\n" " int x;\n" "};\n" - "}\n", + "} // namespace a\n", StroustrupBraceStyle); verifyFormat("void foo()\n" @@ -9231,7 +8302,14 @@ TEST_F(FormatTest, AllmanBraceBreaking) { // .. or dict literals. verifyFormat("void f()\n" "{\n" - " [object someMethod:@{ @\"a\" : @\"b\" }];\n" + " // ...\n" + " [object someMethod:@{@\"a\" : @\"b\"}];\n" + "}", + AllmanBraceStyle); + verifyFormat("void f()\n" + "{\n" + " // ...\n" + " [object someMethod:@{a : @\"b\"}];\n" "}", AllmanBraceStyle); verifyFormat("int f()\n" @@ -9403,6 +8481,7 @@ TEST_F(FormatTest, GNUBraceBreaking) { TEST_F(FormatTest, WebKitBraceBreaking) { FormatStyle WebKitBraceStyle = getLLVMStyle(); WebKitBraceStyle.BreakBeforeBraces = FormatStyle::BS_WebKit; + WebKitBraceStyle.FixNamespaceComments = false; verifyFormat("namespace a {\n" "class A {\n" " void f()\n" @@ -9602,6 +8681,7 @@ TEST_F(FormatTest, ParsesConfigurationBools) { CHECK_PARSE_BOOL(BreakBeforeTernaryOperators); CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma); CHECK_PARSE_BOOL(BreakStringLiterals); + CHECK_PARSE_BOOL(BreakBeforeInheritanceComma) CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine); CHECK_PARSE_BOOL(DerivePointerAlignment); CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); @@ -10403,10 +9483,11 @@ TEST_F(FormatTest, FormatsLambdas) { " << std::count_if(v.begin(), v.end(), [](int x) {\n" " return x == 2; // force break\n" " });"); - verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa([=](\n" - " int iiiiiiiiiiii) {\n" - " return aaaaaaaaaaaaaaaaaaaaaaa != aaaaaaaaaaaaaaaaaaaaaaa;\n" - "});", + verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " [=](int iiiiiiiiiiii) {\n" + " return aaaaaaaaaaaaaaaaaaaaaaa !=\n" + " aaaaaaaaaaaaaaaaaaaaaaa;\n" + " });", getLLVMStyleWithColumns(60)); verifyFormat("SomeFunction({[&] {\n" " // comment\n" @@ -10492,6 +9573,15 @@ TEST_F(FormatTest, FormatsLambdas) { "#endif\n" " ;\n" "};"); + + // Lambdas with complex multiline introducers. + verifyFormat( + "aaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]()\n" + " -> ::std::unordered_set<\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n" + " //\n" + " });"); } TEST_F(FormatTest, FormatsBlocks) { @@ -10919,6 +10009,26 @@ TEST_F(FormatTest, DisableRegions) { " int j;\n" " /* clang-format on */\n" " int k;")); + + // Don't reflow comments within disabled regions. + EXPECT_EQ( + "// clang-format off\n" + "// long long long long long long line\n" + "/* clang-format on */\n" + "/* long long long\n" + " * long long long\n" + " * line */\n" + "int i;\n" + "/* clang-format off */\n" + "/* long long long long long long line */\n", + format("// clang-format off\n" + "// long long long long long long line\n" + "/* clang-format on */\n" + "/* long long long long long long line */\n" + "int i;\n" + "/* clang-format off */\n" + "/* long long long long long long line */\n", + getLLVMStyleWithColumns(20))); } TEST_F(FormatTest, DoNotCrashOnInvalidInput) { @@ -10952,6 +10062,10 @@ TEST_F(FormatTest, ArrayAsTemplateType) { format("auto a = unique_ptr < Foo < Bar>[10]> ;", Spaces)); } +TEST_F(FormatTest, NoSpaceAfterSuper) { + verifyFormat("__super::FooBar();"); +} + TEST(FormatStyle, GetStyleOfFile) { vfs::InMemoryFileSystem FS; // Test 1: format file in the same directory. @@ -10961,13 +10075,33 @@ TEST(FormatStyle, GetStyleOfFile) { ASSERT_TRUE( FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS); - ASSERT_EQ(Style1, getLLVMStyle()); + ASSERT_TRUE((bool)Style1); + ASSERT_EQ(*Style1, getLLVMStyle()); - // Test 2: fallback to default. + // Test 2.1: fallback to default. ASSERT_TRUE( FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS); - ASSERT_EQ(Style2, getMozillaStyle()); + ASSERT_TRUE((bool)Style2); + ASSERT_EQ(*Style2, getMozillaStyle()); + + // Test 2.2: no format on 'none' fallback style. + Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS); + ASSERT_TRUE((bool)Style2); + ASSERT_EQ(*Style2, getNoStyle()); + + // Test 2.3: format if config is found with no based style while fallback is + // 'none'. + ASSERT_TRUE(FS.addFile("/b/.clang-format", 0, + llvm::MemoryBuffer::getMemBuffer("IndentWidth: 2"))); + Style2 = getStyle("file", "/b/test.cpp", "none", "", &FS); + ASSERT_TRUE((bool)Style2); + ASSERT_EQ(*Style2, getLLVMStyle()); + + // Test 2.4: format if yaml with no based style, while fallback is 'none'. + Style2 = getStyle("{}", "a.h", "none", "", &FS); + ASSERT_TRUE((bool)Style2); + ASSERT_EQ(*Style2, getLLVMStyle()); // Test 3: format file in parent directory. ASSERT_TRUE( @@ -10976,7 +10110,34 @@ TEST(FormatStyle, GetStyleOfFile) { ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS); - ASSERT_EQ(Style3, getGoogleStyle()); + ASSERT_TRUE((bool)Style3); + ASSERT_EQ(*Style3, getGoogleStyle()); + + // Test 4: error on invalid fallback style + auto Style4 = getStyle("file", "a.h", "KungFu", "", &FS); + ASSERT_FALSE((bool)Style4); + llvm::consumeError(Style4.takeError()); + + // Test 5: error on invalid yaml on command line + auto Style5 = getStyle("{invalid_key=invalid_value}", "a.h", "LLVM", "", &FS); + ASSERT_FALSE((bool)Style5); + llvm::consumeError(Style5.takeError()); + + // Test 6: error on invalid style + auto Style6 = getStyle("KungFu", "a.h", "LLVM", "", &FS); + ASSERT_FALSE((bool)Style6); + llvm::consumeError(Style6.takeError()); + + // Test 7: found config file, error on parsing it + ASSERT_TRUE( + FS.addFile("/d/.clang-format", 0, + llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM\n" + "InvalidKey: InvalidValue"))); + ASSERT_TRUE( + FS.addFile("/d/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;"))); + auto Style7 = getStyle("file", "/d/.clang-format", "LLVM", "", &FS); + ASSERT_FALSE((bool)Style7); + llvm::consumeError(Style7.takeError()); } TEST_F(ReplacementTest, FormatCodeAfterReplacements) { @@ -11042,17 +10203,19 @@ TEST_F(ReplacementTest, SortIncludesAfterReplacement) { EXPECT_EQ(Expected, *Result); } -TEST_F(FormatTest, AllignTrailingComments) { - EXPECT_EQ("#define MACRO(V) \\\n" - " V(Rt2) /* one more char */ \\\n" - " V(Rs) /* than here */ \\\n" - "/* comment 3 */\n", - format("#define MACRO(V)\\\n" - "V(Rt2) /* one more char */ \\\n" - "V(Rs) /* than here */ \\\n" - "/* comment 3 */ \\\n", - getLLVMStyleWithColumns(40))); +TEST_F(FormatTest, UTF8CharacterLiteralCpp03) { + format::FormatStyle Style = format::getLLVMStyle(); + Style.Standard = FormatStyle::LS_Cpp03; + // cpp03 recognize this string as identifier u8 and literal character 'a' + EXPECT_EQ("auto c = u8 'a';", format("auto c = u8'a';", Style)); } + +TEST_F(FormatTest, UTF8CharacterLiteralCpp11) { + // u8'a' is a C++17 feature, utf8 literal character, LS_Cpp11 covers + // all modes, including C++11, C++14 and C++17 + EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';")); +} + } // end namespace } // end namespace format } // end namespace clang diff --git a/unittests/Format/FormatTestComments.cpp b/unittests/Format/FormatTestComments.cpp new file mode 100644 index 000000000000..df24abe26125 --- /dev/null +++ b/unittests/Format/FormatTestComments.cpp @@ -0,0 +1,2373 @@ +//===- unittest/Format/FormatTestComments.cpp - Formatting unit tests -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Format/Format.h" + +#include "../Tooling/ReplacementTest.h" +#include "FormatTestUtils.h" + +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/MemoryBuffer.h" +#include "gtest/gtest.h" + +#define DEBUG_TYPE "format-test" + +using clang::tooling::ReplacementTest; + +namespace clang { +namespace format { +namespace { + +FormatStyle getGoogleStyle() { return getGoogleStyle(FormatStyle::LK_Cpp); } + +class FormatTestComments : public ::testing::Test { +protected: + enum IncompleteCheck { + IC_ExpectComplete, + IC_ExpectIncomplete, + IC_DoNotCheck + }; + + std::string format(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle(), + IncompleteCheck CheckIncomplete = IC_ExpectComplete) { + DEBUG(llvm::errs() << "---\n"); + DEBUG(llvm::errs() << Code << "\n\n"); + std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); + bool IncompleteFormat = false; + tooling::Replacements Replaces = + reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat); + if (CheckIncomplete != IC_DoNotCheck) { + bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete; + EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n"; + } + ReplacementCount = Replaces.size(); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast<bool>(Result)); + DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { + FormatStyle Style = getLLVMStyle(); + Style.ColumnLimit = ColumnLimit; + return Style; + } + + void verifyFormat(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); + } + + void verifyGoogleFormat(llvm::StringRef Code) { + verifyFormat(Code, getGoogleStyle()); + } + + /// \brief Verify that clang-format does not crash on the given input. + void verifyNoCrash(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + format(Code, Style, IC_DoNotCheck); + } + + int ReplacementCount; +}; + +//===----------------------------------------------------------------------===// +// Tests for comments. +//===----------------------------------------------------------------------===// + +TEST_F(FormatTestComments, UnderstandsSingleLineComments) { + verifyFormat("//* */"); + verifyFormat("// line 1\n" + "// line 2\n" + "void f() {}\n"); + + verifyFormat("void f() {\n" + " // Doesn't do anything\n" + "}"); + verifyFormat("SomeObject\n" + " // Calling someFunction on SomeObject\n" + " .someFunction();"); + verifyFormat("auto result = SomeObject\n" + " // Calling someFunction on SomeObject\n" + " .someFunction();"); + verifyFormat("void f(int i, // some comment (probably for i)\n" + " int j, // some comment (probably for j)\n" + " int k); // some comment (probably for k)"); + verifyFormat("void f(int i,\n" + " // some comment (probably for j)\n" + " int j,\n" + " // some comment (probably for k)\n" + " int k);"); + + verifyFormat("int i // This is a fancy variable\n" + " = 5; // with nicely aligned comment."); + + verifyFormat("// Leading comment.\n" + "int a; // Trailing comment."); + verifyFormat("int a; // Trailing comment\n" + " // on 2\n" + " // or 3 lines.\n" + "int b;"); + verifyFormat("int a; // Trailing comment\n" + "\n" + "// Leading comment.\n" + "int b;"); + verifyFormat("int a; // Comment.\n" + " // More details.\n" + "int bbbb; // Another comment."); + verifyFormat( + "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; // comment\n" + "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // comment\n" + "int cccccccccccccccccccccccccccccc; // comment\n" + "int ddd; // looooooooooooooooooooooooong comment\n" + "int aaaaaaaaaaaaaaaaaaaaaaa; // comment\n" + "int bbbbbbbbbbbbbbbbbbbbb; // comment\n" + "int ccccccccccccccccccc; // comment"); + + verifyFormat("#include \"a\" // comment\n" + "#include \"a/b/c\" // comment"); + verifyFormat("#include <a> // comment\n" + "#include <a/b/c> // comment"); + EXPECT_EQ("#include \"a\" // comment\n" + "#include \"a/b/c\" // comment", + format("#include \\\n" + " \"a\" // comment\n" + "#include \"a/b/c\" // comment")); + + verifyFormat("enum E {\n" + " // comment\n" + " VAL_A, // comment\n" + " VAL_B\n" + "};"); + + EXPECT_EQ("enum A {\n" + " // line a\n" + " a,\n" + " b, // line b\n" + "\n" + " // line c\n" + " c\n" + "};", + format("enum A {\n" + " // line a\n" + " a,\n" + " b, // line b\n" + "\n" + " // line c\n" + " c\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + format("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + getLLVMStyleWithColumns(20))); + verifyFormat( + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment"); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " // Comment inside a statement.\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;"); + verifyFormat("SomeFunction(a,\n" + " // comment\n" + " b + x);"); + verifyFormat("SomeFunction(a, a,\n" + " // comment\n" + " b + x);"); + verifyFormat( + "bool aaaaaaaaaaaaa = // comment\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); + + verifyFormat("int aaaa; // aaaaa\n" + "int aa; // aaaaaaa", + getLLVMStyleWithColumns(20)); + + EXPECT_EQ("void f() { // This does something ..\n" + "}\n" + "int a; // This is unrelated", + format("void f() { // This does something ..\n" + " }\n" + "int a; // This is unrelated")); + EXPECT_EQ("class C {\n" + " void f() { // This does something ..\n" + " } // awesome..\n" + "\n" + " int a; // This is unrelated\n" + "};", + format("class C{void f() { // This does something ..\n" + " } // awesome..\n" + " \n" + "int a; // This is unrelated\n" + "};")); + + EXPECT_EQ("int i; // single line trailing comment", + format("int i;\\\n// single line trailing comment")); + + verifyGoogleFormat("int a; // Trailing comment."); + + verifyFormat("someFunction(anotherFunction( // Force break.\n" + " parameter));"); + + verifyGoogleFormat("#endif // HEADER_GUARD"); + + verifyFormat("const char *test[] = {\n" + " // A\n" + " \"aaaa\",\n" + " // B\n" + " \"aaaaa\"};"); + verifyGoogleFormat( + "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaaaaaa); // 81_cols_with_this_comment"); + EXPECT_EQ("D(a, {\n" + " // test\n" + " int a;\n" + "});", + format("D(a, {\n" + "// test\n" + "int a;\n" + "});")); + + EXPECT_EQ("lineWith(); // comment\n" + "// at start\n" + "otherLine();", + format("lineWith(); // comment\n" + "// at start\n" + "otherLine();")); + EXPECT_EQ("lineWith(); // comment\n" + "/*\n" + " * at start */\n" + "otherLine();", + format("lineWith(); // comment\n" + "/*\n" + " * at start */\n" + "otherLine();")); + EXPECT_EQ("lineWith(); // comment\n" + " // at start\n" + "otherLine();", + format("lineWith(); // comment\n" + " // at start\n" + "otherLine();")); + + EXPECT_EQ("lineWith(); // comment\n" + "// at start\n" + "otherLine(); // comment", + format("lineWith(); // comment\n" + "// at start\n" + "otherLine(); // comment")); + EXPECT_EQ("lineWith();\n" + "// at start\n" + "otherLine(); // comment", + format("lineWith();\n" + " // at start\n" + "otherLine(); // comment")); + EXPECT_EQ("// first\n" + "// at start\n" + "otherLine(); // comment", + format("// first\n" + " // at start\n" + "otherLine(); // comment")); + EXPECT_EQ("f();\n" + "// first\n" + "// at start\n" + "otherLine(); // comment", + format("f();\n" + "// first\n" + " // at start\n" + "otherLine(); // comment")); + verifyFormat("f(); // comment\n" + "// first\n" + "// at start\n" + "otherLine();"); + EXPECT_EQ("f(); // comment\n" + "// first\n" + "// at start\n" + "otherLine();", + format("f(); // comment\n" + "// first\n" + " // at start\n" + "otherLine();")); + EXPECT_EQ("f(); // comment\n" + " // first\n" + "// at start\n" + "otherLine();", + format("f(); // comment\n" + " // first\n" + "// at start\n" + "otherLine();")); + EXPECT_EQ("void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}", + format("void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}")); + EXPECT_EQ("int xy; // a\n" + "int z; // b", + format("int xy; // a\n" + "int z; //b")); + EXPECT_EQ("int xy; // a\n" + "int z; // bb", + format("int xy; // a\n" + "int z; //bb", + getLLVMStyleWithColumns(12))); + + verifyFormat("#define A \\\n" + " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" + " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", + getLLVMStyleWithColumns(60)); + verifyFormat( + "#define A \\\n" + " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" + " int jjjjjjjjjjjjjjjjjjjjjjjj; /* */", + getLLVMStyleWithColumns(61)); + + verifyFormat("if ( // This is some comment\n" + " x + 3) {\n" + "}"); + EXPECT_EQ("if ( // This is some comment\n" + " // spanning two lines\n" + " x + 3) {\n" + "}", + format("if( // This is some comment\n" + " // spanning two lines\n" + " x + 3) {\n" + "}")); + + verifyNoCrash("/\\\n/"); + verifyNoCrash("/\\\n* */"); + // The 0-character somehow makes the lexer return a proper comment. + verifyNoCrash(StringRef("/*\\\0\n/", 6)); +} + +TEST_F(FormatTestComments, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { + EXPECT_EQ("SomeFunction(a,\n" + " b, // comment\n" + " c);", + format("SomeFunction(a,\n" + " b, // comment\n" + " c);")); + EXPECT_EQ("SomeFunction(a, b,\n" + " // comment\n" + " c);", + format("SomeFunction(a,\n" + " b,\n" + " // comment\n" + " c);")); + EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n" + " c);", + format("SomeFunction(a, b, // comment (unclear relation)\n" + " c);")); + EXPECT_EQ("SomeFunction(a, // comment\n" + " b,\n" + " c); // comment", + format("SomeFunction(a, // comment\n" + " b,\n" + " c); // comment")); + EXPECT_EQ("aaaaaaaaaa(aaaa(aaaa,\n" + " aaaa), //\n" + " aaaa, bbbbb);", + format("aaaaaaaaaa(aaaa(aaaa,\n" + "aaaa), //\n" + "aaaa, bbbbb);")); +} + +TEST_F(FormatTestComments, RemovesTrailingWhitespaceOfComments) { + EXPECT_EQ("// comment", format("// comment ")); + EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment", + format("int aaaaaaa, bbbbbbb; // comment ", + getLLVMStyleWithColumns(33))); + EXPECT_EQ("// comment\\\n", format("// comment\\\n \t \v \f ")); + EXPECT_EQ("// comment \\\n", format("// comment \\\n \t \v \f ")); +} + +TEST_F(FormatTestComments, UnderstandsBlockComments) { + verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);"); + verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }"); + EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbb);", + format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n" + "/* Trailing comment for aa... */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbb);")); + EXPECT_EQ( + "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);", + format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n" + "/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);")); + EXPECT_EQ( + "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" + "}", + format("void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" + " aaaaaaaaaaaaaaaaaa ,\n" + " aaaaaaaaaaaaaaaaaa) { /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n" + "}")); + verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + + FormatStyle NoBinPacking = getLLVMStyle(); + NoBinPacking.BinPackParameters = false; + verifyFormat("aaaaaaaa(/* parameter 1 */ aaaaaa,\n" + " /* parameter 2 */ aaaaaa,\n" + " /* parameter 3 */ aaaaaa,\n" + " /* parameter 4 */ aaaaaa);", + NoBinPacking); + + // Aligning block comments in macros. + verifyGoogleFormat("#define A \\\n" + " int i; /*a*/ \\\n" + " int jjj; /*b*/"); +} + +TEST_F(FormatTestComments, AlignsBlockComments) { + EXPECT_EQ("/*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + "void f() {}", + format(" /*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + " void f() {}")); + EXPECT_EQ("class C {\n" + " /*\n" + " * Another multi-line\n" + " * comment.\n" + " */\n" + " void f() {}\n" + "};", + format("class C {\n" + "/*\n" + " * Another multi-line\n" + " * comment.\n" + " */\n" + "void f() {}\n" + "};")); + EXPECT_EQ("/*\n" + " 1. This is a comment with non-trivial formatting.\n" + " 1.1. We have to indent/outdent all lines equally\n" + " 1.1.1. to keep the formatting.\n" + " */", + format(" /*\n" + " 1. This is a comment with non-trivial formatting.\n" + " 1.1. We have to indent/outdent all lines equally\n" + " 1.1.1. to keep the formatting.\n" + " */")); + EXPECT_EQ("/*\n" + "Don't try to outdent if there's not enough indentation.\n" + "*/", + format(" /*\n" + " Don't try to outdent if there's not enough indentation.\n" + " */")); + + EXPECT_EQ("int i; /* Comment with empty...\n" + " *\n" + " * line. */", + format("int i; /* Comment with empty...\n" + " *\n" + " * line. */")); + EXPECT_EQ("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment 1 */\n" + "int baz = 0; /* multiline\n" + " comment 2 */\n" + "int bzz = 0; /* multiline\n" + " comment 3 */", + format("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment 1 */\n" + "int baz = 0; /* multiline\n" + " comment 2 */\n" + "int bzz = 0; /* multiline\n" + " comment 3 */")); + EXPECT_EQ("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment */\n" + "int baz = 0; /* multiline\n" + "comment */", + format("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + "comment */\n" + "int baz = 0; /* multiline\n" + "comment */")); +} + +TEST_F(FormatTestComments, CommentReflowingCanBeTurnedOff) { + FormatStyle Style = getLLVMStyleWithColumns(20); + Style.ReflowComments = false; + verifyFormat("// aaaaaaaaa aaaaaaaaaa aaaaaaaaaa", Style); + verifyFormat("/* aaaaaaaaa aaaaaaaaaa aaaaaaaaaa */", Style); +} + +TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) { + EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */", + format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */")); + EXPECT_EQ( + "void ffffffffffff(\n" + " int aaaaaaaa, int bbbbbbbb,\n" + " int cccccccccccc) { /*\n" + " aaaaaaaaaa\n" + " aaaaaaaaaaaaa\n" + " bbbbbbbbbbbbbb\n" + " bbbbbbbbbb\n" + " */\n" + "}", + format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n" + "{ /*\n" + " aaaaaaaaaa aaaaaaaaaaaaa\n" + " bbbbbbbbbbbbbb bbbbbbbbbb\n" + " */\n" + "}", + getLLVMStyleWithColumns(40))); +} + +TEST_F(FormatTestComments, DontBreakNonTrailingBlockComments) { + EXPECT_EQ("void ffffffffff(\n" + " int aaaaa /* test */);", + format("void ffffffffff(int aaaaa /* test */);", + getLLVMStyleWithColumns(35))); +} + +TEST_F(FormatTestComments, SplitsLongCxxComments) { + EXPECT_EQ("// A comment that\n" + "// doesn't fit on\n" + "// one line", + format("// A comment that doesn't fit on one line", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/// A comment that\n" + "/// doesn't fit on\n" + "/// one line", + format("/// A comment that doesn't fit on one line", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("//! A comment that\n" + "//! doesn't fit on\n" + "//! one line", + format("//! A comment that doesn't fit on one line", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// a b c d\n" + "// e f g\n" + "// h i j k", + format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); + EXPECT_EQ( + "// a b c d\n" + "// e f g\n" + "// h i j k", + format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); + EXPECT_EQ("if (true) // A comment that\n" + " // doesn't fit on\n" + " // one line", + format("if (true) // A comment that doesn't fit on one line ", + getLLVMStyleWithColumns(30))); + EXPECT_EQ("// Don't_touch_leading_whitespace", + format("// Don't_touch_leading_whitespace", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// Add leading\n" + "// whitespace", + format("//Add leading whitespace", getLLVMStyleWithColumns(20))); + EXPECT_EQ("/// Add leading\n" + "/// whitespace", + format("///Add leading whitespace", getLLVMStyleWithColumns(20))); + EXPECT_EQ("//! Add leading\n" + "//! whitespace", + format("//!Add leading whitespace", getLLVMStyleWithColumns(20))); + EXPECT_EQ("// whitespace", format("//whitespace", getLLVMStyle())); + EXPECT_EQ("// Even if it makes the line exceed the column\n" + "// limit", + format("//Even if it makes the line exceed the column limit", + getLLVMStyleWithColumns(51))); + EXPECT_EQ("//--But not here", format("//--But not here", getLLVMStyle())); + EXPECT_EQ("/// line 1\n" + "// add leading whitespace", + format("/// line 1\n" + "//add leading whitespace", + getLLVMStyleWithColumns(30))); + EXPECT_EQ("/// line 1\n" + "/// line 2\n" + "//! line 3\n" + "//! line 4\n" + "//! line 5\n" + "// line 6\n" + "// line 7", + format("///line 1\n" + "///line 2\n" + "//! line 3\n" + "//!line 4\n" + "//!line 5\n" + "// line 6\n" + "//line 7", getLLVMStyleWithColumns(20))); + + EXPECT_EQ("// aa bb cc dd", + format("// aa bb cc dd ", + getLLVMStyleWithColumns(15))); + + EXPECT_EQ("// A comment before\n" + "// a macro\n" + "// definition\n" + "#define a b", + format("// A comment before a macro definition\n" + "#define a b", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("void ffffff(\n" + " int aaaaaaaaa, // wwww\n" + " int bbbbbbbbbb, // xxxxxxx\n" + " // yyyyyyyyyy\n" + " int c, int d, int e) {}", + format("void ffffff(\n" + " int aaaaaaaaa, // wwww\n" + " int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n" + " int c, int d, int e) {}", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + format("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "#define XXX // a b c d\n" + " // e f g h", + format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22))); + EXPECT_EQ( + "#define XXX // q w e r\n" + " // t y u i", + format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22))); + EXPECT_EQ("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4\n" + " // 5\n" + "}", + format("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5\n" + "}", + getLLVMStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, PreservesHangingIndentInCxxComments) { + EXPECT_EQ("// A comment\n" + "// that doesn't\n" + "// fit on one\n" + "// line", + format("// A comment that doesn't fit on one line", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/// A comment\n" + "/// that doesn't\n" + "/// fit on one\n" + "/// line", + format("/// A comment that doesn't fit on one line", + getLLVMStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, DontSplitLineCommentsWithEscapedNewlines) { + EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); + EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + getLLVMStyleWithColumns(50))); + // FIXME: One day we might want to implement adjustment of leading whitespace + // of the consecutive lines in this kind of comment: + EXPECT_EQ("double\n" + " a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + format("double a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + getLLVMStyleWithColumns(49))); +} + +TEST_F(FormatTestComments, DontSplitLineCommentsWithPragmas) { + FormatStyle Pragmas = getLLVMStyleWithColumns(30); + Pragmas.CommentPragmas = "^ IWYU pragma:"; + EXPECT_EQ( + "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", + format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas)); + EXPECT_EQ( + "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", + format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas)); +} + +TEST_F(FormatTestComments, PriorityOfCommentBreaking) { + EXPECT_EQ("if (xxx ==\n" + " yyy && // aaaaaaaaaaaa bbbbbbbbb\n" + " zzz)\n" + " q();", + format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n" + " zzz) q();", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("if (xxxxxxxxxx ==\n" + " yyy && // aaaaaa bbbbbbbb cccc\n" + " zzz)\n" + " q();", + format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n" + " zzz) q();", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("if (xxxxxxxxxx &&\n" + " yyy || // aaaaaa bbbbbbbb cccc\n" + " zzz)\n" + " q();", + format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n" + " zzz) q();", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("fffffffff(\n" + " &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" + " zzz);", + format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" + " zzz);", + getLLVMStyleWithColumns(40))); +} + +TEST_F(FormatTestComments, MultiLineCommentsInDefines) { + EXPECT_EQ("#define A(x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + format("#define A(x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + getLLVMStyleWithColumns(17))); + EXPECT_EQ("#define A( \\\n" + " x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + format("#define A( \\\n" + " x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + getLLVMStyleWithColumns(17))); +} + +TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) { + EXPECT_EQ("namespace {}\n// Test\n#define A", + format("namespace {}\n // Test\n#define A")); + EXPECT_EQ("namespace {}\n/* Test */\n#define A", + format("namespace {}\n /* Test */\n#define A")); + EXPECT_EQ("namespace {}\n/* Test */ #define A", + format("namespace {}\n /* Test */ #define A")); +} + +TEST_F(FormatTestComments, SplitsLongLinesInComments) { + EXPECT_EQ("/* This is a long\n" + " * comment that\n" + " * doesn't\n" + " * fit on one line.\n" + " */", + format("/* " + "This is a long " + "comment that " + "doesn't " + "fit on one line. */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ( + "/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); + EXPECT_EQ( + "/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); + EXPECT_EQ("/*\n" + "This is a long\n" + "comment that doesn't\n" + "fit on one line.\n" + "*/", + format("/*\n" + "This is a long " + "comment that doesn't " + "fit on one line. \n" + "*/", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/*\n" + " * This is a long\n" + " * comment that\n" + " * doesn't fit on\n" + " * one line.\n" + " */", + format("/* \n" + " * This is a long " + " comment that " + " doesn't fit on " + " one line. \n" + " */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/*\n" + " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" + " * so_it_should_be_broken\n" + " * wherever_a_space_occurs\n" + " */", + format("/*\n" + " * This_is_a_comment_with_words_that_dont_fit_on_one_line " + " so_it_should_be_broken " + " wherever_a_space_occurs \n" + " */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/*\n" + " * This_comment_can_not_be_broken_into_lines\n" + " */", + format("/*\n" + " * This_comment_can_not_be_broken_into_lines\n" + " */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " /*\n" + " This is another\n" + " long comment that\n" + " doesn't fit on one\n" + " line 1234567890\n" + " */\n" + "}", + format("{\n" + "/*\n" + "This is another " + " long comment that " + " doesn't fit on one" + " line 1234567890\n" + "*/\n" + "}", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " /*\n" + " * This i s\n" + " * another comment\n" + " * t hat doesn' t\n" + " * fit on one l i\n" + " * n e\n" + " */\n" + "}", + format("{\n" + "/*\n" + " * This i s" + " another comment" + " t hat doesn' t" + " fit on one l i" + " n e\n" + " */\n" + "}", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/*\n" + " * This is a long\n" + " * comment that\n" + " * doesn't fit on\n" + " * one line\n" + " */", + format(" /*\n" + " * This is a long comment that doesn't fit on one line\n" + " */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " if (something) /* This is a\n" + " long\n" + " comment */\n" + " ;\n" + "}", + format("{\n" + " if (something) /* This is a long comment */\n" + " ;\n" + "}", + getLLVMStyleWithColumns(30))); + + EXPECT_EQ("/* A comment before\n" + " * a macro\n" + " * definition */\n" + "#define a b", + format("/* A comment before a macro definition */\n" + "#define a b", + getLLVMStyleWithColumns(20))); + + EXPECT_EQ("/* some comment\n" + " * a comment that\n" + " * we break another\n" + " * comment we have\n" + " * to break a left\n" + " * comment\n" + " */", + format(" /* some comment\n" + " * a comment that we break\n" + " * another comment we have to break\n" + "* a left comment\n" + " */", + getLLVMStyleWithColumns(20))); + + EXPECT_EQ("/**\n" + " * multiline block\n" + " * comment\n" + " *\n" + " */", + format("/**\n" + " * multiline block comment\n" + " *\n" + " */", + getLLVMStyleWithColumns(20))); + + EXPECT_EQ("/*\n" + "\n" + "\n" + " */\n", + format(" /* \n" + " \n" + " \n" + " */\n")); + + EXPECT_EQ("/* a a */", + format("/* a a */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* a a bc */", + format("/* a a bc */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* aaa aaa\n" + " * aaaaa */", + format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); + EXPECT_EQ("/* aaa aaa\n" + " * aaaaa */", + format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); +} + +TEST_F(FormatTestComments, SplitsLongLinesInCommentsInPreprocessor) { + EXPECT_EQ("#define X \\\n" + " /* \\\n" + " Test \\\n" + " Macro comment \\\n" + " with a long \\\n" + " line \\\n" + " */ \\\n" + " A + B", + format("#define X \\\n" + " /*\n" + " Test\n" + " Macro comment with a long line\n" + " */ \\\n" + " A + B", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("#define X \\\n" + " /* Macro comment \\\n" + " with a long \\\n" + " line */ \\\n" + " A + B", + format("#define X \\\n" + " /* Macro comment with a long\n" + " line */ \\\n" + " A + B", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("#define X \\\n" + " /* Macro comment \\\n" + " * with a long \\\n" + " * line */ \\\n" + " A + B", + format("#define X \\\n" + " /* Macro comment with a long line */ \\\n" + " A + B", + getLLVMStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, CommentsInStaticInitializers) { + EXPECT_EQ( + "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n" + " aaaaaaaaaaaaaaaaaaaa /* comment */,\n" + " /* comment */ aaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaa, // comment\n" + " aaaaaaaaaaaaaaaaaaaa};", + format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n" + " aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n" + " /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n" + " aaaaaaaaaaaaaaaaaaaa , // comment\n" + " aaaaaaaaaaaaaaaaaaaa };")); + verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" + " bbbbbbbbbbb, ccccccccccc};"); + verifyFormat("static SomeType type = {aaaaaaaaaaa,\n" + " // comment for bb....\n" + " bbbbbbbbbbb, ccccccccccc};"); + verifyGoogleFormat( + "static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" + " bbbbbbbbbbb, ccccccccccc};"); + verifyGoogleFormat("static SomeType type = {aaaaaaaaaaa,\n" + " // comment for bb....\n" + " bbbbbbbbbbb, ccccccccccc};"); + + verifyFormat("S s = {{a, b, c}, // Group #1\n" + " {d, e, f}, // Group #2\n" + " {g, h, i}}; // Group #3"); + verifyFormat("S s = {{// Group #1\n" + " a, b, c},\n" + " {// Group #2\n" + " d, e, f},\n" + " {// Group #3\n" + " g, h, i}};"); + + EXPECT_EQ("S s = {\n" + " // Some comment\n" + " a,\n" + "\n" + " // Comment after empty line\n" + " b}", + format("S s = {\n" + " // Some comment\n" + " a,\n" + " \n" + " // Comment after empty line\n" + " b\n" + "}")); + EXPECT_EQ("S s = {\n" + " /* Some comment */\n" + " a,\n" + "\n" + " /* Comment after empty line */\n" + " b}", + format("S s = {\n" + " /* Some comment */\n" + " a,\n" + " \n" + " /* Comment after empty line */\n" + " b\n" + "}")); + verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n" + " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" + " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" + " 0x00, 0x00, 0x00, 0x00}; // comment\n"); +} + +TEST_F(FormatTestComments, LineCommentsAfterRightBrace) { + EXPECT_EQ("if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}", + format("if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}", + format("if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}")); + EXPECT_EQ("do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);", + format("do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("while (a < b) { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}", + format("while (a < b) {// line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}", + getLLVMStyleWithColumns(80))); +} + +TEST_F(FormatTestComments, ReflowsComments) { + // Break a long line and reflow with the full next line. + EXPECT_EQ("// long long long\n" + "// long long", + format("// long long long long\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Keep the trailing newline while reflowing. + EXPECT_EQ("// long long long\n" + "// long long\n", + format("// long long long long\n" + "// long\n", + getLLVMStyleWithColumns(20))); + + // Break a long line and reflow with a part of the next line. + EXPECT_EQ("// long long long\n" + "// long long\n" + "// long_long", + format("// long long long long\n" + "// long long_long", + getLLVMStyleWithColumns(20))); + + // Break but do not reflow if the first word from the next line is too long. + EXPECT_EQ("// long long long\n" + "// long\n" + "// long_long_long\n", + format("// long long long long\n" + "// long_long_long\n", + getLLVMStyleWithColumns(20))); + + // Don't break or reflow short lines. + verifyFormat("// long\n" + "// long long long lo\n" + "// long long long lo\n" + "// long", + getLLVMStyleWithColumns(20)); + + // Keep prefixes and decorations while reflowing. + EXPECT_EQ("/// long long long\n" + "/// long long\n", + format("/// long long long long\n" + "/// long\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("//! long long long\n" + "//! long long\n", + format("//! long long long long\n" + "//! long\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* long long long\n" + " * long long */", + format("/* long long long long\n" + " * long */", + getLLVMStyleWithColumns(20))); + + // Don't bring leading whitespace up while reflowing. + EXPECT_EQ("/* long long long\n" + " * long long long\n" + " */", + format("/* long long long long\n" + " * long long\n" + " */", + getLLVMStyleWithColumns(20))); + + // Reflow the last line of a block comment with its trailing '*/'. + EXPECT_EQ("/* long long long\n" + " long long */", + format("/* long long long long\n" + " long */", + getLLVMStyleWithColumns(20))); + + // Reflow two short lines; keep the postfix of the last one. + EXPECT_EQ("/* long long long\n" + " * long long long */", + format("/* long long long long\n" + " * long\n" + " * long */", + getLLVMStyleWithColumns(20))); + + // Put the postfix of the last short reflow line on a newline if it doesn't + // fit. + EXPECT_EQ("/* long long long\n" + " * long long longg\n" + " */", + format("/* long long long long\n" + " * long\n" + " * longg */", + getLLVMStyleWithColumns(20))); + + // Reflow lines with leading whitespace. + EXPECT_EQ("{\n" + " /*\n" + " * long long long\n" + " * long long long\n" + " * long long long\n" + " */\n" + "}", + format("{\n" + "/*\n" + " * long long long long\n" + " * long\n" + " * long long long long\n" + " */\n" + "}", + getLLVMStyleWithColumns(20))); + + // Break single line block comments that are first in the line with ' *' + // decoration. + EXPECT_EQ("/* long long long\n" + " * long */", + format("/* long long long long */", getLLVMStyleWithColumns(20))); + + // Break single line block comment that are not first in the line with ' ' + // decoration. + EXPECT_EQ("int i; /* long long\n" + " long */", + format("int i; /* long long long */", getLLVMStyleWithColumns(20))); + + // Reflow a line that goes just over the column limit. + EXPECT_EQ("// long long long\n" + "// lon long", + format("// long long long lon\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Stop reflowing if the next line has a different indentation than the + // previous line. + EXPECT_EQ("// long long long\n" + "// long\n" + "// long long\n" + "// long", + format("// long long long long\n" + "// long long\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Reflow into the last part of a really long line that has been broken into + // multiple lines. + EXPECT_EQ("// long long long\n" + "// long long long\n" + "// long long long\n", + format("// long long long long long long long long\n" + "// long\n", + getLLVMStyleWithColumns(20))); + + // Break the first line, then reflow the beginning of the second and third + // line up. + EXPECT_EQ("// long long long\n" + "// lon1 lon2 lon2\n" + "// lon2 lon3 lon3", + format("// long long long lon1\n" + "// lon2 lon2 lon2\n" + "// lon3 lon3", + getLLVMStyleWithColumns(20))); + + // Reflow the beginning of the second line, then break the rest. + EXPECT_EQ("// long long long\n" + "// lon1 lon2 lon2\n" + "// lon2 lon2 lon2\n" + "// lon3", + format("// long long long lon1\n" + "// lon2 lon2 lon2 lon2 lon2 lon3", + getLLVMStyleWithColumns(20))); + + // Shrink the first line, then reflow the second line up. + EXPECT_EQ("// long long long", format("// long long\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Don't shrink leading whitespace. + EXPECT_EQ("int i; /// a", + format("int i; /// a", getLLVMStyleWithColumns(20))); + + // Shrink trailing whitespace if there is no postfix and reflow. + EXPECT_EQ("// long long long\n" + "// long long", + format("// long long long long \n" + "// long", + getLLVMStyleWithColumns(20))); + + // Shrink trailing whitespace to a single one if there is postfix. + EXPECT_EQ("/* long long long */", + format("/* long long long */", getLLVMStyleWithColumns(20))); + + // Break a block comment postfix if exceeding the line limit. + EXPECT_EQ("/* long\n" + " */", + format("/* long */", getLLVMStyleWithColumns(20))); + + // Reflow indented comments. + EXPECT_EQ("{\n" + " // long long long\n" + " // long long\n" + " int i; /* long lon\n" + " g long\n" + " */\n" + "}", + format("{\n" + " // long long long long\n" + " // long\n" + " int i; /* long lon g\n" + " long */\n" + "}", + getLLVMStyleWithColumns(20))); + + // Don't realign trailing comments after reflow has happened. + EXPECT_EQ("// long long long\n" + "// long long\n" + "long i; // long", + format("// long long long long\n" + "// long\n" + "long i; // long", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("// long long long\n" + "// longng long long\n" + "// long lo", + format("// long long long longng\n" + "// long long long\n" + "// lo", + getLLVMStyleWithColumns(20))); + + // Reflow lines after a broken line. + EXPECT_EQ("int a; // Trailing\n" + " // comment on\n" + " // 2 or 3\n" + " // lines.\n", + format("int a; // Trailing comment\n" + " // on 2\n" + " // or 3\n" + " // lines.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/// This long line\n" + "/// gets reflown.\n", + format("/// This long line gets\n" + "/// reflown.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("//! This long line\n" + "//! gets reflown.\n", + format(" //! This long line gets\n" + " //! reflown.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* This long line\n" + " * gets reflown.\n" + " */\n", + format("/* This long line gets\n" + " * reflown.\n" + " */\n", + getLLVMStyleWithColumns(20))); + + // Reflow after indentation makes a line too long. + EXPECT_EQ("{\n" + " // long long long\n" + " // lo long\n" + "}\n", + format("{\n" + "// long long long lo\n" + "// long\n" + "}\n", + getLLVMStyleWithColumns(20))); + + // Break and reflow multiple lines. + EXPECT_EQ("/*\n" + " * Reflow the end of\n" + " * line by 11 22 33\n" + " * 4.\n" + " */\n", + format("/*\n" + " * Reflow the end of line\n" + " * by\n" + " * 11\n" + " * 22\n" + " * 33\n" + " * 4.\n" + " */\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/// First line gets\n" + "/// broken. Second\n" + "/// line gets\n" + "/// reflown and\n" + "/// broken. Third\n" + "/// gets reflown.\n", + format("/// First line gets broken.\n" + "/// Second line gets reflown and broken.\n" + "/// Third gets reflown.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("int i; // first long\n" + " // long snd\n" + " // long.\n", + format("int i; // first long long\n" + " // snd long.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " // first long line\n" + " // line second\n" + " // long line line\n" + " // third long line\n" + " // line\n" + "}\n", + format("{\n" + " // first long line line\n" + " // second long line line\n" + " // third long line line\n" + "}\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("int i; /* first line\n" + " * second\n" + " * line third\n" + " * line\n" + " */", + format("int i; /* first line\n" + " * second line\n" + " * third line\n" + " */", + getLLVMStyleWithColumns(20))); + + // Reflow the last two lines of a section that starts with a line having + // different indentation. + EXPECT_EQ( + "// long\n" + "// long long long\n" + "// long long", + format("// long\n" + "// long long long long\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Keep the block comment endling '*/' while reflowing. + EXPECT_EQ("/* Long long long\n" + " * line short */\n", + format("/* Long long long line\n" + " * short */\n", + getLLVMStyleWithColumns(20))); + + // Don't reflow between separate blocks of comments. + EXPECT_EQ("/* First comment\n" + " * block will */\n" + "/* Snd\n" + " */\n", + format("/* First comment block\n" + " * will */\n" + "/* Snd\n" + " */\n", + getLLVMStyleWithColumns(20))); + + // Don't reflow across blank comment lines. + EXPECT_EQ("int i; // This long\n" + " // line gets\n" + " // broken.\n" + " //\n" + " // keep.\n", + format("int i; // This long line gets broken.\n" + " // \n" + " // keep.\n", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("{\n" + " /// long long long\n" + " /// long long\n" + " ///\n" + " /// long\n" + "}", + format("{\n" + " /// long long long long\n" + " /// long\n" + " ///\n" + " /// long\n" + "}", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("//! long long long\n" + "//! long\n" + "\n" + "//! long", + format("//! long long long long\n" + "\n" + "//! long", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* long long long\n" + " long\n" + "\n" + " long */", + format("/* long long long long\n" + "\n" + " long */", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* long long long\n" + " * long\n" + " *\n" + " * long */", + format("/* long long long long\n" + " *\n" + " * long */", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines having content that is a single character. + EXPECT_EQ("// long long long\n" + "// long\n" + "// l", + format("// long long long long\n" + "// l", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines starting with two punctuation characters. + EXPECT_EQ("// long long long\n" + "// long\n" + "// ... --- ...", + format( + "// long long long long\n" + "// ... --- ...", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines starting with '@'. + EXPECT_EQ("// long long long\n" + "// long\n" + "// @param arg", + format("// long long long long\n" + "// @param arg", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines starting with 'TODO'. + EXPECT_EQ("// long long long\n" + "// long\n" + "// TODO: long", + format("// long long long long\n" + "// TODO: long", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines starting with 'FIXME'. + EXPECT_EQ("// long long long\n" + "// long\n" + "// FIXME: long", + format("// long long long long\n" + "// FIXME: long", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines starting with 'XXX'. + EXPECT_EQ("// long long long\n" + "// long\n" + "// XXX: long", + format("// long long long long\n" + "// XXX: long", + getLLVMStyleWithColumns(20))); + + // Don't reflow comment pragmas. + EXPECT_EQ("// long long long\n" + "// long\n" + "// IWYU pragma:", + format("// long long long long\n" + "// IWYU pragma:", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* long long long\n" + " * long\n" + " * IWYU pragma:\n" + " */", + format("/* long long long long\n" + " * IWYU pragma:\n" + " */", + getLLVMStyleWithColumns(20))); + + // Reflow lines that have a non-punctuation character among their first 2 + // characters. + EXPECT_EQ("// long long long\n" + "// long 'long'", + format( + "// long long long long\n" + "// 'long'", + getLLVMStyleWithColumns(20))); + + // Don't reflow between separate blocks of comments. + EXPECT_EQ("/* First comment\n" + " * block will */\n" + "/* Snd\n" + " */\n", + format("/* First comment block\n" + " * will */\n" + "/* Snd\n" + " */\n", + getLLVMStyleWithColumns(20))); + + // Don't reflow lines having different indentation. + EXPECT_EQ("// long long long\n" + "// long\n" + "// long", + format("// long long long long\n" + "// long", + getLLVMStyleWithColumns(20))); + + // Don't break or reflow after implicit string literals. + verifyFormat("#include <t> // l l l\n" + " // l", + getLLVMStyleWithColumns(20)); + + // Don't break or reflow comments on import lines. + EXPECT_EQ("#include \"t\" /* l l l\n" + " * l */", + format("#include \"t\" /* l l l\n" + " * l */", + getLLVMStyleWithColumns(20))); + + // Don't reflow between different trailing comment sections. + EXPECT_EQ("int i; // long long\n" + " // long\n" + "int j; // long long\n" + " // long\n", + format("int i; // long long long\n" + "int j; // long long long\n", + getLLVMStyleWithColumns(20))); + + // Don't reflow if the first word on the next line is longer than the + // available space at current line. + EXPECT_EQ("int i; // trigger\n" + " // reflow\n" + " // longsec\n", + format("int i; // trigger reflow\n" + " // longsec\n", + getLLVMStyleWithColumns(20))); + + // Keep empty comment lines. + EXPECT_EQ("/**/", format(" /**/", getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20))); + EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20))); + EXPECT_EQ("//", format(" // ", getLLVMStyleWithColumns(20))); + EXPECT_EQ("///", format(" /// ", getLLVMStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, IgnoresIf0Contents) { + EXPECT_EQ("#if 0\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f() {}", + format("#if 0\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f( ) { }")); + EXPECT_EQ("#if false\n" + "void f( ) { }\n" + "#endif\n" + "void g() {}\n", + format("#if false\n" + "void f( ) { }\n" + "#endif\n" + "void g( ) { }\n")); + EXPECT_EQ("enum E {\n" + " One,\n" + " Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five\n" + "};", + format("enum E {\n" + " One,Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five};")); + EXPECT_EQ("enum F {\n" + " One,\n" + "#if 1\n" + " Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five\n" + "#endif\n" + "};", + format("enum F {\n" + "One,\n" + "#if 1\n" + "Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + "Five\n" + "#endif\n" + "};")); + EXPECT_EQ("enum G {\n" + " One,\n" + "#if 0\n" + "Two,\n" + "#else\n" + " Three,\n" + "#endif\n" + " Four\n" + "};", + format("enum G {\n" + "One,\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four\n" + "};")); + EXPECT_EQ("enum H {\n" + " One,\n" + "#if 0\n" + "#ifdef Q\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "#endif\n" + " Four\n" + "};", + format("enum H {\n" + "One,\n" + "#if 0\n" + "#ifdef Q\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "#endif\n" + "Four\n" + "};")); + EXPECT_EQ("enum I {\n" + " One,\n" + "#if /* test */ 0 || 1\n" + "Two,\n" + "Three,\n" + "#endif\n" + " Four\n" + "};", + format("enum I {\n" + "One,\n" + "#if /* test */ 0 || 1\n" + "Two,\n" + "Three,\n" + "#endif\n" + "Four\n" + "};")); + EXPECT_EQ("enum J {\n" + " One,\n" + "#if 0\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four,\n" + "#endif\n" + " Five\n" + "};", + format("enum J {\n" + "One,\n" + "#if 0\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four,\n" + "#endif\n" + "Five\n" + "};")); + + // Ignore stuff in SWIG-blocks. + EXPECT_EQ("#ifdef SWIG\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f() {}", + format("#ifdef SWIG\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f( ) { }")); + EXPECT_EQ("#ifndef SWIG\n" + "void f() {}\n" + "#endif", + format("#ifndef SWIG\n" + "void f( ) { }\n" + "#endif")); +} + +TEST_F(FormatTestComments, DontCrashOnBlockComments) { + EXPECT_EQ( + "int xxxxxxxxx; /* " + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" + "zzzzzz\n" + "0*/", + format("int xxxxxxxxx; /* " + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" + "0*/")); +} + +TEST_F(FormatTestComments, BlockCommentsInControlLoops) { + verifyFormat("if (0) /* a comment in a strange place */ {\n" + " f();\n" + "}"); + verifyFormat("if (0) /* a comment in a strange place */ {\n" + " f();\n" + "} /* another comment */ else /* comment #3 */ {\n" + " g();\n" + "}"); + verifyFormat("while (0) /* a comment in a strange place */ {\n" + " f();\n" + "}"); + verifyFormat("for (;;) /* a comment in a strange place */ {\n" + " f();\n" + "}"); + verifyFormat("do /* a comment in a strange place */ {\n" + " f();\n" + "} /* another comment */ while (0);"); +} + +TEST_F(FormatTestComments, BlockComments) { + EXPECT_EQ("/* */ /* */ /* */\n/* */ /* */ /* */", + format("/* *//* */ /* */\n/* *//* */ /* */")); + EXPECT_EQ("/* */ a /* */ b;", format(" /* */ a/* */ b;")); + EXPECT_EQ("#define A /*123*/ \\\n" + " b\n" + "/* */\n" + "someCall(\n" + " parameter);", + format("#define A /*123*/ b\n" + "/* */\n" + "someCall(parameter);", + getLLVMStyleWithColumns(15))); + + EXPECT_EQ("#define A\n" + "/* */ someCall(\n" + " parameter);", + format("#define A\n" + "/* */someCall(parameter);", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("/*\n**\n*/", format("/*\n**\n*/")); + EXPECT_EQ("/*\n" + " *\n" + " * aaaaaa\n" + " * aaaaaa\n" + " */", + format("/*\n" + "*\n" + " * aaaaaa aaaaaa\n" + "*/", + getLLVMStyleWithColumns(10))); + EXPECT_EQ("/*\n" + "**\n" + "* aaaaaa\n" + "*aaaaaa\n" + "*/", + format("/*\n" + "**\n" + "* aaaaaa aaaaaa\n" + "*/", + getLLVMStyleWithColumns(10))); + EXPECT_EQ("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " /* line 1\n" + " bbbbbbbbbbbb */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " /* line 1\n" + " bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + getLLVMStyleWithColumns(50))); + + FormatStyle NoBinPacking = getLLVMStyle(); + NoBinPacking.BinPackParameters = false; + EXPECT_EQ("someFunction(1, /* comment 1 */\n" + " 2, /* comment 2 */\n" + " 3, /* comment 3 */\n" + " aaaa,\n" + " bbbb);", + format("someFunction (1, /* comment 1 */\n" + " 2, /* comment 2 */ \n" + " 3, /* comment 3 */\n" + "aaaa, bbbb );", + NoBinPacking)); + verifyFormat( + "bool aaaaaaaaaaaaa = /* comment: */ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); + EXPECT_EQ( + "bool aaaaaaaaaaaaa = /* trailing comment */\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;", + format( + "bool aaaaaaaaaaaaa = /* trailing comment */\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;")); + EXPECT_EQ( + "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" + "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" + "int cccccccccccccccccccccccccccccc; /* comment */\n", + format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" + "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" + "int cccccccccccccccccccccccccccccc; /* comment */\n")); + + verifyFormat("void f(int * /* unused */) {}"); + + EXPECT_EQ("/*\n" + " **\n" + " */", + format("/*\n" + " **\n" + " */")); + EXPECT_EQ("/*\n" + " *q\n" + " */", + format("/*\n" + " *q\n" + " */")); + EXPECT_EQ("/*\n" + " * q\n" + " */", + format("/*\n" + " * q\n" + " */")); + EXPECT_EQ("/*\n" + " **/", + format("/*\n" + " **/")); + EXPECT_EQ("/*\n" + " ***/", + format("/*\n" + " ***/")); +} + +TEST_F(FormatTestComments, BlockCommentsInMacros) { + EXPECT_EQ("#define A \\\n" + " { \\\n" + " /* one line */ \\\n" + " someCall();", + format("#define A { \\\n" + " /* one line */ \\\n" + " someCall();", + getLLVMStyleWithColumns(20))); + EXPECT_EQ("#define A \\\n" + " { \\\n" + " /* previous */ \\\n" + " /* one line */ \\\n" + " someCall();", + format("#define A { \\\n" + " /* previous */ \\\n" + " /* one line */ \\\n" + " someCall();", + getLLVMStyleWithColumns(20))); +} + +TEST_F(FormatTestComments, BlockCommentsAtEndOfLine) { + EXPECT_EQ("a = {\n" + " 1111 /* */\n" + "};", + format("a = {1111 /* */\n" + "};", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("a = {\n" + " 1111 /* */\n" + "};", + format("a = {1111 /* */\n" + "};", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("a = {\n" + " 1111 /* a\n" + " */\n" + "};", + format("a = {1111 /* a */\n" + "};", + getLLVMStyleWithColumns(15))); +} + +TEST_F(FormatTestComments, IndentLineCommentsInStartOfBlockAtEndOfFile) { + verifyFormat("{\n" + " // a\n" + " // b"); +} + +TEST_F(FormatTestComments, AlignTrailingComments) { + EXPECT_EQ("#define MACRO(V) \\\n" + " V(Rt2) /* one more char */ \\\n" + " V(Rs) /* than here */ \\\n" + "/* comment 3 */\n", + format("#define MACRO(V)\\\n" + "V(Rt2) /* one more char */ \\\n" + "V(Rs) /* than here */ \\\n" + "/* comment 3 */ \\\n", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("int i = f(abc, // line 1\n" + " d, // line 2\n" + " // line 3\n" + " b);", + format("int i = f(abc, // line 1\n" + " d, // line 2\n" + " // line 3\n" + " b);", + getLLVMStyleWithColumns(40))); + + // Align newly broken trailing comments. + EXPECT_EQ("int ab; // line\n" + "int a; // long\n" + " // long\n", + format("int ab; // line\n" + "int a; // long long\n", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("int ab; // line\n" + "int a; // long\n" + " // long\n" + " // long", + format("int ab; // line\n" + "int a; // long long\n" + " // long", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("int ab; // line\n" + "int a; // long\n" + " // long\n" + "pt c; // long", + format("int ab; // line\n" + "int a; // long long\n" + "pt c; // long", + getLLVMStyleWithColumns(15))); + EXPECT_EQ("int ab; // line\n" + "int a; // long\n" + " // long\n" + "\n" + "// long", + format("int ab; // line\n" + "int a; // long long\n" + "\n" + "// long", + getLLVMStyleWithColumns(15))); + + // Align comment line sections aligned with the next token with the next + // token. + EXPECT_EQ("class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + format("class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + format("class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + format("int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + getLLVMStyleWithColumns(40))); + EXPECT_EQ("int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}", + format("int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}", + getLLVMStyleWithColumns(80))); + + // If all the lines in a sequence of line comments are aligned with the next + // token, the first line belongs to the previous token and the other lines + // belong to the next token. + EXPECT_EQ("int a; // line about a\n" + "long b;", + format("int a; // line about a\n" + " long b;", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("int a; // line about a\n" + "// line about b\n" + "long b;", + format("int a; // line about a\n" + " // line about b\n" + " long b;", + getLLVMStyleWithColumns(80))); + EXPECT_EQ("int a; // line about a\n" + "// line 1 about b\n" + "// line 2 about b\n" + "long b;", + format("int a; // line about a\n" + " // line 1 about b\n" + " // line 2 about b\n" + " long b;", + getLLVMStyleWithColumns(80))); +} + +TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { + EXPECT_EQ("/*\n" + " */", + format("/*\n" + "*/", getLLVMStyle())); + EXPECT_EQ("/*\n" + " */", + format("/*\n" + " */", getLLVMStyle())); + EXPECT_EQ("/*\n" + " */", + format("/*\n" + " */", getLLVMStyle())); + + // Align a single line. + EXPECT_EQ("/*\n" + " * line */", + format("/*\n" + "* line */", + getLLVMStyle())); + EXPECT_EQ("/*\n" + " * line */", + format("/*\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/*\n" + " * line */", + format("/*\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/*\n" + " * line */", + format("/*\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/**\n" + " * line */", + format("/**\n" + "* line */", + getLLVMStyle())); + EXPECT_EQ("/**\n" + " * line */", + format("/**\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/**\n" + " * line */", + format("/**\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/**\n" + " * line */", + format("/**\n" + " * line */", + getLLVMStyle())); + EXPECT_EQ("/**\n" + " * line */", + format("/**\n" + " * line */", + getLLVMStyle())); + + // Align the end '*/' after a line. + EXPECT_EQ("/*\n" + " * line\n" + " */", + format("/*\n" + "* line\n" + "*/", getLLVMStyle())); + EXPECT_EQ("/*\n" + " * line\n" + " */", + format("/*\n" + " * line\n" + " */", getLLVMStyle())); + EXPECT_EQ("/*\n" + " * line\n" + " */", + format("/*\n" + " * line\n" + " */", getLLVMStyle())); + + // Align two lines. + EXPECT_EQ("/* line 1\n" + " * line 2 */", + format("/* line 1\n" + " * line 2 */", + getLLVMStyle())); + EXPECT_EQ("/* line 1\n" + " * line 2 */", + format("/* line 1\n" + "* line 2 */", + getLLVMStyle())); + EXPECT_EQ("/* line 1\n" + " * line 2 */", + format("/* line 1\n" + " * line 2 */", + getLLVMStyle())); + EXPECT_EQ("/* line 1\n" + " * line 2 */", + format("/* line 1\n" + " * line 2 */", + getLLVMStyle())); + EXPECT_EQ("/* line 1\n" + " * line 2 */", + format("/* line 1\n" + " * line 2 */", + getLLVMStyle())); + EXPECT_EQ("int i; /* line 1\n" + " * line 2 */", + format("int i; /* line 1\n" + "* line 2 */", + getLLVMStyle())); + EXPECT_EQ("int i; /* line 1\n" + " * line 2 */", + format("int i; /* line 1\n" + " * line 2 */", + getLLVMStyle())); + EXPECT_EQ("int i; /* line 1\n" + " * line 2 */", + format("int i; /* line 1\n" + " * line 2 */", + getLLVMStyle())); + + // Align several lines. + EXPECT_EQ("/* line 1\n" + " * line 2\n" + " * line 3 */", + format("/* line 1\n" + " * line 2\n" + "* line 3 */", + getLLVMStyle())); + EXPECT_EQ("/* line 1\n" + " * line 2\n" + " * line 3 */", + format("/* line 1\n" + " * line 2\n" + "* line 3 */", + getLLVMStyle())); + EXPECT_EQ("/*\n" + "** line 1\n" + "** line 2\n" + "*/", + format("/*\n" + "** line 1\n" + " ** line 2\n" + "*/", + getLLVMStyle())); + + // Align with different indent after the decorations. + EXPECT_EQ("/*\n" + " * line 1\n" + " * line 2\n" + " * line 3\n" + " * line 4\n" + " */", + format("/*\n" + "* line 1\n" + " * line 2\n" + " * line 3\n" + "* line 4\n" + "*/", getLLVMStyle())); + + // Align empty or blank lines. + EXPECT_EQ("/**\n" + " *\n" + " *\n" + " *\n" + " */", + format("/**\n" + "* \n" + " * \n" + " *\n" + "*/", getLLVMStyle())); + + // Align while breaking and reflowing. + EXPECT_EQ("/*\n" + " * long long long\n" + " * long long\n" + " *\n" + " * long */", + format("/*\n" + " * long long long long\n" + " * long\n" + " *\n" + "* long */", + getLLVMStyleWithColumns(20))); +} +} // end namespace +} // end namespace format +} // end namespace clang diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 230717fe47cc..d8fa8e4b942c 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -132,6 +132,8 @@ TEST_F(FormatTestJS, ReservedWords) { verifyFormat("x.interface = 1;"); verifyFormat("x.for = 1;"); verifyFormat("x.of() = 1;"); + verifyFormat("of(null);"); + verifyFormat("import {of} from 'x';"); verifyFormat("x.in() = 1;"); verifyFormat("x.let() = 1;"); verifyFormat("x.var() = 1;"); @@ -167,6 +169,8 @@ TEST_F(FormatTestJS, ReservedWordsMethods) { TEST_F(FormatTestJS, CppKeywords) { // Make sure we don't mess stuff up because of C++ keywords. verifyFormat("return operator && (aa);"); + // .. or QT ones. + verifyFormat("slots: Slot[];"); } TEST_F(FormatTestJS, ES6DestructuringAssignment) { @@ -240,6 +244,18 @@ TEST_F(FormatTestJS, ContainerLiterals) { "};"); verifyFormat("var x = {y: (a) => a};"); + // Methods in object literals. + verifyFormat("var x = {\n" + " y(a: string): number {\n" + " return a;\n" + " }\n" + "};"); + verifyFormat("var x = {\n" + " y(a: string) {\n" + " return a;\n" + " }\n" + "};"); + // Computed keys. verifyFormat("var x = {[a]: 1, b: 2, [c]: 3};"); verifyFormat("var x = {\n" @@ -266,6 +282,11 @@ TEST_F(FormatTestJS, ContainerLiterals) { " aaa,\n" " aaa,\n" "};"); + verifyFormat("return {\n" + " a,\n" + " b: 'b',\n" + " c,\n" + "};"); } TEST_F(FormatTestJS, MethodsInObjectLiterals) { @@ -451,6 +472,8 @@ TEST_F(FormatTestJS, AsyncFunctions) { verifyFormat("export async function f() {\n" " return fetch(x);\n" "}"); + verifyFormat("let x = async () => f();"); + verifyFormat("let x = async();"); verifyFormat("class X {\n" " async asyncMethod() {\n" " return fetch(1);\n" @@ -497,6 +520,11 @@ TEST_F(FormatTestJS, ArrayLiterals) { " [];"); verifyFormat("someFunction([], {a: a});"); + + verifyFormat("var string = [\n" + " 'aaaaaa',\n" + " 'bbbbbb',\n" + "].join('+');"); } TEST_F(FormatTestJS, ColumnLayoutForArrayLiterals) { @@ -587,6 +615,11 @@ TEST_F(FormatTestJS, FunctionLiterals) { " doSomething();\n" "}, this));"); + verifyFormat("SomeFunction(function() {\n" + " foo();\n" + " bar();\n" + "}.bind(this));"); + // FIXME: This is bad, we should be wrapping before "function() {". verifyFormat("someFunction(function() {\n" " doSomething(); // break\n" @@ -858,13 +891,25 @@ TEST_F(FormatTestJS, AutomaticSemicolonInsertionHeuristic) { "return 1", "a = null\n" " return 1"); + // Below "class Y {}" should ideally be on its own line. verifyFormat( "x = {\n" " a: 1\n" - "}\n" - "class Y {}", + "} class Y {}", " x = {a : 1}\n" " class Y { }"); + verifyFormat( + "if (x) {\n" + "}\n" + "return 1", + "if (x) {}\n" + " return 1"); + verifyFormat( + "if (x) {\n" + "}\n" + "class X {}", + "if (x) {}\n" + " class X {}"); } TEST_F(FormatTestJS, ImportExportASI) { @@ -873,11 +918,17 @@ TEST_F(FormatTestJS, ImportExportASI) { "export function z() {}", "import {x} from 'y'\n" " export function z() {}"); + // Below "class Y {}" should ideally be on its own line. verifyFormat( - "export {x}\n" - "class Y {}", + "export {x} class Y {}", " export {x}\n" " class Y {\n}"); + verifyFormat( + "if (x) {\n" + "}\n" + "export class Y {}", + "if ( x ) { }\n" + " export class Y {}"); } TEST_F(FormatTestJS, ClosureStyleCasts) { @@ -913,6 +964,7 @@ TEST_F(FormatTestJS, RegexLiteralClassification) { verifyFormat("var x = a ? /abc/ : /abc/;"); verifyFormat("for (var i = 0; /abc/.test(s[i]); i++) {\n}"); verifyFormat("var x = !/abc/.test(y);"); + verifyFormat("var x = foo()! / 10;"); verifyFormat("var x = a && /abc/.test(y);"); verifyFormat("var x = a || /abc/.test(y);"); verifyFormat("var x = a + /abc/.search(y);"); @@ -1018,6 +1070,15 @@ TEST_F(FormatTestJS, RegexLiteralExamples) { verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);"); } +TEST_F(FormatTestJS, IgnoresMpegTS) { + std::string MpegTS(200, ' '); + MpegTS.replace(0, strlen("nearlyLooks + like + ts + code; "), + "nearlyLooks + like + ts + code; "); + MpegTS[0] = 0x47; + MpegTS[188] = 0x47; + verifyFormat(MpegTS, MpegTS); +} + TEST_F(FormatTestJS, TypeAnnotations) { verifyFormat("var x: string;"); verifyFormat("var x: {a: string; b: number;} = {};"); @@ -1045,6 +1106,9 @@ TEST_F(FormatTestJS, TypeAnnotations) { verifyFormat("function someFunc(args: string[]):\n" " {longReturnValue: string[]} {}", getGoogleJSStyleWithColumns(60)); + verifyFormat( + "var someValue = (v as aaaaaaaaaaaaaaaaaaaa<T>[])\n" + " .someFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } TEST_F(FormatTestJS, UnionIntersectionTypes) { @@ -1072,6 +1136,10 @@ TEST_F(FormatTestJS, ClassDeclarations) { verifyFormat("class C {\n static x(): string {\n return 'asd';\n }\n}"); verifyFormat("class C extends P implements I {}"); verifyFormat("class C extends p.P implements i.I {}"); + verifyFormat( + "x(class {\n" + " a(): A {}\n" + "});"); verifyFormat("class Test {\n" " aaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaa: aaaaaaaaaaaaaaaaaaaa):\n" " aaaaaaaaaaaaaaaaaaaaaa {}\n" @@ -1164,6 +1232,20 @@ TEST_F(FormatTestJS, TypeAliases) { "class C {}"); } +TEST_F(FormatTestJS, TypeInterfaceLineWrapping) { + const FormatStyle &Style = getGoogleJSStyleWithColumns(20); + verifyFormat("type LongTypeIsReallyUnreasonablyLong =\n" + " string;\n", + "type LongTypeIsReallyUnreasonablyLong = string;\n", + Style); + verifyFormat( + "interface AbstractStrategyFactoryProvider {\n" + " a: number\n" + "}\n", + "interface AbstractStrategyFactoryProvider { a: number }\n", + Style); +} + TEST_F(FormatTestJS, Modules) { verifyFormat("import SomeThing from 'some/module.js';"); verifyFormat("import {X, Y} from 'some/module.js';"); @@ -1351,6 +1433,62 @@ TEST_F(FormatTestJS, TemplateStrings) { "var y;"); // Escaped dollar. verifyFormat("var x = ` \\${foo}`;\n"); + + // The token stream can contain two string_literals in sequence, but that + // doesn't mean that they are implicitly concatenated in JavaScript. + verifyFormat("var f = `aaaa ${a ? 'a' : 'b'}`;"); + + // Ensure that scopes are appropriately set around evaluated expressions in + // template strings. + verifyFormat("var f = `aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa\n" + " aaaaaaaaaaaaa:${aaaaaaa.aaaaa} aaaaaaaa`;", + "var f = `aaaaaaaaaaaaa:${aaaaaaa. aaaaa} aaaaaaaa\n" + " aaaaaaaaaaaaa:${ aaaaaaa. aaaaa} aaaaaaaa`;"); + verifyFormat("var x = someFunction(`${})`) //\n" + " .oooooooooooooooooon();"); + verifyFormat("var x = someFunction(`${aaaa}${\n" + " aaaaa( //\n" + " aaaaa)\n" + " })`);"); +} + +TEST_F(FormatTestJS, TemplateStringMultiLineExpression) { + verifyFormat("var f = `aaaaaaaaaaaaaaaaaa: ${\n" + " aaaaa + //\n" + " bbbb\n" + " }`;", + "var f = `aaaaaaaaaaaaaaaaaa: ${aaaaa + //\n" + " bbbb}`;"); + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${\n" + " aaaaa + //\n" + " bbbb\n" + " }`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${ aaaaa + //\n" + " bbbb }`;"); + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${\n" + " someFunction(\n" + " aaaaa + //\n" + " bbbb)\n" + " }`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction (\n" + " aaaaa + //\n" + " bbbb)}`;"); + + // It might be preferable to wrap before "someFunction". + verifyFormat("var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction({\n" + " aaaa: aaaaa,\n" + " bbbb: bbbbb,\n" + " })}`;", + "var f = `\n" + " aaaaaaaaaaaaaaaaaa: ${someFunction ({\n" + " aaaa: aaaaa,\n" + " bbbb: bbbbb,\n" + " })}`;"); } TEST_F(FormatTestJS, TemplateStringASI) { @@ -1387,6 +1525,9 @@ TEST_F(FormatTestJS, CastSyntax) { verifyFormat("x = x as {a: string};"); verifyFormat("x = x as (string);"); verifyFormat("x = x! as (string);"); + verifyFormat("var x = something.someFunction() as\n" + " something;", + getGoogleJSStyleWithColumns(40)); } TEST_F(FormatTestJS, TypeArguments) { @@ -1460,6 +1601,58 @@ TEST_F(FormatTestJS, JSDocAnnotations) { " * @export {this.is.a.long.path.to.a.Type}\n" " */", getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @mods {this.is.a.long.path.to.a.Type}\n" + " */", + "/**\n" + " * @mods {this.is.a.long.path.to.a.Type}\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " */", + "/**\n" + " * @param {this.is.a.long.path.to.a.Type}\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat("/**\n" + " * @see http://very/very/long/url/is/long\n" + " */", + "/**\n" + " * @see http://very/very/long/url/is/long\n" + " */", + getGoogleJSStyleWithColumns(20)); + verifyFormat( + "/**\n" + " * @param This is a\n" + " * long comment but\n" + " * no type\n" + " */", + "/**\n" + " * @param This is a long comment but no type\n" + " */", + getGoogleJSStyleWithColumns(20)); + // Don't break @param line, but reindent it and reflow unrelated lines. + verifyFormat("{\n" + " /**\n" + " * long long long\n" + " * long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long\n" + " * long long\n" + " */\n" + " function f(a) {}\n" + "}", + "{\n" + "/**\n" + " * long long long long\n" + " * @param {this.is.a.long.path.to.a.Type} a\n" + " * long long long long\n" + " * long\n" + " */\n" + " function f(a) {}\n" + "}", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, RequoteStringsSingle) { @@ -1532,6 +1725,12 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) { verifyFormat("let x = (foo)!;\n"); verifyFormat("let x = foo! - 1;\n"); verifyFormat("let x = {foo: 1}!;\n"); + verifyFormat( + "let x = hello.foo()!\n" + " .foo()!\n" + " .foo()!\n" + " .foo()!;\n", + getGoogleJSStyleWithColumns(20)); } TEST_F(FormatTestJS, Conditional) { @@ -1548,6 +1747,5 @@ TEST_F(FormatTestJS, ImportComments) { getGoogleJSStyleWithColumns(25)); verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10)); } - } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp index dfc3debc46e2..6e685f6703e1 100644 --- a/unittests/Format/FormatTestJava.cpp +++ b/unittests/Format/FormatTestJava.cpp @@ -225,6 +225,13 @@ TEST_F(FormatTestJava, EnumDeclarations) { " }\n" " };\n" "}"); + verifyFormat("public enum VeryLongEnum {\n" + " ENUM_WITH_MANY_PARAMETERS(\n" + " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\", \"bbbbbbbbbbbbbbbb\", " + "\"cccccccccccccccccccccccc\"),\n" + " SECOND_ENUM(\"a\", \"b\", \"c\");\n" + " private VeryLongEnum(String a, String b, String c) {}\n" + "}\n"); } TEST_F(FormatTestJava, ArrayInitializers) { @@ -515,5 +522,17 @@ TEST_F(FormatTestJava, AlignsBlockComments) { " void f() {}")); } +TEST_F(FormatTestJava, RetainsLogicalShifts) { + verifyFormat("void f() {\n" + " int a = 1;\n" + " a >>>= 1;\n" + "}"); + verifyFormat("void f() {\n" + " int a = 1;\n" + " a = a >>> 1;\n" + "}"); +} + + } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp index 6a530f921e6d..680ff92f75e8 100644 --- a/unittests/Format/FormatTestObjC.cpp +++ b/unittests/Format/FormatTestObjC.cpp @@ -68,17 +68,21 @@ protected: FormatStyle Style; }; -TEST_F(FormatTestObjC, DetectsObjCInHeaders) { - Style = getStyle("LLVM", "a.h", "none", "@interface\n" - "- (id)init;"); - EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language); +TEST(FormatTestObjCStyle, DetectsObjCInHeaders) { + auto Style = getStyle("LLVM", "a.h", "none", "@interface\n" + "- (id)init;"); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); + Style = getStyle("LLVM", "a.h", "none", "@interface\n" "+ (id)init;"); - EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_ObjC, Style->Language); // No recognizable ObjC. Style = getStyle("LLVM", "a.h", "none", "void f() {}"); - EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language); + ASSERT_TRUE((bool)Style); + EXPECT_EQ(FormatStyle::LK_Cpp, Style->Language); } TEST_F(FormatTestObjC, FormatObjCTryCatch) { diff --git a/unittests/Format/FormatTestProto.cpp b/unittests/Format/FormatTestProto.cpp index 6881af4361cf..d174c65a1f32 100644 --- a/unittests/Format/FormatTestProto.cpp +++ b/unittests/Format/FormatTestProto.cpp @@ -135,6 +135,16 @@ TEST_F(FormatTestProto, MessageFieldAttributes) { " key: 'a' //\n" " }\n" "];"); + verifyFormat("optional string test = 1 [default =\n" + " \"test\"\n" + " \"test\"];"); + verifyFormat("optional Aaaaaaaa aaaaaaaa = 12 [\n" + " (aaa) = aaaa,\n" + " (bbbbbbbbbbbbbbbbbbbbbbbbbb) = {\n" + " aaaaaaaaaaaaaaaaa: true,\n" + " aaaaaaaaaaaaaaaa: true\n" + " }\n" + "];"); } TEST_F(FormatTestProto, DoesntWrapFileOptions) { diff --git a/unittests/Format/FormatTestSelective.cpp b/unittests/Format/FormatTestSelective.cpp index 2bc60fd1e0d3..367dbafcaf4c 100644 --- a/unittests/Format/FormatTestSelective.cpp +++ b/unittests/Format/FormatTestSelective.cpp @@ -111,13 +111,19 @@ TEST_F(FormatTestSelective, FormatsCommentsLocally) { format("int a; // comment\n" "int b; // comment", 0, 0)); - EXPECT_EQ("int a; // comment\n" - " // line 2\n" + EXPECT_EQ("int a; // comment\n" + " // line 2\n" "int b;", format("int a; // comment\n" " // line 2\n" "int b;", 28, 0)); + EXPECT_EQ("int a; // comment\n" + "// comment 2\n" + "int b;", + format("int a; // comment\n" + "// comment 2\n" + "int b;", 28, 0)); EXPECT_EQ("int aaaaaa; // comment\n" "int b;\n" "int c; // unrelated comment", diff --git a/unittests/Format/NamespaceEndCommentsFixerTest.cpp b/unittests/Format/NamespaceEndCommentsFixerTest.cpp new file mode 100644 index 000000000000..912638f45652 --- /dev/null +++ b/unittests/Format/NamespaceEndCommentsFixerTest.cpp @@ -0,0 +1,602 @@ +//===- NamespaceEndCommentsFixerTest.cpp - Formatting unit tests ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Format/Format.h" + +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "llvm/Support/Debug.h" +#include "gtest/gtest.h" + +#define DEBUG_TYPE "namespace-end-comments-fixer-test" + +namespace clang { +namespace format { +namespace { + +class NamespaceEndCommentsFixerTest : public ::testing::Test { +protected: + std::string + fixNamespaceEndComments(llvm::StringRef Code, + std::vector<tooling::Range> Ranges, + const FormatStyle &Style = getLLVMStyle()) { + DEBUG(llvm::errs() << "---\n"); + DEBUG(llvm::errs() << Code << "\n\n"); + tooling::Replacements Replaces = + clang::format::fixNamespaceEndComments(Style, Code, Ranges, "<stdin>"); + auto Result = applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast<bool>(Result)); + DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); + return *Result; + } + + std::string + fixNamespaceEndComments(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + return fixNamespaceEndComments( + Code, + /*Ranges=*/{1, tooling::Range(0, Code.size())}, Style); + } +}; + +TEST_F(NamespaceEndCommentsFixerTest, AddsEndComment) { + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "}// namespace", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "}// namespace\n", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "}\n")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + " int j;\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("inline namespace A {\n" + " int i;\n" + " int j;\n" + "}// namespace A", + fixNamespaceEndComments("inline namespace A {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("namespace ::A {\n" + " int i;\n" + " int j;\n" + "}// namespace ::A", + fixNamespaceEndComments("namespace ::A {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("namespace ::A::B {\n" + " int i;\n" + " int j;\n" + "}// namespace ::A::B", + fixNamespaceEndComments("namespace ::A::B {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("namespace /**/::/**/A/**/::/**/B/**/ {\n" + " int i;\n" + " int j;\n" + "}// namespace ::A::B", + fixNamespaceEndComments("namespace /**/::/**/A/**/::/**/B/**/ {\n" + " int i;\n" + " int j;\n" + "}")); + EXPECT_EQ("namespace A {\n" + "namespace B {\n" + " int i;\n" + "}\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + "namespace B {\n" + " int i;\n" + "}\n" + "}")); + EXPECT_EQ("namespace A {\n" + "namespace B {\n" + " int i;\n" + " int j;\n" + "}// namespace B\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + "namespace B {\n" + " int i;\n" + " int j;\n" + "}\n" + "}")); + EXPECT_EQ("namespace A {\n" + " int a;\n" + " int b;\n" + "}// namespace A\n" + "namespace B {\n" + " int b;\n" + " int a;\n" + "}// namespace B", + fixNamespaceEndComments("namespace A {\n" + " int a;\n" + " int b;\n" + "}\n" + "namespace B {\n" + " int b;\n" + " int a;\n" + "}")); + EXPECT_EQ("namespace A {\n" + " int a1;\n" + " int a2;\n" + "}// namespace A\n" + "namespace A {\n" + " int a2;\n" + " int a1;\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + " int a1;\n" + " int a2;\n" + "}\n" + "namespace A {\n" + " int a2;\n" + " int a1;\n" + "}")); + EXPECT_EQ("namespace A {\n" + " int a;\n" + " int b;\n" + "}// namespace A\n" + "// comment about b\n" + "int b;", + fixNamespaceEndComments("namespace A {\n" + " int a;\n" + " int b;\n" + "}\n" + "// comment about b\n" + "int b;")); + + EXPECT_EQ("namespace A {\n" + "namespace B {\n" + "namespace C {\n" + "namespace D {\n" + "}\n" + "}// namespace C\n" + "}// namespace B\n" + "}// namespace A", + fixNamespaceEndComments("namespace A {\n" + "namespace B {\n" + "namespace C {\n" + "namespace D {\n" + "}\n" + "}\n" + "}\n" + "}")); + + // Adds an end comment after a semicolon. + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "};// namespace", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "};")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + " int j;\n" + "};// namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + " int j;\n" + "};")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + " int j;\n" + "};// namespace A\n" + "// unrelated", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + " int j;\n" + "};\n" + "// unrelated")); +} + +TEST_F(NamespaceEndCommentsFixerTest, AddsNewlineIfNeeded) { + EXPECT_EQ("namespace A {\n" + " int i;\n" + " int j;\n" + "}// namespace A\n" + " int k;", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + " int j;\n" + "} int k;")); + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "}// namespace\n" + " int k;", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "} int k;")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + " int j;\n" + "}// namespace A\n" + " namespace B {\n" + " int j;\n" + " int k;\n" + "}// namespace B", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + " int j;\n" + "} namespace B {\n" + " int j;\n" + " int k;\n" + "}")); + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "};// namespace\n" + "int k;", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "};int k;")); + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "};// namespace\n" + ";", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "};;")); +} + +TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddEndCommentForShortNamespace) { + EXPECT_EQ("namespace {}", fixNamespaceEndComments("namespace {}")); + EXPECT_EQ("namespace A {}", fixNamespaceEndComments("namespace A {}")); + EXPECT_EQ("namespace A { a }", + fixNamespaceEndComments("namespace A { a }")); + EXPECT_EQ("namespace A { a };", + fixNamespaceEndComments("namespace A { a };")); +} + +TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterUnaffectedRBrace) { + EXPECT_EQ("namespace A {\n" + " int i;\n" + "}", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "}", + // The range (16, 3) spans the 'int' above. + /*Ranges=*/{1, tooling::Range(16, 3)})); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "};", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "};", + // The range (16, 3) spans the 'int' above. + /*Ranges=*/{1, tooling::Range(16, 3)})); +} + +TEST_F(NamespaceEndCommentsFixerTest, DoesNotAddCommentAfterRBraceInPPDirective) { + EXPECT_EQ("#define SAD \\\n" + "namespace A { \\\n" + " int i; \\\n" + "}", + fixNamespaceEndComments("#define SAD \\\n" + "namespace A { \\\n" + " int i; \\\n" + "}")); +} + +TEST_F(NamespaceEndCommentsFixerTest, KeepsValidEndComment) { + EXPECT_EQ("namespace {\n" + " int i;\n" + "} // end anonymous namespace", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + "} // end anonymous namespace")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} /* end of namespace A */", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} /* end of namespace A */")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} // namespace A")); + EXPECT_EQ("namespace A::B {\n" + " int i;\n" + "} // end namespace A::B", + fixNamespaceEndComments("namespace A::B {\n" + " int i;\n" + "} // end namespace A::B")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "}; // end namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "}; // end namespace A")); + EXPECT_EQ("namespace {\n" + " int i;\n" + "}; /* unnamed namespace */", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + "}; /* unnamed namespace */")); +} + +TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndLineComment) { + EXPECT_EQ("namespace {\n" + " int i;\n" + "} // namespace", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + "} // namespace A")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} // namespace")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} //")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} //")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} // banamespace A")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "}; // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "}; // banamespace A")); + // Updates invalid line comments even for short namespaces. + EXPECT_EQ("namespace A {} // namespace A", + fixNamespaceEndComments("namespace A {} // namespace")); + EXPECT_EQ("namespace A {}; // namespace A", + fixNamespaceEndComments("namespace A {}; // namespace")); +} + +TEST_F(NamespaceEndCommentsFixerTest, UpdatesInvalidEndBlockComment) { + EXPECT_EQ("namespace {\n" + " int i;\n" + "} // namespace", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + "} /* namespace A */")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} /* end namespace */")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} /**/")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} /* end unnamed namespace */")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "} // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "} /* banamespace A */")); + EXPECT_EQ("namespace A {\n" + " int i;\n" + "}; // namespace A", + fixNamespaceEndComments("namespace A {\n" + " int i;\n" + "}; /* banamespace A */")); + EXPECT_EQ("namespace A {} // namespace A", + fixNamespaceEndComments("namespace A {} /**/")); + EXPECT_EQ("namespace A {}; // namespace A", + fixNamespaceEndComments("namespace A {}; /**/")); +} + +TEST_F(NamespaceEndCommentsFixerTest, + DoesNotAddEndCommentForNamespacesControlledByMacros) { + EXPECT_EQ("#ifdef 1\n" + "namespace A {\n" + "#elseif\n" + "namespace B {\n" + "#endif\n" + " int i;\n" + "}\n" + "}\n", + fixNamespaceEndComments("#ifdef 1\n" + "namespace A {\n" + "#elseif\n" + "namespace B {\n" + "#endif\n" + " int i;\n" + "}\n" + "}\n")); +} + +TEST_F(NamespaceEndCommentsFixerTest, + DoesNotAddEndCommentForNamespacesInMacroDeclarations) { + EXPECT_EQ("#ifdef 1\n" + "namespace A {\n" + "#elseif\n" + "namespace B {\n" + "#endif\n" + " int i;\n" + "}\n" + "}\n", + fixNamespaceEndComments("#ifdef 1\n" + "namespace A {\n" + "#elseif\n" + "namespace B {\n" + "#endif\n" + " int i;\n" + "}\n" + "}\n")); + EXPECT_EQ("namespace {\n" + " int i;\n" + " int j;\n" + "}// namespace\n" + "#if A\n" + " int i;\n" + "#else\n" + " int j;\n" + "#endif", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + " int j;\n" + "}\n" + "#if A\n" + " int i;\n" + "#else\n" + " int j;\n" + "#endif")); + EXPECT_EQ("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "}", + fixNamespaceEndComments("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "}")); + EXPECT_EQ("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "} // namespace A", + fixNamespaceEndComments("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "} // namespace A")); + EXPECT_EQ("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "} // namespace B", + fixNamespaceEndComments("#if A\n" + "namespace A {\n" + "#else\n" + "namespace B {\n" + "#endif\n" + "int i;\n" + "int j;\n" + "} // namespace B")); + EXPECT_EQ("namespace A\n" + "int i;\n" + "int j;\n" + "#if A\n" + "}\n" + "#else\n" + "}\n" + "#endif", + fixNamespaceEndComments("namespace A\n" + "int i;\n" + "int j;\n" + "#if A\n" + "}\n" + "#else\n" + "}\n" + "#endif")); + EXPECT_EQ("namespace A\n" + "int i;\n" + "int j;\n" + "#if A\n" + "} // namespace A\n" + "#else\n" + "} // namespace A\n" + "#endif", + fixNamespaceEndComments("namespace A\n" + "int i;\n" + "int j;\n" + "#if A\n" + "} // namespace A\n" + "#else\n" + "} // namespace A\n" + "#endif")); +} + +TEST_F(NamespaceEndCommentsFixerTest, + DoesNotAddEndCommentForUnbalancedRBracesAfterNamespaceEnd) { + EXPECT_EQ("namespace {\n" + " int i;\n" + "} // namespace\n" + "}", + fixNamespaceEndComments("namespace {\n" + " int i;\n" + "} // namespace\n" + "}")); +} + +TEST_F(NamespaceEndCommentsFixerTest, HandlesInlineAtEndOfLine_PR32438) { + EXPECT_EQ("template <int> struct a {};\n" + "struct a<bool{}> b() {\n" + "}\n" + "#define c inline\n" + "void d() {\n" + "}\n", + fixNamespaceEndComments("template <int> struct a {};\n" + "struct a<bool{}> b() {\n" + "}\n" + "#define c inline\n" + "void d() {\n" + "}\n")); +} +} // end namespace +} // end namespace format +} // end namespace clang |