brintos

brintos / llvm-project-archived public Read only

0
0
Text · 52.7 KiB · d7fb15d Raw
1730 lines · cpp
1//===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FormatTestBase.h"10 11#define DEBUG_TYPE "format-test"12 13namespace clang {14namespace format {15namespace test {16namespace {17 18class FormatTestCSharp : public test::FormatTestBase {19protected:20  FormatStyle getDefaultStyle() const override {21    return getMicrosoftStyle(FormatStyle::LK_CSharp);22  }23 24  static std::string format(StringRef Code, unsigned Offset, unsigned Length,25                            const FormatStyle &Style) {26    LLVM_DEBUG(llvm::errs() << "---\n");27    LLVM_DEBUG(llvm::errs() << Code << "\n\n");28    std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));29    tooling::Replacements Replaces = reformat(Style, Code, Ranges);30    auto Result = applyAllReplacements(Code, Replaces);31    EXPECT_TRUE(static_cast<bool>(Result));32    LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");33    return *Result;34  }35 36  static std::string37  format(StringRef Code,38         const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {39    return format(Code, 0, Code.size(), Style);40  }41 42  static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {43    FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);44    Style.ColumnLimit = ColumnLimit;45    return Style;46  }47};48 49TEST_F(FormatTestCSharp, CSharpClass) {50  verifyFormat("public class SomeClass\n"51               "{\n"52               "    void f()\n"53               "    {\n"54               "    }\n"55               "    int g()\n"56               "    {\n"57               "        return 0;\n"58               "    }\n"59               "    void h()\n"60               "    {\n"61               "        while (true)\n"62               "            f();\n"63               "        for (;;)\n"64               "            f();\n"65               "        if (true)\n"66               "            f();\n"67               "    }\n"68               "}");69 70  // Ensure that small and empty classes are handled correctly with condensed71  // (Google C++-like) brace-breaking style.72  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);73  Style.BreakBeforeBraces = FormatStyle::BS_Attach;74 75  verifyFormat("public class SomeEmptyClass {}", Style);76 77  verifyFormat("public class SomeTinyClass {\n"78               "  int X;\n"79               "}",80               Style);81  verifyFormat("private class SomeTinyClass {\n"82               "  int X;\n"83               "}",84               Style);85  verifyFormat("protected class SomeTinyClass {\n"86               "  int X;\n"87               "}",88               Style);89  verifyFormat("internal class SomeTinyClass {\n"90               "  int X;\n"91               "}",92               Style);93}94 95TEST_F(FormatTestCSharp, AccessModifiers) {96  verifyFormat("public String toString()\n"97               "{\n"98               "}");99  verifyFormat("private String toString()\n"100               "{\n"101               "}");102  verifyFormat("protected String toString()\n"103               "{\n"104               "}");105  verifyFormat("internal String toString()\n"106               "{\n"107               "}");108 109  verifyFormat("public override String toString()\n"110               "{\n"111               "}");112  verifyFormat("private override String toString()\n"113               "{\n"114               "}");115  verifyFormat("protected override String toString()\n"116               "{\n"117               "}");118  verifyFormat("internal override String toString()\n"119               "{\n"120               "}");121 122  verifyFormat("internal static String toString()\n"123               "{\n"124               "}");125}126 127TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {128  // Breaking of interpolated strings is not implemented.129  auto Style = getDefaultStyle();130  Style.ColumnLimit = 40;131  Style.BreakStringLiterals = true;132  verifyFormat("foo("133               "$\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"134               "aaaaaaa\");",135               Style);136}137 138TEST_F(FormatTestCSharp, StringLiteralBreaks) {139  // The line is 75 characters long.  The default limit for the Microsoft style140  // is 120.141  auto Style = getDefaultStyle();142  Style.BreakStringLiterals = true;143  verifyFormat("foo("144               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"145               "aaaaaa\");",146               Style);147  // When the column limit is smaller, the string should get broken.148  Style.ColumnLimit = 40;149  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +150    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +151    "aaa");)",152               "foo("153               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"154               "aaaaaa\");",155               Style);156  // The new quotes should be the same as the original.157  verifyFormat(R"(foo(@"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +158    @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +159    @"aaaaa");)",160               "foo("161               "@\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"162               "aaaaaaa\");",163               Style);164  // The operators can be on either line.165  Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;166  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"167    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"168    + "a");)",169               "foo("170               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"171               "aaaaaa\");",172               Style);173  Style.AlignOperands = FormatStyle::OAS_AlignAfterOperator;174  verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"175    + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"176    + "a");)",177               "foo("178               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"179               "aaaaaa\");",180               Style);181  verifyFormat(R"(x = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"182  + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";)",183               "x = "184               "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"185               "aaaaaa\";",186               Style);187}188 189TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {190  verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");191  // @"ABC\" + ToString("B") - handle embedded \ in literal string at192  // the end193  //194  /*195   * After removal of Lexer change we are currently not able196   * To handle these cases197   verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");198   verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");199   verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");200   verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");201  */202}203 204TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {205  verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");206  verifyFormat("foo($\"aaaa{A}\");");207  verifyFormat(208      "foo($\"aaaa{A}"209      "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");210  verifyFormat("Name = $\"{firstName} {lastName}\";");211 212  // $"ABC\" + ToString("B") - handle embedded \ in literal string at213  // the end214  verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");215  verifyFormat("$\"{domain}\\\\{user}\"");216  verifyFormat(217      "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");218}219 220TEST_F(FormatTestCSharp, CSharpFatArrows) {221  verifyIncompleteFormat("Task serverTask = Task.Run(async() => {");222  verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");223}224 225TEST_F(FormatTestCSharp, CSharpConditionalExpressions) {226  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);227  // conditional expression is not seen as a NullConditional.228  verifyFormat("var y = A < B ? -1 : 1;", Style);229}230 231TEST_F(FormatTestCSharp, CSharpNullConditional) {232  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);233  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;234 235  verifyFormat(236      "public Person(string firstName, string lastName, int? age = null)");237 238  verifyFormat("foo () {\n"239               "  switch (args?.Length) {}\n"240               "}",241               Style);242 243  verifyFormat("switch (args?.Length) {}", Style);244 245  verifyFormat("public static void Main(string[] args)\n"246               "{\n"247               "    string dirPath = args?[0];\n"248               "}");249 250  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;251 252  verifyFormat("switch(args?.Length) {}", Style);253}254 255TEST_F(FormatTestCSharp, Attributes) {256  verifyFormat("[STAThread]\n"257               "static void Main(string[] args)\n"258               "{\n"259               "}");260 261  verifyFormat("[TestMethod]\n"262               "private class Test\n"263               "{\n"264               "}");265 266  verifyFormat("[TestMethod]\n"267               "protected class Test\n"268               "{\n"269               "}");270 271  verifyFormat("[TestMethod]\n"272               "internal class Test\n"273               "{\n"274               "}");275 276  verifyFormat("[TestMethod]\n"277               "class Test\n"278               "{\n"279               "}");280 281  verifyFormat("[TestMethod]\n"282               "[DeploymentItem(\"Test.txt\")]\n"283               "public class Test\n"284               "{\n"285               "}");286 287  verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"288               "[System.Runtime.InteropServices.ComVisible(true)]\n"289               "public sealed class STAThreadAttribute : Attribute\n"290               "{\n"291               "}");292 293  verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "294               "provided port\")]\n"295               "class Test\n"296               "{\n"297               "}");298 299  verifyFormat("[TestMethod]\n"300               "public string Host { set; get; }");301 302  // Adjacent properties should not cause line wrapping issues303  verifyFormat("[JsonProperty(\"foo\")]\n"304               "public string Foo { set; get; }\n"305               "[JsonProperty(\"bar\")]\n"306               "public string Bar { set; get; }\n"307               "[JsonProperty(\"bar\")]\n"308               "protected string Bar { set; get; }\n"309               "[JsonProperty(\"bar\")]\n"310               "internal string Bar { set; get; }");311 312  // Multiple attributes should always be split (not just the first ones)313  verifyFormat("[XmlIgnore]\n"314               "[JsonProperty(\"foo\")]\n"315               "public string Foo { set; get; }");316 317  verifyFormat("[XmlIgnore]\n"318               "[JsonProperty(\"foo\")]\n"319               "public string Foo { set; get; }\n"320               "[XmlIgnore]\n"321               "[JsonProperty(\"bar\")]\n"322               "public string Bar { set; get; }");323 324  verifyFormat("[XmlIgnore]\n"325               "[ScriptIgnore]\n"326               "[JsonProperty(\"foo\")]\n"327               "public string Foo { set; get; }\n"328               "[XmlIgnore]\n"329               "[ScriptIgnore]\n"330               "[JsonProperty(\"bar\")]\n"331               "public string Bar { set; get; }");332 333  verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "334               "listening on provided host\")]\n"335               "public string Host { set; get; }");336 337  verifyIncompleteFormat(338      "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n"339      "// The const char* returned by hello_world must not be deleted.\n"340      "private static extern IntPtr HelloFromCpp();)");341 342  // Class attributes go on their own line and do not affect layout of343  // interfaces. Line wrapping decisions previously caused each interface to be344  // on its own line.345  verifyFormat("[SomeAttribute]\n"346               "[SomeOtherAttribute]\n"347               "public class A : IShape, IAnimal, IVehicle\n"348               "{\n"349               "    int X;\n"350               "}");351 352  // Attributes in a method declaration do not cause line wrapping.353  verifyFormat("void MethodA([In][Out] ref double x)\n"354               "{\n"355               "}");356 357  verifyFormat("void MethodA([In, Out] ref double x)\n"358               "{\n"359               "}");360 361  verifyFormat("void MethodA([In, Out] double[] x)\n"362               "{\n"363               "}");364 365  verifyFormat("void MethodA([In] double[] x)\n"366               "{\n"367               "}");368 369  verifyFormat("void MethodA(int[] x)\n"370               "{\n"371               "}");372  verifyFormat("void MethodA(int[][] x)\n"373               "{\n"374               "}");375  verifyFormat("void MethodA([] x)\n"376               "{\n"377               "}");378 379  verifyFormat("public void Log([CallerLineNumber] int line = -1, "380               "[CallerFilePath] string path = null,\n"381               "                [CallerMemberName] string name = null)\n"382               "{\n"383               "}");384 385  // [] in an attribute do not cause premature line wrapping or indenting.386  verifyFormat(R"(//387public class A388{389    [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)]390    [DoNotSerialize]391    public Data MemberVariable;392})");393 394  //  Unwrappable lines go on a line of their own.395  // 'target:' is not treated as a label.396  // Modify Style to enforce a column limit.397  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);398  Style.ColumnLimit = 10;399  verifyFormat(R"([assembly:InternalsVisibleTo(400    "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])",401               Style);402}403 404TEST_F(FormatTestCSharp, CSharpUsing) {405  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);406  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;407  verifyFormat("public void foo () {\n"408               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"409               "  using () {}\n"410               "}",411               Style);412 413  // Ensure clang-format affects top-level snippets correctly.414  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",415               Style);416 417  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;418  verifyFormat("public void foo() {\n"419               "  using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"420               "  using() {}\n"421               "}",422               Style);423 424  // Ensure clang-format affects top-level snippets correctly.425  verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",426               Style);427 428  Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;429  verifyFormat("public void foo() {\n"430               "  using (StreamWriter sw = new StreamWriter(filenameA)) {}\n"431               "  using () {}\n"432               "}",433               Style);434 435  // Ensure clang-format affects top-level snippets correctly.436  verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}",437               Style);438 439  Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;440  verifyFormat("public void foo() {\n"441               "  using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"442               "  using() {}\n"443               "}",444               Style);445 446  // Ensure clang-format affects top-level snippets correctly.447  verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",448               Style);449}450 451TEST_F(FormatTestCSharp, CSharpRegions) {452  verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "453               "aaaaaaaaaaaaaaa long region");454}455 456TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {457  // AfterEnum is true by default.458  verifyFormat("public enum var\n"459               "{\n"460               "    none,\n"461               "    @string,\n"462               "    bool,\n"463               "    @enum\n"464               "}");465}466 467TEST_F(FormatTestCSharp, CSharpNullCoalescing) {468  verifyFormat("var test = ABC ?? DEF");469  verifyFormat("string myname = name ?? \"ABC\";");470  verifyFormat("return _name ?? \"DEF\";");471}472 473TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) {474  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);475  Style.SpaceBeforeAssignmentOperators = true;476 477  verifyFormat(R"(test ??= ABC;)", Style);478  verifyFormat(R"(test ??= true;)", Style);479 480  Style.SpaceBeforeAssignmentOperators = false;481 482  verifyFormat(R"(test??= ABC;)", Style);483  verifyFormat(R"(test??= true;)", Style);484}485 486TEST_F(FormatTestCSharp, CSharpNullForgiving) {487  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);488 489  verifyFormat("var test = null!;", Style);490  verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style);491  verifyFormat("int test = (1! + 2 + bar! + foo())!", Style);492  verifyFormat(R"(test ??= !foo!;)", Style);493  verifyFormat("test = !bar! ?? !foo!;", Style);494  verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && "495               "!false! && !bar()! + (!foo()))!",496               Style);497 498  // Check that line break keeps identifier with the bang.499  Style.ColumnLimit = 14;500 501  verifyFormat("var test =\n"502               "    foo!;",503               Style);504}505 506TEST_F(FormatTestCSharp, AttributesIndentation) {507  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);508  Style.BreakAfterReturnType = FormatStyle::RTBS_None;509 510  verifyFormat("[STAThread]\n"511               "static void Main(string[] args)\n"512               "{\n"513               "}",514               Style);515 516  verifyFormat("[STAThread]\n"517               "void "518               "veryLooooooooooooooongFunctionName(string[] args)\n"519               "{\n"520               "}",521               Style);522 523  verifyFormat("[STAThread]\n"524               "veryLoooooooooooooooooooongReturnType "525               "veryLooooooooooooooongFunctionName(string[] args)\n"526               "{\n"527               "}",528               Style);529 530  verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"531               "public override X Y()\n"532               "{\n"533               "}",534               Style);535 536  verifyFormat("[SuppressMessage]\n"537               "public X Y()\n"538               "{\n"539               "}",540               Style);541 542  verifyFormat("[SuppressMessage]\n"543               "public override X Y()\n"544               "{\n"545               "}",546               Style);547 548  verifyFormat("public A(B b) : base(b)\n"549               "{\n"550               "    [SuppressMessage]\n"551               "    public override X Y()\n"552               "    {\n"553               "    }\n"554               "}",555               Style);556 557  verifyFormat("public A : Base\n"558               "{\n"559               "}\n"560               "[Test]\n"561               "public Foo()\n"562               "{\n"563               "}",564               Style);565 566  verifyFormat("namespace\n"567               "{\n"568               "public A : Base\n"569               "{\n"570               "}\n"571               "[Test]\n"572               "public Foo()\n"573               "{\n"574               "}\n"575               "}",576               Style);577}578 579TEST_F(FormatTestCSharp, CSharpSpaceBefore) {580  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);581  Style.SpaceBeforeParens = FormatStyle::SBPO_Always;582 583  verifyFormat("List<string> list;", Style);584  verifyFormat("Dictionary<string, string> dict;", Style);585 586  verifyFormat("for (int i = 0; i < size (); i++) {\n"587               "}",588               Style);589  verifyFormat("foreach (var x in y) {\n"590               "}",591               Style);592  verifyFormat("switch (x) {}", Style);593  verifyFormat("do {\n"594               "} while (x);",595               Style);596 597  Style.SpaceBeforeParens = FormatStyle::SBPO_Never;598 599  verifyFormat("List<string> list;", Style);600  verifyFormat("Dictionary<string, string> dict;", Style);601 602  verifyFormat("for(int i = 0; i < size(); i++) {\n"603               "}",604               Style);605  verifyFormat("foreach(var x in y) {\n"606               "}",607               Style);608  verifyFormat("switch(x) {}", Style);609  verifyFormat("do {\n"610               "} while(x);",611               Style);612}613 614TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) {615  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);616 617  verifyFormat("(int)x / y;", Style);618 619  Style.SpaceAfterCStyleCast = true;620  verifyFormat("(int) x / y;", Style);621}622 623TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) {624  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);625 626  verifyFormat(R"(string str = @"""";)", Style);627  verifyFormat(R"(string str = @"""Hello world""";)", Style);628  verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style);629  verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style);630  verifyFormat(R"(return @$"Foo ""/foo?f={Request.Query["f"]}""";)", Style);631  verifyFormat(R"(return @$"path\to\{specifiedFile}")", Style);632}633 634TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) {635  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);636 637  verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style);638  verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style);639  verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style);640}641 642TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) {643  // Use MS style as Google Style inserts a line break before multiline strings.644 645  // verifyFormat does not understand multiline C# string-literals646  // so check the format explicitly.647 648  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);649 650  std::string Code = R"(string s1 = $@"some code:651  class {className} {{652    {className}() {{}}653  }}";)";654 655  EXPECT_EQ(Code, format(Code, Style));656 657  // Multiline string in the middle of a function call.658  Code = R"(659var x = foo(className, $@"some code:660  class {className} {{661    {className}() {{}}662  }}",663            y);)"; // y aligned with `className` arg.664 665  EXPECT_EQ(Code, format(Code, Style));666 667  // Interpolated string with embedded multiline string.668  Code = R"(Console.WriteLine($"{string.Join(@",669		", values)}");)";670 671  EXPECT_EQ(Code, format(Code, Style));672}673 674TEST_F(FormatTestCSharp, CSharpNewOperator) {675  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);676 677  verifyFormat("public void F() {\n"678               "  var v = new C(() => { var t = 5; });\n"679               "}",680               Style);681  verifyFormat("public void F() {\n"682               "  var v = new C(() => {\n"683               "    try {\n"684               "    } catch {\n"685               "      var t = 5;\n"686               "    }\n"687               "  });\n"688               "}",689               Style);690}691 692TEST_F(FormatTestCSharp, NewModifier) {693  verifyFormat("public new class NestedC {\n"694               "  public int x = 100;\n"695               "}",696               getLLVMStyle(FormatStyle::LK_CSharp));697}698 699TEST_F(FormatTestCSharp, CSharpLambdas) {700  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);701  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);702 703  verifyFormat(R"(//704class MyClass {705  Action<string> greet = name => {706    string greeting = $"Hello {name}!";707    Console.WriteLine(greeting);708  };709})",710               GoogleStyle);711 712  // Microsoft Style:713  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas714  verifyFormat(R"(//715class MyClass716{717    Action<string> greet = name =>718    {719        string greeting = $"Hello {name}!";720        Console.WriteLine(greeting);721    };722})",723               MicrosoftStyle);724 725  verifyFormat("void bar()\n"726               "{\n"727               "    Function(Val, (Action)(() =>\n"728               "                           {\n"729               "                               lock (mylock)\n"730               "                               {\n"731               "                                   if (true)\n"732               "                                   {\n"733               "                                       A.Remove(item);\n"734               "                                   }\n"735               "                               }\n"736               "                           }));\n"737               "}",738               MicrosoftStyle);739 740  verifyFormat("void baz()\n"741               "{\n"742               "    Function(Val, (Action)(() =>\n"743               "                           {\n"744               "                               using (var a = new Lock())\n"745               "                               {\n"746               "                                   if (true)\n"747               "                                   {\n"748               "                                       A.Remove(item);\n"749               "                                   }\n"750               "                               }\n"751               "                           }));\n"752               "}",753               MicrosoftStyle);754 755  verifyFormat("void baz()\n"756               "{\n"757               "    Function(Val, (Action)(() =>\n"758               "                           {\n"759               "                               if (true)\n"760               "                               {\n"761               "                                   A.Remove(item);\n"762               "                               }\n"763               "                           }));\n"764               "}",765               MicrosoftStyle);766 767  verifyFormat("void baz()\n"768               "{\n"769               "    Function(Val, (Action)(() =>\n"770               "                           {\n"771               "                               do\n"772               "                               {\n"773               "                                   A.Remove(item);\n"774               "                               } while (true)\n"775               "                           }));\n"776               "}",777               MicrosoftStyle);778 779  verifyFormat("void baz()\n"780               "{\n"781               "    Function(Val, (Action)(() =>\n"782               "                           { A.Remove(item); }));\n"783               "}",784               MicrosoftStyle);785 786  verifyFormat("void bar()\n"787               "{\n"788               "    Function(Val, (() =>\n"789               "                   {\n"790               "                       lock (mylock)\n"791               "                       {\n"792               "                           if (true)\n"793               "                           {\n"794               "                               A.Remove(item);\n"795               "                           }\n"796               "                       }\n"797               "                   }));\n"798               "}",799               MicrosoftStyle);800  verifyFormat("void bar()\n"801               "{\n"802               "    Function((() =>\n"803               "              {\n"804               "                  lock (mylock)\n"805               "                  {\n"806               "                      if (true)\n"807               "                      {\n"808               "                          A.Remove(item);\n"809               "                      }\n"810               "                  }\n"811               "              }));\n"812               "}",813               MicrosoftStyle);814 815  MicrosoftStyle.IndentWidth = 2;816  verifyFormat("void bar()\n"817               "{\n"818               "  Function((() =>\n"819               "            {\n"820               "              lock (mylock)\n"821               "              {\n"822               "                if (true)\n"823               "                {\n"824               "                  A.Remove(item);\n"825               "                }\n"826               "              }\n"827               "            }));\n"828               "}",829               MicrosoftStyle);830  verifyFormat("void bar() {\n"831               "  Function((() => {\n"832               "    lock (mylock) {\n"833               "      if (true) {\n"834               "        A.Remove(item);\n"835               "      }\n"836               "    }\n"837               "  }));\n"838               "}",839               GoogleStyle);840}841 842TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) {843  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);844  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);845 846  verifyFormat(R"(//847public class Sample848{849    public void Test()850    {851        while (true)852        {853            preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());854            CodeThatFollowsLambda();855            IsWellAligned();856        }857    }858})",859               MicrosoftStyle);860 861  verifyFormat(R"(//862public class Sample {863  public void Test() {864    while (true) {865      preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());866      CodeThatFollowsLambda();867      IsWellAligned();868    }869  }870})",871               GoogleStyle);872}873 874TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) {875  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);876  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);877 878  verifyFormat(R"(//879public class Test880{881    private static void ComplexLambda(BuildReport protoReport)882    {883        allSelectedScenes =884            veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)885                .Select(scene => scene.path)886                .ToArray();887        if (allSelectedScenes.Count == 0)888        {889            return;890        }891        Functions();892        AreWell();893        Aligned();894        AfterLambdaBlock();895    }896})",897               MicrosoftStyle);898 899  verifyFormat(R"(//900public class Test {901  private static void ComplexLambda(BuildReport protoReport) {902    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds903                            .Where(scene => scene.enabled)904                            .Select(scene => scene.path)905                            .ToArray();906    if (allSelectedScenes.Count == 0) {907      return;908    }909    Functions();910    AreWell();911    Aligned();912    AfterLambdaBlock();913  }914})",915               GoogleStyle);916}917 918TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) {919  FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);920  FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);921 922  verifyFormat(R"(//923public class Test924{925    private static void MultipleLambdas(BuildReport protoReport)926    {927        allSelectedScenes =928            veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)929                .Select(scene => scene.path)930                .ToArray();931        preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());932        if (allSelectedScenes.Count == 0)933        {934            return;935        }936        Functions();937        AreWell();938        Aligned();939        AfterLambdaBlock();940    }941})",942               MicrosoftStyle);943 944  verifyFormat(R"(//945public class Test {946  private static void MultipleLambdas(BuildReport protoReport) {947    allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds948                            .Where(scene => scene.enabled)949                            .Select(scene => scene.path)950                            .ToArray();951    preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());952    if (allSelectedScenes.Count == 0) {953      return;954    }955    Functions();956    AreWell();957    Aligned();958    AfterLambdaBlock();959  }960})",961               GoogleStyle);962}963 964TEST_F(FormatTestCSharp, CSharpObjectInitializers) {965  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);966 967  // Start code fragments with a comment line so that C++ raw string literals968  // as seen are identical to expected formatted code.969 970  verifyFormat(R"(//971Shape[] shapes = new[] {972  new Circle {973    Radius = 2.7281,974    Colour = Colours.Red,975  },976  new Square {977    Side = 101.1,978    Colour = Colours.Yellow,979  },980};)",981               Style);982 983  // Omitted final `,`s will change the formatting.984  verifyFormat(R"(//985Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red },986                         new Square { Side = 101.1, Colour = Colours.Yellow } };)",987               Style);988 989  // Lambdas can be supplied as initialiser arguments.990  verifyFormat(R"(//991private Transformer _transformer = new X.Y {992  Filler = (Shape shape) => { return new Transform.Fill(shape, RED); },993  Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); },994};)",995               Style);996 997  // Dictionary initialisation.998  verifyFormat(R"(//999var myDict = new Dictionary<string, string> {1000  ["name"] = _donald,1001  ["age"] = Convert.ToString(DateTime.Today.Year - 1934),1002  ["type"] = _duck,1003};)",1004               Style);1005}1006 1007TEST_F(FormatTestCSharp, CSharpArrayInitializers) {1008  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1009 1010  verifyFormat(R"(//1011private MySet<Node>[] setPoints = {1012  new Point<Node>(),1013  new Point<Node>(),1014};)",1015               Style);1016}1017 1018TEST_F(FormatTestCSharp, CSharpNamedArguments) {1019  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1020 1021  verifyFormat(R"(//1022PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)",1023               Style);1024 1025  // Ensure that trailing comments do not cause problems.1026  verifyFormat(R"(//1027PrintOrderDetails(orderNum: 31, productName: "Red Mug",  // comment1028                  sellerName: "Gift Shop");)",1029               Style);1030 1031  verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style);1032}1033 1034TEST_F(FormatTestCSharp, CSharpPropertyAccessors) {1035  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1036 1037  verifyFormat("int Value { get }", Style);1038  verifyFormat("int Value { get; }", Style);1039  verifyFormat("int Value { internal get; }", Style);1040  verifyFormat("int Value { get; } = 0", Style);1041  verifyFormat("int Value { set }", Style);1042  verifyFormat("int Value { set; }", Style);1043  verifyFormat("int Value { init; }", Style);1044  verifyFormat("int Value { internal set; }", Style);1045  verifyFormat("int Value { set; } = 0", Style);1046  verifyFormat("int Value { get; set }", Style);1047  verifyFormat("int Value { get; init; }", Style);1048  verifyFormat("int Value { set; get }", Style);1049  verifyFormat("int Value { get; private set; }", Style);1050  verifyFormat("int Value { get; set; }", Style);1051  verifyFormat("int Value { get; set; } = 0", Style);1052  verifyFormat("int Value { internal get; internal set; }", Style);1053 1054  // Do not wrap expression body definitions.1055  verifyFormat(R"(//1056public string Name {1057  get => _name;1058  set => _name = value;1059})",1060               Style);1061  verifyFormat(R"(//1062public string Name {1063  init => _name = value;1064  get => _name;1065})",1066               Style);1067  verifyFormat(R"(//1068public string Name {1069  set => _name = value;1070  get => _name;1071})",1072               Style);1073 1074  // Examples taken from1075  // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties1076  verifyFormat(R"(1077// Expression body definitions1078public class SaleItem {1079  public decimal Price {1080    get => _cost;1081    set => _cost = value;1082  }1083})",1084               Style);1085 1086  verifyFormat(R"(1087// Properties with backing fields1088class TimePeriod {1089  public double Hours {1090    get { return _seconds / 3600; }1091    set {1092      if (value < 0 || value > 24)1093        throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24.");1094      _seconds = value * 3600;1095    }1096  }1097})",1098               Style);1099 1100  verifyFormat(R"(1101// Auto-implemented properties1102public class SaleItem {1103  public decimal Price { get; set; }1104})",1105               Style);1106 1107  // Add column limit to wrap long lines.1108  Style.ColumnLimit = 100;1109 1110  // Examples with assignment to default value.1111  verifyFormat(R"(1112// Long assignment to default value1113class MyClass {1114  public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } =1115      VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,1116                                     DefaultThirdArgument);1117})",1118               Style);1119 1120  verifyFormat(R"(1121// Long assignment to default value with expression body1122class MyClass {1123  public override VeryLongNamedTypeIndeed VeryLongNamedValue {1124    get => veryLongNamedField;1125    set => veryLongNamedField = value;1126  } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,1127                                     DefaultThirdArgument);1128})",1129               Style);1130 1131  // Brace wrapping and single-lining of accessor can be controlled by config.1132  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;1133  Style.BreakBeforeBraces = FormatStyle::BS_Custom;1134  Style.BraceWrapping.AfterFunction = true;1135 1136  verifyFormat(R"(//1137class TimePeriod {1138  public double Hours1139  {1140    get {1141      return _seconds / 3600;1142    }1143    set {1144      _seconds = value * 3600;1145    }1146  }1147})",1148               Style);1149 1150  // Microsoft style trivial property accessors have no line break before the1151  // opening brace.1152  auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);1153  verifyFormat(R"(//1154public class SaleItem1155{1156    public decimal Price { get; set; }1157})",1158               MicrosoftStyle);1159 1160  verifyFormat("internal class Program\n"1161               "{\n"1162               "    bool AutoAllowKnownApps\n"1163               "    {\n"1164               "        get;\n"1165               "        [Simple]\n"1166               "        set;\n"1167               "    }\n"1168               "}",1169               MicrosoftStyle);1170}1171 1172TEST_F(FormatTestCSharp, DefaultLiteral) {1173  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1174 1175  verifyFormat(1176      "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style);1177  verifyFormat("System.Numerics.Complex fillValue = default;", Style);1178  verifyFormat("int Value { get } = default;", Style);1179  verifyFormat("int Value { get } = default!;", Style);1180  verifyFormat(R"(//1181public record Person {1182  public string GetInit { get; init; } = default!;1183};)",1184               Style);1185  verifyFormat(R"(//1186public record Person {1187  public string GetSet { get; set; } = default!;1188};)",1189               Style);1190}1191 1192TEST_F(FormatTestCSharp, CSharpSpaces) {1193  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1194  Style.SpaceBeforeSquareBrackets = false;1195  Style.SpacesInSquareBrackets = false;1196  Style.SpaceBeforeCpp11BracedList = true;1197  Style.Cpp11BracedListStyle = FormatStyle::BLS_Block;1198  Style.SpacesInContainerLiterals = false;1199  Style.SpaceAfterCStyleCast = false;1200 1201  verifyFormat(R"(new Car { "Door", 0.1 })", Style);1202  verifyFormat(R"(new Car { 0.1, "Door" })", Style);1203  verifyFormat(R"(new string[] { "A" })", Style);1204  verifyFormat(R"(new string[] {})", Style);1205  verifyFormat(R"(new Car { someVariableName })", Style);1206  verifyFormat(R"(new Car { someVariableName })", Style);1207  verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)",1208               Style);1209  verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style);1210  verifyFormat(R"(bool[] xs = { true, true };)", Style);1211  verifyIncompleteFormat(1212      R"(taskContext.Factory.Run(async () => doThing(args);)", Style);1213  verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style);1214  verifyFormat(R"(private float[,] Values;)", Style);1215  verifyFormat(R"(Result this[Index x] => Foo(x);)", Style);1216 1217  verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style);1218  verifyFormat(R"(var (key, value))", Style);1219 1220  // `&&` is not seen as a reference.1221  verifyFormat(R"(A == typeof(X) && someBool)", Style);1222 1223  // Not seen as a C-style cast.1224  verifyFormat(R"(//1225foreach ((A a, B b) in someList) {1226})",1227               Style);1228 1229  // space after lock in `lock (processes)`.1230  verifyFormat("lock (process)", Style);1231 1232  Style.SpacesInSquareBrackets = true;1233  verifyFormat(R"(private float[ , ] Values;)", Style);1234  verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);1235  verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);1236 1237  // Method returning tuple1238  verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);1239  verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);1240  verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);1241  verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);1242  verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);1243  verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);1244  verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);1245  verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);1246  verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);1247  verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);1248  verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);1249  verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);1250 1251  Style.SpacesInSquareBrackets = false;1252  Style.SpaceBeforeSquareBrackets = true;1253  verifyFormat("return a is [1, 2, 3];", Style);1254  verifyFormat("return a is [..];", Style);1255  Style.SpaceBeforeSquareBrackets = false;1256  verifyFormat("return a is [1, 2, 3];", Style);1257  verifyFormat("return a is [..];", Style);1258}1259 1260TEST_F(FormatTestCSharp, CSharpNullableTypes) {1261  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1262  Style.SpacesInSquareBrackets = false;1263 1264  verifyFormat(R"(//1265public class A {1266  void foo() {1267    int? value = some.bar();1268  }1269})",1270               Style); // int? is nullable not a conditional expression.1271 1272  verifyFormat(R"(void foo(int? x, int? y, int? z) {})",1273               Style); // Nullables in function definitions.1274 1275  verifyFormat(R"(public float? Value;)", Style); // no space before `?`.1276 1277  verifyFormat(R"(int?[] arr = new int?[10];)",1278               Style); // An array of a nullable type.1279 1280  verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.1281 1282  verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics.1283 1284  verifyFormat(R"(//1285public interface I {1286  int? Function();1287})",1288               Style); // Interface methods.1289 1290  Style.ColumnLimit = 10;1291  verifyFormat(R"(//1292public VeryLongType? Function(1293    int arg1,1294    int arg2) {1295  //1296})",1297               Style); // ? sticks with identifier.1298}1299 1300TEST_F(FormatTestCSharp, CSharpArraySubscripts) {1301  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1302 1303  // Do not format array subscript operators as attributes.1304  verifyFormat(R"(//1305if (someThings[index].Contains(myThing)) {1306})",1307               Style);1308 1309  verifyFormat(R"(//1310if (someThings[i][j][k].Contains(myThing)) {1311})",1312               Style);1313}1314 1315TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {1316  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1317 1318  EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);1319 1320  verifyFormat("class ItemFactory<T>\n"1321               "    where T : new() {\n"1322               "}",1323               Style);1324 1325  verifyFormat("namespace A {\n"1326               "  delegate T MyDelegate<T>()\n"1327               "      where T : new();\n"1328               "}",1329               Style);1330 1331  // When the "where" line is not to be formatted, following lines should not1332  // take on its indentation.1333  verifyFormat("class ItemFactory<T>\n"1334               "    where T : new() {\n"1335               "  int f() {}\n"1336               "}",1337               "class ItemFactory<T>\n"1338               "    where T : new() {\n"1339               "  int f() {}\n"1340               "}",1341               Style, {tooling::Range(43, 13)});1342 1343  verifyFormat("class Dictionary<TKey, TVal>\n"1344               "    where TKey : IComparable<TKey>\n"1345               "    where TVal : IMyInterface {\n"1346               "  public void MyMethod<T>(T t)\n"1347               "      where T : IMyInterface {\n"1348               "    doThing();\n"1349               "  }\n"1350               "}",1351               Style);1352 1353  verifyFormat("class ItemFactory<T>\n"1354               "    where T : new(), IAnInterface<T>, IAnotherInterface<T>, "1355               "IAnotherInterfaceStill<T> {\n"1356               "}",1357               Style);1358 1359  Style.ColumnLimit = 50; // Force lines to be wrapped.1360  verifyFormat(R"(//1361class ItemFactory<T, U>1362    where T : new(),1363              IAnInterface<T>,1364              IAnotherInterface<T, U>,1365              IAnotherInterfaceStill<T, U> {1366})",1367               Style);1368 1369  // In other languages `where` can be used as a normal identifier.1370  // This example is in C++!1371  verifyFormat(R"(//1372class A {1373  int f(int where) {}1374};)",1375               getGoogleStyle(FormatStyle::LK_Cpp));1376}1377 1378TEST_F(FormatTestCSharp, CSharpAfterEnum) {1379  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1380  Style.BreakBeforeBraces = FormatStyle::BS_Custom;1381  Style.BraceWrapping.AfterEnum = false;1382  Style.AllowShortEnumsOnASingleLine = false;1383 1384  verifyFormat("enum MyEnum {\n"1385               "  Foo,\n"1386               "  Bar,\n"1387               "}",1388               Style);1389  verifyFormat("internal enum MyEnum {\n"1390               "  Foo,\n"1391               "  Bar,\n"1392               "}",1393               Style);1394  verifyFormat("public enum MyEnum {\n"1395               "  Foo,\n"1396               "  Bar,\n"1397               "}",1398               Style);1399  verifyFormat("protected enum MyEnum {\n"1400               "  Foo,\n"1401               "  Bar,\n"1402               "}",1403               Style);1404  verifyFormat("private enum MyEnum {\n"1405               "  Foo,\n"1406               "  Bar,\n"1407               "}",1408               Style);1409 1410  Style.BraceWrapping.AfterEnum = true;1411  Style.AllowShortEnumsOnASingleLine = false;1412 1413  verifyFormat("enum MyEnum\n"1414               "{\n"1415               "  Foo,\n"1416               "  Bar,\n"1417               "}",1418               Style);1419  verifyFormat("internal enum MyEnum\n"1420               "{\n"1421               "  Foo,\n"1422               "  Bar,\n"1423               "}",1424               Style);1425  verifyFormat("public enum MyEnum\n"1426               "{\n"1427               "  Foo,\n"1428               "  Bar,\n"1429               "}",1430               Style);1431  verifyFormat("protected enum MyEnum\n"1432               "{\n"1433               "  Foo,\n"1434               "  Bar,\n"1435               "}",1436               Style);1437  verifyFormat("private enum MyEnum\n"1438               "{\n"1439               "  Foo,\n"1440               "  Bar,\n"1441               "}",1442               Style);1443  verifyFormat("/* Foo */ private enum MyEnum\n"1444               "{\n"1445               "  Foo,\n"1446               "  Bar,\n"1447               "}",1448               Style);1449  verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n"1450               "{\n"1451               "  Foo,\n"1452               "  Bar,\n"1453               "}",1454               Style);1455}1456 1457TEST_F(FormatTestCSharp, CSharpAfterClass) {1458  FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);1459  Style.BreakBeforeBraces = FormatStyle::BS_Custom;1460  Style.BraceWrapping.AfterClass = false;1461 1462  verifyFormat("class MyClass {\n"1463               "  int a;\n"1464               "  int b;\n"1465               "}",1466               Style);1467  verifyFormat("internal class MyClass {\n"1468               "  int a;\n"1469               "  int b;\n"1470               "}",1471               Style);1472  verifyFormat("public class MyClass {\n"1473               "  int a;\n"1474               "  int b;\n"1475               "}",1476               Style);1477  verifyFormat("protected class MyClass {\n"1478               "  int a;\n"1479               "  int b;\n"1480               "}",1481               Style);1482  verifyFormat("private class MyClass {\n"1483               "  int a;\n"1484               "  int b;\n"1485               "}",1486               Style);1487 1488  verifyFormat("interface Interface {\n"1489               "  int a;\n"1490               "  int b;\n"1491               "}",1492               Style);1493  verifyFormat("internal interface Interface {\n"1494               "  int a;\n"1495               "  int b;\n"1496               "}",1497               Style);1498  verifyFormat("public interface Interface {\n"1499               "  int a;\n"1500               "  int b;\n"1501               "}",1502               Style);1503  verifyFormat("protected interface Interface {\n"1504               "  int a;\n"1505               "  int b;\n"1506               "}",1507               Style);1508  verifyFormat("private interface Interface {\n"1509               "  int a;\n"1510               "  int b;\n"1511               "}",1512               Style);1513 1514  Style.BraceWrapping.AfterClass = true;1515 1516  verifyFormat("class MyClass\n"1517               "{\n"1518               "  int a;\n"1519               "  int b;\n"1520               "}",1521               Style);1522  verifyFormat("internal class MyClass\n"1523               "{\n"1524               "  int a;\n"1525               "  int b;\n"1526               "}",1527               Style);1528  verifyFormat("public class MyClass\n"1529               "{\n"1530               "  int a;\n"1531               "  int b;\n"1532               "}",1533               Style);1534  verifyFormat("protected class MyClass\n"1535               "{\n"1536               "  int a;\n"1537               "  int b;\n"1538               "}",1539               Style);1540  verifyFormat("private class MyClass\n"1541               "{\n"1542               "  int a;\n"1543               "  int b;\n"1544               "}",1545               Style);1546 1547  verifyFormat("interface MyInterface\n"1548               "{\n"1549               "  int a;\n"1550               "  int b;\n"1551               "}",1552               Style);1553  verifyFormat("internal interface MyInterface\n"1554               "{\n"1555               "  int a;\n"1556               "  int b;\n"1557               "}",1558               Style);1559  verifyFormat("public interface MyInterface\n"1560               "{\n"1561               "  int a;\n"1562               "  int b;\n"1563               "}",1564               Style);1565  verifyFormat("protected interface MyInterface\n"1566               "{\n"1567               "  int a;\n"1568               "  int b;\n"1569               "}",1570               Style);1571  verifyFormat("private interface MyInterface\n"1572               "{\n"1573               "  int a;\n"1574               "  int b;\n"1575               "}",1576               Style);1577  verifyFormat("/* Foo */ private interface MyInterface\n"1578               "{\n"1579               "  int a;\n"1580               "  int b;\n"1581               "}",1582               Style);1583  verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n"1584               "{\n"1585               "  int a;\n"1586               "  int b;\n"1587               "}",1588               Style);1589}1590 1591TEST_F(FormatTestCSharp, NamespaceIndentation) {1592  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);1593  Style.NamespaceIndentation = FormatStyle::NI_None;1594 1595  verifyFormat("namespace A\n"1596               "{\n"1597               "public interface Name1\n"1598               "{\n"1599               "}\n"1600               "}",1601               Style);1602 1603  verifyFormat("namespace A.B\n"1604               "{\n"1605               "public interface Name1\n"1606               "{\n"1607               "}\n"1608               "}",1609               Style);1610 1611  Style.NamespaceIndentation = FormatStyle::NI_Inner;1612 1613  verifyFormat("namespace A\n"1614               "{\n"1615               "namespace B\n"1616               "{\n"1617               "    public interface Name1\n"1618               "    {\n"1619               "    }\n"1620               "}\n"1621               "}",1622               Style);1623 1624  Style.NamespaceIndentation = FormatStyle::NI_All;1625 1626  verifyFormat("namespace A.B\n"1627               "{\n"1628               "    public interface Name1\n"1629               "    {\n"1630               "    }\n"1631               "}",1632               Style);1633 1634  verifyFormat("namespace A\n"1635               "{\n"1636               "    namespace B\n"1637               "    {\n"1638               "        public interface Name1\n"1639               "        {\n"1640               "        }\n"1641               "    }\n"1642               "}",1643               Style);1644}1645 1646TEST_F(FormatTestCSharp, SwitchExpression) {1647  FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);1648  verifyFormat("int x = a switch {\n"1649               "    1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n"1650               "    2 => 1,\n"1651               "    _ => 2\n"1652               "};",1653               Style);1654}1655 1656TEST_F(FormatTestCSharp, EmptyShortBlock) {1657  auto Style = getLLVMStyle();1658  Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;1659 1660  verifyFormat("try {\n"1661               "  doA();\n"1662               "} catch (Exception e) {\n"1663               "  e.printStackTrace();\n"1664               "}",1665               Style);1666 1667  verifyFormat("try {\n"1668               "  doA();\n"1669               "} catch (Exception e) {}",1670               Style);1671}1672 1673TEST_F(FormatTestCSharp, ShortFunctions) {1674  FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);1675  Style.NamespaceIndentation = FormatStyle::NI_All;1676  Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;1677  verifyFormat("interface Interface {\n"1678               "  void f() { return; }\n"1679               "};",1680               Style);1681  verifyFormat("public interface Interface {\n"1682               "  void f() { return; }\n"1683               "};",1684               Style);1685  verifyFormat("namespace {\n"1686               "  void f() {\n"1687               "    return;\n"1688               "  }\n"1689               "};",1690               Style);1691  // "union" is not a keyword in C#.1692  verifyFormat("namespace union {\n"1693               "  void f() {\n"1694               "    return;\n"1695               "  }\n"1696               "};",1697               Style);1698}1699 1700TEST_F(FormatTestCSharp, BrokenBrackets) {1701  EXPECT_NE("", format("int where b <")); // reduced from crasher1702}1703 1704TEST_F(FormatTestCSharp, GotoCaseLabel) {1705  verifyFormat("switch (i)\n"1706               "{\n"1707               "case 0:\n"1708               "    goto case 1;\n"1709               "case 1:\n"1710               "    j = 0;\n"1711               "    {\n"1712               "        break;\n"1713               "    }\n"1714               "}",1715               "switch (i) {\n"1716               "case 0:\n"1717               "  goto case 1;\n"1718               "case 1:\n"1719               "  j = 0;\n"1720               "  {\n"1721               "    break;\n"1722               "  }\n"1723               "}");1724}1725 1726} // namespace1727} // namespace test1728} // namespace format1729} // namespace clang1730