diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 | 
| commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
| tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /unittests/Format/FormatTest.cpp | |
| parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) | |
Notes
Diffstat (limited to 'unittests/Format/FormatTest.cpp')
| -rw-r--r-- | unittests/Format/FormatTest.cpp | 508 | 
1 files changed, 492 insertions, 16 deletions
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index d9a16db74c889..8d46ba6efcfee 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -7,9 +7,14 @@  //  //===----------------------------------------------------------------------===// -#include "FormatTestUtils.h"  #include "clang/Format/Format.h" + +#include "../Tooling/RewriterTestContext.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" @@ -42,10 +47,10 @@ protected:        EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";      }      ReplacementCount = Replaces.size(); -    std::string Result = applyAllReplacements(Code, Replaces); -    EXPECT_NE("", Result); -    DEBUG(llvm::errs() << "\n" << Result << "\n\n"); -    return Result; +    auto Result = applyAllReplacements(Code, Replaces); +    EXPECT_TRUE(static_cast<bool>(Result)); +    DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); +    return *Result;    }    FormatStyle getLLVMStyleWithColumns(unsigned ColumnLimit) { @@ -291,11 +296,23 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {    verifyFormat("if (a)\n  if (b) {\n    f();\n  }\ng();");    FormatStyle AllowsMergedIf = getLLVMStyle(); +  AllowsMergedIf.AlignEscapedNewlinesLeft = true;    AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;    verifyFormat("if (a)\n"                 "  // comment\n"                 "  f();",                 AllowsMergedIf); +  verifyFormat("{\n" +               "  if (a)\n" +               "  label:\n" +               "    f();\n" +               "}", +               AllowsMergedIf); +  verifyFormat("#define A \\\n" +               "  if (a)  \\\n" +               "  label:  \\\n" +               "    f()", +               AllowsMergedIf);    verifyFormat("if (a)\n"                 "  ;",                 AllowsMergedIf); @@ -738,6 +755,7 @@ TEST_F(FormatTest, CaseRanges) {    verifyFormat("switch (x) {\n"                 "case 'A' ... 'Z':\n"                 "case 1 ... 5:\n" +               "case a ... b:\n"                 "  break;\n"                 "}");  } @@ -962,6 +980,14 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) {                     "// 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" @@ -1097,7 +1123,7 @@ TEST_F(FormatTest, RemovesTrailingWhitespaceOfComments) {  TEST_F(FormatTest, UnderstandsBlockComments) {    verifyFormat("f(/*noSpaceAfterParameterNamingComment=*/true);"); -  verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y); }"); +  verifyFormat("void f() { g(/*aaa=*/x, /*bbb=*/!y, /*c=*/::c); }");    EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n"              "  bbbbbbbbbbbbbbbbbbbbbbbbb);",              format("f(aaaaaaaaaaaaaaaaaaaaaaaaa ,   \\\n" @@ -1117,6 +1143,8 @@ TEST_F(FormatTest, UnderstandsBlockComments) {               "                      aaaaaaaaaaaaaaaaaa  ,\n"               "    aaaaaaaaaaaaaaaaaa) {   /*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/\n"               "}")); +  verifyFormat("f(/* aaaaaaaaaaaaaaaaaa = */\n" +               "  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);");    FormatStyle NoBinPacking = getLLVMStyle();    NoBinPacking.BinPackParameters = false; @@ -2741,6 +2769,12 @@ TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) {                 "  case 1:          \\\n"                 "  case 2\n",                 getLLVMStyleWithColumns(20)); +  verifyFormat("#define MACRO(a) \\\n" +               "  if (a)         \\\n" +               "    f();         \\\n" +               "  else           \\\n" +               "    g()", +               getLLVMStyleWithColumns(18));    verifyFormat("#define A template <typename T>");    verifyIncompleteFormat("#define STR(x) #x\n"                           "f(STR(this_is_a_string_literal{));"); @@ -3842,6 +3876,11 @@ TEST_F(FormatTest, BreaksFunctionDeclarations) {        "typename aaaaaaaaaa<aaaaaa>::aaaaaaaaaaa\n"        "aaaaaaaaaa<aaaaaa>::aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"        "    bool *aaaaaaaaaaaaaaaaaa, bool *aa) {}"); +  verifyGoogleFormat( +      "template <typename T>\n" +      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" +      "aaaaaaaaaaaaaaaaaaaaaaa<T>::aaaaaaaaaaaaa(\n" +      "    aaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaa);");    FormatStyle Style = getLLVMStyle();    Style.PointerAlignment = FormatStyle::PAS_Left; @@ -3979,6 +4018,12 @@ TEST_F(FormatTest, FunctionAnnotations) {                 "                << bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");    verifyFormat("TEST_F(ThisIsATestFixtureeeeeeeeeeeee,\n"                 "       ThisIsATestWithAReallyReallyReallyReallyLongName) {}"); +  verifyFormat("MACRO(abc).function() // wrap\n" +               "    << abc;"); +  verifyFormat("MACRO(abc)->function() // wrap\n" +               "    << abc;"); +  verifyFormat("MACRO(abc)::function() // wrap\n" +               "    << abc;");  }  TEST_F(FormatTest, BreaksDesireably) { @@ -4426,6 +4471,11 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) {        "    aaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));",        Style); +  verifyFormat("bbbbbbbbbbbb(aaaaaaaaaaaaaaaaaaaaaaaa, //\n" +               "    ccccccc(aaaaaaaaaaaaaaaaa,         //\n" +               "        b));", +               Style); +    Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak;    Style.BinPackArguments = false;    Style.BinPackParameters = false; @@ -4439,12 +4489,31 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) {                 "    aaaaaaaaaaa aaaaaaaaa,\n"                 "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);",                 Style); -  verifyFormat("SomeLongVariableName->someFunction(\n" -               "    foooooooo(\n" -               "        aaaaaaaaaaaaaaa,\n" -               "        aaaaaaaaaaaaaaaaaaaaa,\n" -               "        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));", +  verifyFormat("SomeLongVariableName->someFunction(foooooooo(\n" +               "    aaaaaaaaaaaaaaa,\n" +               "    aaaaaaaaaaaaaaaaaaaaa,\n" +               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa));",                 Style); +  verifyFormat( +      "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa(\n" +      "    aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)));", +      Style); +  verifyFormat( +      "aaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaa.aaaaaaaaaa(\n" +      "    aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)));", +      Style); +  verifyFormat( +      "aaaaaaaaaaaaaaaaaaaaaaaa(\n" +      "    aaaaaaaaaaaaaaaaaaaaa(\n" +      "        aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)),\n" +      "    aaaaaaaaaaaaaaaa);", +      Style); +  verifyFormat( +      "aaaaaaaaaaaaaaaaaaaaaaaa(\n" +      "    aaaaaaaaaaaaaaaaaaaaa(\n" +      "        aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaa)) &&\n" +      "    aaaaaaaaaaaaaaaa);", +      Style);  }  TEST_F(FormatTest, ParenthesesAndOperandAlignment) { @@ -4686,6 +4755,14 @@ TEST_F(FormatTest, BreaksConditionalExpressionsAfterOperator) {                 "                       ccccccccccccccc :\n"                 "                       ddddddddddddddd);",                 Style); +  verifyFormat("int i = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" +               "            /*bbbbbbbbbbbbbbb=*/bbbbbbbbbbbbbbbbbbbbbbbbb :\n" +               "            ccccccccccccccccccccccccccc;", +               Style); +  verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ?\n" +               "           aaaaa :\n" +               "           bbbbbbbbbbbbbbb + cccccccccccccccc;", +               Style);  }  TEST_F(FormatTest, DeclarationsOfMultipleVariables) { @@ -5083,6 +5160,13 @@ TEST_F(FormatTest, AlignsPipes) {                 "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;");    verifyFormat("SemaRef.Diag(Loc, diag::note_for_range_begin_end)\n"                 "    << BEF << IsTemplate << Description << E->getType();"); +  verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n" +               "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" +               "           aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); +  verifyFormat("Diag(aaaaaaaaaaaaaaaaaaaa, aaaaaaaa)\n" +               "    << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" +               "           aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa)\n" +               "    << aaa;");    verifyFormat(        "llvm::errs() << aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -5306,6 +5390,10 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) {    verifyFormat("template <typename T> // T can be A, B or C.\n"                 "struct C {};",                 AlwaysBreak); +  verifyFormat("template <enum E> class A {\n" +               "public:\n" +               "  E *f();\n" +               "};");  }  TEST_F(FormatTest, WrapsAtNestedNameSpecifiers) { @@ -5382,6 +5470,10 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) {    verifyFormat("struct A<std::enable_if<sizeof(T2) ? sizeof(int32) : "                 "sizeof(char)>::type>;");    verifyFormat("template <class T> struct S<std::is_arithmetic<T>{}> {};"); +  verifyFormat("f(a.operator()<A>());"); +  verifyFormat("f(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" +               "      .template operator()<A>());", +               getLLVMStyleWithColumns(35));    // Not template parameters.    verifyFormat("return a < b && c > d;"); @@ -5402,6 +5494,7 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) {  TEST_F(FormatTest, UnderstandsBinaryOperators) {    verifyFormat("COMPARE(a, ==, b);"); +  verifyFormat("auto s = sizeof...(Ts) - 1;");  }  TEST_F(FormatTest, UnderstandsPointersToMembers) { @@ -5534,14 +5627,21 @@ TEST_F(FormatTest, UnderstandsFunctionRefQualification) {    verifyFormat("SomeType MemberFunction(const Deleted &) && {}");    verifyFormat("SomeType MemberFunction(const Deleted &) && final {}");    verifyFormat("SomeType MemberFunction(const Deleted &) && override {}"); +  verifyFormat("SomeType MemberFunction(const Deleted &) const &;");    FormatStyle AlignLeft = getLLVMStyle();    AlignLeft.PointerAlignment = FormatStyle::PAS_Left; +  verifyFormat("void A::b() && {}", AlignLeft);    verifyFormat("Deleted& operator=(const Deleted&) & = default;", AlignLeft);    verifyFormat("SomeType MemberFunction(const Deleted&) & = delete;",                 AlignLeft);    verifyFormat("Deleted& operator=(const Deleted&) &;", AlignLeft);    verifyFormat("SomeType MemberFunction(const Deleted&) &;", AlignLeft); +  verifyFormat("auto Function(T t) & -> void {}", AlignLeft); +  verifyFormat("auto Function(T... t) & -> void {}", AlignLeft); +  verifyFormat("auto Function(T) & -> void {}", AlignLeft); +  verifyFormat("auto Function(T) & -> void;", AlignLeft); +  verifyFormat("SomeType MemberFunction(const Deleted&) const &;", AlignLeft);    FormatStyle Spaces = getLLVMStyle();    Spaces.SpacesInCStyleCastParentheses = true; @@ -5626,6 +5726,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {    verifyFormat("[](const decltype(*a) &value) {}");    verifyFormat("decltype(a * b) F();");    verifyFormat("#define MACRO() [](A *a) { return 1; }"); +  verifyFormat("Constructor() : member([](A *a, B *b) {}) {}");    verifyIndependentOfContext("typedef void (*f)(int *a);");    verifyIndependentOfContext("int i{a * b};");    verifyIndependentOfContext("aaa && aaa->f();"); @@ -5654,6 +5755,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"        "    aaaaaaaaaaaaaaaaaaaaaaaaaaaa, *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); +  verifyGoogleFormat("int const* a = &b;");    verifyGoogleFormat("**outparam = 1;");    verifyGoogleFormat("*outparam = a * b;");    verifyGoogleFormat("int main(int argc, char** argv) {}"); @@ -5922,6 +6024,7 @@ TEST_F(FormatTest, FormatsCasts) {    verifyFormat("my_int a = (my_int)(my_int)-1;");    verifyFormat("my_int a = (ns::my_int)-2;");    verifyFormat("case (my_int)ONE:"); +  verifyFormat("auto x = (X)this;");    // FIXME: single value wrapped with paren will be treated as cast.    verifyFormat("void f(int i = (kValue)*kMask) {}"); @@ -5995,6 +6098,7 @@ TEST_F(FormatTest, FormatsFunctionTypes) {    verifyFormat("some_var = function(*some_pointer_var)[0];");    verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }");    verifyFormat("int x = f(&h)();"); +  verifyFormat("returnsFunction(¶m1, ¶m2)(param);");  }  TEST_F(FormatTest, FormatsPointersToArrayTypes) { @@ -6038,6 +6142,10 @@ TEST_F(FormatTest, BreaksLongDeclarations) {                 "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");    verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"                 "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}"); +  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" +               "LooooooooooooooooooooooooooongFunctionDeclaration(T... t);"); +  verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" +               "LooooooooooooooooooooooooooongFunctionDeclaration(T /*t*/) {}");    FormatStyle Indented = getLLVMStyle();    Indented.IndentWrappedFunctionNames = true;    verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n" @@ -6126,6 +6234,8 @@ TEST_F(FormatTest, FormatsArrays) {        "llvm::outs() << \"aaaaaaaaaaaa: \"\n"        "             << (*aaaaaaaiaaaaaaa)[aaaaaaaaaaaaaaaaaaaaaaaaa]\n"        "                                  [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];"); +  verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaaaaaaa][a]\n" +               "    .aaaaaaaaaaaaaaaaaaaaaa();");    verifyGoogleFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<int>\n"                       "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa[aaaaaaaaaaaa];"); @@ -6133,6 +6243,7 @@ TEST_F(FormatTest, FormatsArrays) {        "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n"        "                                  .aaaaaaa[0]\n"        "                                  .aaaaaaaaaaaaaaaaaaaaaa();"); +  verifyFormat("a[::b::c];");    verifyNoCrash("a[,Y?)]", getLLVMStyleWithColumns(10)); @@ -6607,7 +6718,7 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) {                 "                   bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};");    verifyNoCrash("a<,"); -   +    // No braced initializer here.    verifyFormat("void f() {\n"                 "  struct Dummy {};\n" @@ -6918,6 +7029,14 @@ TEST_F(FormatTest, BlockComments) {                     "* 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; @@ -7026,10 +7145,9 @@ TEST_F(FormatTest, BlockCommentsAtEndOfLine) {  }  TEST_F(FormatTest, IndentLineCommentsInStartOfBlockAtEndOfFile) { -  // FIXME: This is not what we want...    verifyFormat("{\n" -               "// a" -               "// b"); +               "  // a\n" +               "  // b");  }  TEST_F(FormatTest, FormatStarDependingOnContext) { @@ -7949,6 +8067,10 @@ TEST_F(FormatTest, BreaksStringLiterals) {                     "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"});",                     getGoogleStyle())); +  FormatStyle Style = getLLVMStyleWithColumns(12); +  Style.BreakStringLiterals = false; +  EXPECT_EQ("\"some text other\";", format("\"some text other\";", Style)); +    FormatStyle AlignLeft = getLLVMStyleWithColumns(12);    AlignLeft.AlignEscapedNewlinesLeft = true;    EXPECT_EQ("#define A \\\n" @@ -8484,6 +8606,230 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {                     "\t */\n"                     "\t int i;\n"                     "}")); + +  Tab.UseTab = FormatStyle::UT_ForContinuationAndIndentation; +  Tab.TabWidth = 8; +  Tab.IndentWidth = 8; +  EXPECT_EQ("if (aaaaaaaa && // q\n" +            "    bb)         // w\n" +            "\t;", +            format("if (aaaaaaaa &&// q\n" +                   "bb)// w\n" +                   ";", +                   Tab)); +  EXPECT_EQ("if (aaa && bbb) // w\n" +            "\t;", +            format("if(aaa&&bbb)// w\n" +                   ";", +                   Tab)); +  verifyFormat("class X {\n" +               "\tvoid f() {\n" +               "\t\tsomeFunction(parameter1,\n" +               "\t\t\t     parameter2);\n" +               "\t}\n" +               "};", +               Tab); +  verifyFormat("#define A                        \\\n" +               "\tvoid f() {               \\\n" +               "\t\tsomeFunction(    \\\n" +               "\t\t    parameter1,  \\\n" +               "\t\t    parameter2); \\\n" +               "\t}", +               Tab); +  Tab.TabWidth = 4; +  Tab.IndentWidth = 8; +  verifyFormat("class TabWidth4Indent8 {\n" +               "\t\tvoid f() {\n" +               "\t\t\t\tsomeFunction(parameter1,\n" +               "\t\t\t\t\t\t\t parameter2);\n" +               "\t\t}\n" +               "};", +               Tab); +  Tab.TabWidth = 4; +  Tab.IndentWidth = 4; +  verifyFormat("class TabWidth4Indent4 {\n" +               "\tvoid f() {\n" +               "\t\tsomeFunction(parameter1,\n" +               "\t\t\t\t\t parameter2);\n" +               "\t}\n" +               "};", +               Tab); +  Tab.TabWidth = 8; +  Tab.IndentWidth = 4; +  verifyFormat("class TabWidth8Indent4 {\n" +               "    void f() {\n" +               "\tsomeFunction(parameter1,\n" +               "\t\t     parameter2);\n" +               "    }\n" +               "};", +               Tab); +  Tab.TabWidth = 8; +  Tab.IndentWidth = 8; +  EXPECT_EQ("/*\n" +            "\t      a\t\tcomment\n" +            "\t      in multiple lines\n" +            "       */", +            format("   /*\t \t \n" +                   " \t \t a\t\tcomment\t \t\n" +                   " \t \t in multiple lines\t\n" +                   " \t  */", +                   Tab)); +  verifyFormat("{\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "\taaaaaaaaaaaaaaaaaaaaaaaaaaaa();\n" +               "};", +               Tab); +  verifyFormat("enum AA {\n" +               "\ta1, // Force multiple lines\n" +               "\ta2,\n" +               "\ta3\n" +               "};", +               Tab); +  EXPECT_EQ("if (aaaaaaaa && // q\n" +            "    bb)         // w\n" +            "\t;", +            format("if (aaaaaaaa &&// q\n" +                   "bb)// w\n" +                   ";", +                   Tab)); +  verifyFormat("class X {\n" +               "\tvoid f() {\n" +               "\t\tsomeFunction(parameter1,\n" +               "\t\t\t     parameter2);\n" +               "\t}\n" +               "};", +               Tab); +  verifyFormat("{\n" +               "\tQ(\n" +               "\t    {\n" +               "\t\t    int a;\n" +               "\t\t    someFunction(aaaaaaaa,\n" +               "\t\t\t\t bbbbbbb);\n" +               "\t    },\n" +               "\t    p);\n" +               "}", +               Tab); +  EXPECT_EQ("{\n" +            "\t/* aaaa\n" +            "\t   bbbb */\n" +            "}", +            format("{\n" +                   "/* aaaa\n" +                   "   bbbb */\n" +                   "}", +                   Tab)); +  EXPECT_EQ("{\n" +            "\t/*\n" +            "\t  aaaaaaaaaaaaaaaaaaaaaaaaaa\n" +            "\t  bbbbbbbbbbbbb\n" +            "\t*/\n" +            "}", +            format("{\n" +                   "/*\n" +                   "  aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" +                   "*/\n" +                   "}", +                   Tab)); +  EXPECT_EQ("{\n" +            "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa\n" +            "\t// bbbbbbbbbbbbb\n" +            "}", +            format("{\n" +                   "\t// aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" +                   "}", +                   Tab)); +  EXPECT_EQ("{\n" +            "\t/*\n" +            "\t  aaaaaaaaaaaaaaaaaaaaaaaaaa\n" +            "\t  bbbbbbbbbbbbb\n" +            "\t*/\n" +            "}", +            format("{\n" +                   "\t/*\n" +                   "\t  aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbb\n" +                   "\t*/\n" +                   "}", +                   Tab)); +  EXPECT_EQ("{\n" +            "\t/*\n" +            "\n" +            "\t*/\n" +            "}", +            format("{\n" +                   "\t/*\n" +                   "\n" +                   "\t*/\n" +                   "}", +                   Tab)); +  EXPECT_EQ("{\n" +            "\t/*\n" +            " asdf\n" +            "\t*/\n" +            "}", +            format("{\n" +                   "\t/*\n" +                   " asdf\n" +                   "\t*/\n" +                   "}", +                   Tab)); +  EXPECT_EQ("/*\n" +            "\t      a\t\tcomment\n" +            "\t      in multiple lines\n" +            "       */", +            format("   /*\t \t \n" +                   " \t \t a\t\tcomment\t \t\n" +                   " \t \t in multiple lines\t\n" +                   " \t  */", +                   Tab)); +  EXPECT_EQ("/* some\n" +            "   comment */", +            format(" \t \t /* some\n" +                   " \t \t    comment */", +                   Tab)); +  EXPECT_EQ("int a; /* some\n" +            "   comment */", +            format(" \t \t int a; /* some\n" +                   " \t \t    comment */", +                   Tab)); +  EXPECT_EQ("int a; /* some\n" +            "comment */", +            format(" \t \t int\ta; /* some\n" +                   " \t \t    comment */", +                   Tab)); +  EXPECT_EQ("f(\"\t\t\"); /* some\n" +            "    comment */", +            format(" \t \t f(\"\t\t\"); /* some\n" +                   " \t \t    comment */", +                   Tab)); +  EXPECT_EQ("{\n" +            "  /*\n" +            "   * Comment\n" +            "   */\n" +            "  int i;\n" +            "}", +            format("{\n" +                   "\t/*\n" +                   "\t * Comment\n" +                   "\t */\n" +                   "\t int i;\n" +                   "}")); +  Tab.AlignConsecutiveAssignments = true; +  Tab.AlignConsecutiveDeclarations = true; +  Tab.TabWidth = 4; +  Tab.IndentWidth = 4; +  verifyFormat("class Assign {\n" +               "\tvoid f() {\n" +               "\t\tint         x      = 123;\n" +               "\t\tint         random = 4;\n" +               "\t\tstd::string alphabet =\n" +               "\t\t\t\"abcdefghijklmnopqrstuvwxyz\";\n" +               "\t}\n" +               "};", +               Tab);  }  TEST_F(FormatTest, CalculatesOriginalColumn) { @@ -8644,7 +8990,8 @@ TEST_F(FormatTest, ConfigurableSpacesInParentheses) {    verifyFormat("#define x (( int )-1)", Spaces);    // Run the first set of tests again with: -  Spaces.SpacesInParentheses = false, Spaces.SpaceInEmptyParentheses = true; +  Spaces.SpacesInParentheses = false; +  Spaces.SpaceInEmptyParentheses = true;    Spaces.SpacesInCStyleCastParentheses = true;    verifyFormat("call(x, y, z);", Spaces);    verifyFormat("call( );", Spaces); @@ -9814,8 +10161,10 @@ TEST_F(FormatTest, ParsesConfigurationBools) {    CHECK_PARSE_BOOL(AlwaysBreakTemplateDeclarations);    CHECK_PARSE_BOOL(BinPackArguments);    CHECK_PARSE_BOOL(BinPackParameters); +  CHECK_PARSE_BOOL(BreakAfterJavaFieldAnnotations);    CHECK_PARSE_BOOL(BreakBeforeTernaryOperators);    CHECK_PARSE_BOOL(BreakConstructorInitializersBeforeComma); +  CHECK_PARSE_BOOL(BreakStringLiterals);    CHECK_PARSE_BOOL(ConstructorInitializerAllOnOneLineOrOnePerLine);    CHECK_PARSE_BOOL(DerivePointerAlignment);    CHECK_PARSE_BOOL_FIELD(DerivePointerAlignment, "DerivePointerBinding"); @@ -9870,6 +10219,7 @@ TEST_F(FormatTest, ParsesConfiguration) {                SpacesBeforeTrailingComments, 1234u);    CHECK_PARSE("IndentWidth: 32", IndentWidth, 32u);    CHECK_PARSE("ContinuationIndentWidth: 11", ContinuationIndentWidth, 11u); +  CHECK_PARSE("CommentPragmas: '// abc$'", CommentPragmas, "// abc$");    Style.PointerAlignment = FormatStyle::PAS_Middle;    CHECK_PARSE("PointerAlignment: Left", PointerAlignment, @@ -9923,6 +10273,8 @@ TEST_F(FormatTest, ParsesConfiguration) {    CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);    CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);    CHECK_PARSE("UseTab: Always", UseTab, FormatStyle::UT_Always); +  CHECK_PARSE("UseTab: ForContinuationAndIndentation", UseTab, +              FormatStyle::UT_ForContinuationAndIndentation);    // For backward compatibility:    CHECK_PARSE("UseTab: false", UseTab, FormatStyle::UT_Never);    CHECK_PARSE("UseTab: true", UseTab, FormatStyle::UT_Always); @@ -10028,6 +10380,7 @@ TEST_F(FormatTest, ParsesConfiguration) {                "  - Regex: .*\n"                "    Priority: 1",                IncludeCategories, ExpectedCategories); +  CHECK_PARSE("IncludeIsMainRegex: 'abc$'", IncludeIsMainRegex, "abc$");  }  TEST_F(FormatTest, ParsesConfigurationWithLanguages) { @@ -10309,6 +10662,15 @@ TEST_F(FormatTest, ConstructorInitializerIndentWidth) {        ": aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa),\n"        "  aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {}",        Style); +  Style.AlignAfterOpenBracket = FormatStyle::BAS_AlwaysBreak; +  verifyFormat( +      "SomeLongTemplateVariableName<\n" +      "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa>", +      Style); +  verifyFormat( +      "bool smaller = 1 < bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb(\n" +      "                       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa);", +      Style);  }  TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) { @@ -10328,6 +10690,9 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {    verifyFormat("SomeClass::Constructor()\n"                 "    : a(a) {}",                 Style); +  verifyFormat("SomeClass::Constructor() noexcept\n" +               "    : a(a) {}", +               Style);    verifyFormat("SomeClass::Constructor()\n"                 "    : a(a)\n"                 "    , b(b)\n" @@ -10637,6 +11002,10 @@ TEST_F(FormatTest, FormatsLambdas) {        "      return aaaaaaaaaaaaaaaaa;\n"        "    });",        getLLVMStyleWithColumns(70)); +  verifyFormat("[]() //\n" +               "    -> int {\n" +               "  return 1; //\n" +               "};");    // Multiple lambdas in the same parentheses change indentation rules.    verifyFormat("SomeFunction(\n" @@ -11114,6 +11483,113 @@ TEST_F(FormatTest, FormatsTableGenCode) {    verifyFormat("include \"a.td\"\ninclude \"b.td\"", Style);  } +// Since this test case uses UNIX-style file path. We disable it for MS +// compiler. +#if !defined(_MSC_VER) && !defined(__MINGW32__) + +TEST(FormatStyle, GetStyleOfFile) { +  vfs::InMemoryFileSystem FS; +  // Test 1: format file in the same directory. +  ASSERT_TRUE( +      FS.addFile("/a/.clang-format", 0, +                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM"))); +  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()); + +  // Test 2: 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()); + +  // Test 3: format file in parent directory. +  ASSERT_TRUE( +      FS.addFile("/c/.clang-format", 0, +                 llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google"))); +  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()); +} + +#endif // _MSC_VER + +class ReplacementTest : public ::testing::Test { +protected: +  tooling::Replacement createReplacement(SourceLocation Start, unsigned Length, +                                         llvm::StringRef ReplacementText) { +    return tooling::Replacement(Context.Sources, Start, Length, +                                ReplacementText); +  } + +  RewriterTestContext Context; +}; + +TEST_F(ReplacementTest, FormatCodeAfterReplacements) { +  // Column limit is 20. +  std::string Code = "Type *a =\n" +                     "    new Type();\n" +                     "g(iiiii, 0, jjjjj,\n" +                     "  0, kkkkk, 0, mm);\n" +                     "int  bad     = format   ;"; +  std::string Expected = "auto a = new Type();\n" +                         "g(iiiii, nullptr,\n" +                         "  jjjjj, nullptr,\n" +                         "  kkkkk, nullptr,\n" +                         "  mm);\n" +                         "int  bad     = format   ;"; +  FileID ID = Context.createInMemoryFile("format.cpp", Code); +  tooling::Replacements Replaces; +  Replaces.insert(tooling::Replacement( +      Context.Sources, Context.getLocation(ID, 1, 1), 6, "auto ")); +  Replaces.insert(tooling::Replacement( +      Context.Sources, Context.getLocation(ID, 3, 10), 1, "nullptr")); +  Replaces.insert(tooling::Replacement( +      Context.Sources, Context.getLocation(ID, 4, 3), 1, "nullptr")); +  Replaces.insert(tooling::Replacement( +      Context.Sources, Context.getLocation(ID, 4, 13), 1, "nullptr")); + +  format::FormatStyle Style = format::getLLVMStyle(); +  Style.ColumnLimit = 20; // Set column limit to 20 to increase readibility. +  auto FormattedReplaces = formatReplacements(Code, Replaces, Style); +  EXPECT_TRUE(static_cast<bool>(FormattedReplaces)) +      << llvm::toString(FormattedReplaces.takeError()) << "\n"; +  auto Result = applyAllReplacements(Code, *FormattedReplaces); +  EXPECT_TRUE(static_cast<bool>(Result)); +  EXPECT_EQ(Expected, *Result); +} + +TEST_F(ReplacementTest, SortIncludesAfterReplacement) { +  std::string Code = "#include \"a.h\"\n" +                     "#include \"c.h\"\n" +                     "\n" +                     "int main() {\n" +                     "  return 0;\n" +                     "}"; +  std::string Expected = "#include \"a.h\"\n" +                         "#include \"b.h\"\n" +                         "#include \"c.h\"\n" +                         "\n" +                         "int main() {\n" +                         "  return 0;\n" +                         "}"; +  FileID ID = Context.createInMemoryFile("fix.cpp", Code); +  tooling::Replacements Replaces; +  Replaces.insert(tooling::Replacement( +      Context.Sources, Context.getLocation(ID, 1, 1), 0, "#include \"b.h\"\n")); + +  format::FormatStyle Style = format::getLLVMStyle(); +  Style.SortIncludes = true; +  auto FormattedReplaces = formatReplacements(Code, Replaces, Style); +  EXPECT_TRUE(static_cast<bool>(FormattedReplaces)) +      << llvm::toString(FormattedReplaces.takeError()) << "\n"; +  auto Result = applyAllReplacements(Code, *FormattedReplaces); +  EXPECT_TRUE(static_cast<bool>(Result)); +  EXPECT_EQ(Expected, *Result); +} +  } // end namespace  } // end namespace format  } // end namespace clang  | 
