1cbb726d0SPaul Hoad //===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===// 2cbb726d0SPaul Hoad // 3cbb726d0SPaul Hoad // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4cbb726d0SPaul Hoad // See https://llvm.org/LICENSE.txt for license information. 5cbb726d0SPaul Hoad // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6cbb726d0SPaul Hoad // 7cbb726d0SPaul Hoad //===----------------------------------------------------------------------===// 8cbb726d0SPaul Hoad 9ddc80637Ssstwcw #include "FormatTestBase.h" 10cbb726d0SPaul Hoad 11cbb726d0SPaul Hoad #define DEBUG_TYPE "format-test" 12cbb726d0SPaul Hoad 13cbb726d0SPaul Hoad namespace clang { 14cbb726d0SPaul Hoad namespace format { 15ddc80637Ssstwcw namespace test { 16ddc80637Ssstwcw namespace { 17cbb726d0SPaul Hoad 18ddc80637Ssstwcw class FormatTestCSharp : public test::FormatTestBase { 19cbb726d0SPaul Hoad protected: 20ddc80637Ssstwcw FormatStyle getDefaultStyle() const override { 21ddc80637Ssstwcw return getMicrosoftStyle(FormatStyle::LK_CSharp); 22ddc80637Ssstwcw } 23ddc80637Ssstwcw 241c58208dSOwen Pan static std::string format(StringRef Code, unsigned Offset, unsigned Length, 251c58208dSOwen Pan const FormatStyle &Style) { 26cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << "---\n"); 27cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << Code << "\n\n"); 28cbb726d0SPaul Hoad std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); 29cbb726d0SPaul Hoad tooling::Replacements Replaces = reformat(Style, Code, Ranges); 30cbb726d0SPaul Hoad auto Result = applyAllReplacements(Code, Replaces); 31cbb726d0SPaul Hoad EXPECT_TRUE(static_cast<bool>(Result)); 32cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); 33cbb726d0SPaul Hoad return *Result; 34cbb726d0SPaul Hoad } 35cbb726d0SPaul Hoad 36cbb726d0SPaul Hoad static std::string 371c58208dSOwen Pan format(StringRef Code, 38a2f963bbSPaul Hoad const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) { 39cbb726d0SPaul Hoad return format(Code, 0, Code.size(), Style); 40cbb726d0SPaul Hoad } 41cbb726d0SPaul Hoad 42cbb726d0SPaul Hoad static FormatStyle getStyleWithColumns(unsigned ColumnLimit) { 43a2f963bbSPaul Hoad FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 44cbb726d0SPaul Hoad Style.ColumnLimit = ColumnLimit; 45cbb726d0SPaul Hoad return Style; 46cbb726d0SPaul Hoad } 47cbb726d0SPaul Hoad }; 48cbb726d0SPaul Hoad 49cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpClass) { 50a2f963bbSPaul Hoad verifyFormat("public class SomeClass\n" 51a2f963bbSPaul Hoad "{\n" 52a2f963bbSPaul Hoad " void f()\n" 53a2f963bbSPaul Hoad " {\n" 54a2f963bbSPaul Hoad " }\n" 55a2f963bbSPaul Hoad " int g()\n" 56a2f963bbSPaul Hoad " {\n" 57a2f963bbSPaul Hoad " return 0;\n" 58a2f963bbSPaul Hoad " }\n" 59a2f963bbSPaul Hoad " void h()\n" 60a2f963bbSPaul Hoad " {\n" 61a2f963bbSPaul Hoad " while (true)\n" 62a2f963bbSPaul Hoad " f();\n" 63a2f963bbSPaul Hoad " for (;;)\n" 64a2f963bbSPaul Hoad " f();\n" 65a2f963bbSPaul Hoad " if (true)\n" 66a2f963bbSPaul Hoad " f();\n" 67cbb726d0SPaul Hoad " }\n" 68cbb726d0SPaul Hoad "}"); 69f40a7972SJonathan Coe 70f40a7972SJonathan Coe // Ensure that small and empty classes are handled correctly with condensed 71f40a7972SJonathan Coe // (Google C++-like) brace-breaking style. 72f40a7972SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 73f40a7972SJonathan Coe Style.BreakBeforeBraces = FormatStyle::BS_Attach; 74f40a7972SJonathan Coe 75f40a7972SJonathan Coe verifyFormat("public class SomeEmptyClass {}", Style); 76f40a7972SJonathan Coe 77f40a7972SJonathan Coe verifyFormat("public class SomeTinyClass {\n" 78f40a7972SJonathan Coe " int X;\n" 79f40a7972SJonathan Coe "}", 80f40a7972SJonathan Coe Style); 81f40a7972SJonathan Coe verifyFormat("private class SomeTinyClass {\n" 82f40a7972SJonathan Coe " int X;\n" 83f40a7972SJonathan Coe "}", 84f40a7972SJonathan Coe Style); 85f40a7972SJonathan Coe verifyFormat("protected class SomeTinyClass {\n" 86f40a7972SJonathan Coe " int X;\n" 87f40a7972SJonathan Coe "}", 88f40a7972SJonathan Coe Style); 89f40a7972SJonathan Coe verifyFormat("internal class SomeTinyClass {\n" 90f40a7972SJonathan Coe " int X;\n" 91f40a7972SJonathan Coe "}", 92f40a7972SJonathan Coe Style); 93cbb726d0SPaul Hoad } 94cbb726d0SPaul Hoad 95cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, AccessModifiers) { 96a2f963bbSPaul Hoad verifyFormat("public String toString()\n" 97a2f963bbSPaul Hoad "{\n" 98a2f963bbSPaul Hoad "}"); 99a2f963bbSPaul Hoad verifyFormat("private String toString()\n" 100a2f963bbSPaul Hoad "{\n" 101a2f963bbSPaul Hoad "}"); 102a2f963bbSPaul Hoad verifyFormat("protected String toString()\n" 103a2f963bbSPaul Hoad "{\n" 104a2f963bbSPaul Hoad "}"); 105a2f963bbSPaul Hoad verifyFormat("internal String toString()\n" 106a2f963bbSPaul Hoad "{\n" 107a2f963bbSPaul Hoad "}"); 108cbb726d0SPaul Hoad 109a2f963bbSPaul Hoad verifyFormat("public override String toString()\n" 110a2f963bbSPaul Hoad "{\n" 111a2f963bbSPaul Hoad "}"); 112a2f963bbSPaul Hoad verifyFormat("private override String toString()\n" 113a2f963bbSPaul Hoad "{\n" 114a2f963bbSPaul Hoad "}"); 115a2f963bbSPaul Hoad verifyFormat("protected override String toString()\n" 116a2f963bbSPaul Hoad "{\n" 117a2f963bbSPaul Hoad "}"); 118a2f963bbSPaul Hoad verifyFormat("internal override String toString()\n" 119a2f963bbSPaul Hoad "{\n" 120a2f963bbSPaul Hoad "}"); 121cbb726d0SPaul Hoad 122a2f963bbSPaul Hoad verifyFormat("internal static String toString()\n" 123a2f963bbSPaul Hoad "{\n" 124a2f963bbSPaul Hoad "}"); 125cbb726d0SPaul Hoad } 126cbb726d0SPaul Hoad 127cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, NoStringLiteralBreaks) { 128ddc80637Ssstwcw // Breaking of interpolated strings is not implemented. 129ddc80637Ssstwcw auto Style = getDefaultStyle(); 130ddc80637Ssstwcw Style.ColumnLimit = 40; 131ddc80637Ssstwcw Style.BreakStringLiterals = true; 132ddc80637Ssstwcw verifyFormat("foo(" 133ddc80637Ssstwcw "$\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 134ddc80637Ssstwcw "aaaaaaa\");", 135ddc80637Ssstwcw Style); 136ddc80637Ssstwcw } 137ddc80637Ssstwcw 138ddc80637Ssstwcw TEST_F(FormatTestCSharp, StringLiteralBreaks) { 139ddc80637Ssstwcw // The line is 75 characters long. The default limit for the Microsoft style 140ddc80637Ssstwcw // is 120. 141ddc80637Ssstwcw auto Style = getDefaultStyle(); 142ddc80637Ssstwcw Style.BreakStringLiterals = true; 143cbb726d0SPaul Hoad verifyFormat("foo(" 144cbb726d0SPaul Hoad "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 145ddc80637Ssstwcw "aaaaaa\");", 146ddc80637Ssstwcw Style); 147ddc80637Ssstwcw // When the column limit is smaller, the string should get broken. 148ddc80637Ssstwcw Style.ColumnLimit = 40; 149ddc80637Ssstwcw verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 150ddc80637Ssstwcw "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 151ddc80637Ssstwcw "aaa");)", 152ddc80637Ssstwcw "foo(" 153ddc80637Ssstwcw "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 154ddc80637Ssstwcw "aaaaaa\");", 155ddc80637Ssstwcw Style); 156ddc80637Ssstwcw // The new quotes should be the same as the original. 157ddc80637Ssstwcw verifyFormat(R"(foo(@"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 158ddc80637Ssstwcw @"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 159ddc80637Ssstwcw @"aaaaa");)", 160ddc80637Ssstwcw "foo(" 161ddc80637Ssstwcw "@\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 162ddc80637Ssstwcw "aaaaaaa\");", 163ddc80637Ssstwcw Style); 164ddc80637Ssstwcw // The operators can be on either line. 165ddc80637Ssstwcw Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; 166ddc80637Ssstwcw verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 167ddc80637Ssstwcw + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 168ddc80637Ssstwcw + "a");)", 169ddc80637Ssstwcw "foo(" 170ddc80637Ssstwcw "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 171ddc80637Ssstwcw "aaaaaa\");", 172ddc80637Ssstwcw Style); 173ddc80637Ssstwcw Style.AlignOperands = FormatStyle::OAS_AlignAfterOperator; 174ddc80637Ssstwcw verifyFormat(R"(foo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 175ddc80637Ssstwcw + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 176ddc80637Ssstwcw + "a");)", 177ddc80637Ssstwcw "foo(" 178ddc80637Ssstwcw "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 179ddc80637Ssstwcw "aaaaaa\");", 180ddc80637Ssstwcw Style); 181ddc80637Ssstwcw verifyFormat(R"(x = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 182ddc80637Ssstwcw + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";)", 183ddc80637Ssstwcw "x = " 184ddc80637Ssstwcw "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 185ddc80637Ssstwcw "aaaaaa\";", 186ddc80637Ssstwcw Style); 187cbb726d0SPaul Hoad } 188cbb726d0SPaul Hoad 189cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) { 190cbb726d0SPaul Hoad verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");"); 191cbb726d0SPaul Hoad // @"ABC\" + ToString("B") - handle embedded \ in literal string at 192cbb726d0SPaul Hoad // the end 193cbb726d0SPaul Hoad // 194cbb726d0SPaul Hoad /* 195cbb726d0SPaul Hoad * After removal of Lexer change we are currently not able 196cbb726d0SPaul Hoad * To handle these cases 197cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");"); 198cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\""); 199cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"\""); 200cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc"); 201cbb726d0SPaul Hoad */ 202cbb726d0SPaul Hoad } 203cbb726d0SPaul Hoad 204cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) { 205cbb726d0SPaul Hoad verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");"); 206cbb726d0SPaul Hoad verifyFormat("foo($\"aaaa{A}\");"); 207cbb726d0SPaul Hoad verifyFormat( 208cbb726d0SPaul Hoad "foo($\"aaaa{A}" 209cbb726d0SPaul Hoad "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");"); 210cbb726d0SPaul Hoad verifyFormat("Name = $\"{firstName} {lastName}\";"); 211cbb726d0SPaul Hoad 212cbb726d0SPaul Hoad // $"ABC\" + ToString("B") - handle embedded \ in literal string at 213cbb726d0SPaul Hoad // the end 214cbb726d0SPaul Hoad verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");"); 215cbb726d0SPaul Hoad verifyFormat("$\"{domain}\\\\{user}\""); 216cbb726d0SPaul Hoad verifyFormat( 217cbb726d0SPaul Hoad "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";"); 218cbb726d0SPaul Hoad } 219cbb726d0SPaul Hoad 220cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpFatArrows) { 221ddc80637Ssstwcw verifyIncompleteFormat("Task serverTask = Task.Run(async() => {"); 222cbb726d0SPaul Hoad verifyFormat("public override string ToString() => \"{Name}\\{Age}\";"); 223cbb726d0SPaul Hoad } 224cbb726d0SPaul Hoad 225c3af063cSJonathan Coe TEST_F(FormatTestCSharp, CSharpConditionalExpressions) { 226c3af063cSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 227c3af063cSJonathan Coe // conditional expression is not seen as a NullConditional. 228c3af063cSJonathan Coe verifyFormat("var y = A < B ? -1 : 1;", Style); 229c3af063cSJonathan Coe } 230c3af063cSJonathan Coe 231cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullConditional) { 2324c056583SPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 2334c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 2344c056583SPaul Hoad 235cbb726d0SPaul Hoad verifyFormat( 236cbb726d0SPaul Hoad "public Person(string firstName, string lastName, int? age = null)"); 237cbb726d0SPaul Hoad 2384c056583SPaul Hoad verifyFormat("foo () {\n" 2394c056583SPaul Hoad " switch (args?.Length) {}\n" 2404c056583SPaul Hoad "}", 2414c056583SPaul Hoad Style); 2424c056583SPaul Hoad 2434c056583SPaul Hoad verifyFormat("switch (args?.Length) {}", Style); 244cbb726d0SPaul Hoad 245a2f963bbSPaul Hoad verifyFormat("public static void Main(string[] args)\n" 246a2f963bbSPaul Hoad "{\n" 247a2f963bbSPaul Hoad " string dirPath = args?[0];\n" 248a2f963bbSPaul Hoad "}"); 2494c056583SPaul Hoad 2504c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 2514c056583SPaul Hoad 2524c056583SPaul Hoad verifyFormat("switch(args?.Length) {}", Style); 253cbb726d0SPaul Hoad } 254cbb726d0SPaul Hoad 255cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, Attributes) { 256cbb726d0SPaul Hoad verifyFormat("[STAThread]\n" 257a2f963bbSPaul Hoad "static void Main(string[] args)\n" 258a2f963bbSPaul Hoad "{\n" 259a2f963bbSPaul Hoad "}"); 260cbb726d0SPaul Hoad 261cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 262a2f963bbSPaul Hoad "private class Test\n" 263a2f963bbSPaul Hoad "{\n" 264a2f963bbSPaul Hoad "}"); 265cbb726d0SPaul Hoad 266cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 267a2f963bbSPaul Hoad "protected class Test\n" 268a2f963bbSPaul Hoad "{\n" 269a2f963bbSPaul Hoad "}"); 270cbb726d0SPaul Hoad 271cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 272a2f963bbSPaul Hoad "internal class Test\n" 273a2f963bbSPaul Hoad "{\n" 274a2f963bbSPaul Hoad "}"); 275cbb726d0SPaul Hoad 276cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 277a2f963bbSPaul Hoad "class Test\n" 278a2f963bbSPaul Hoad "{\n" 279a2f963bbSPaul Hoad "}"); 280cbb726d0SPaul Hoad 281cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 282cbb726d0SPaul Hoad "[DeploymentItem(\"Test.txt\")]\n" 283a2f963bbSPaul Hoad "public class Test\n" 284a2f963bbSPaul Hoad "{\n" 285a2f963bbSPaul Hoad "}"); 286cbb726d0SPaul Hoad 287cbb726d0SPaul Hoad verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n" 288cbb726d0SPaul Hoad "[System.Runtime.InteropServices.ComVisible(true)]\n" 289a2f963bbSPaul Hoad "public sealed class STAThreadAttribute : Attribute\n" 290a2f963bbSPaul Hoad "{\n" 291a2f963bbSPaul Hoad "}"); 292cbb726d0SPaul Hoad 293cbb726d0SPaul Hoad verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on " 294cbb726d0SPaul Hoad "provided port\")]\n" 295a2f963bbSPaul Hoad "class Test\n" 296a2f963bbSPaul Hoad "{\n" 297a2f963bbSPaul Hoad "}"); 298cbb726d0SPaul Hoad 299cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 300f22b0727SJonathan Coe "public string Host { set; get; }"); 301cbb726d0SPaul Hoad 302ffb48d48Smydeveloperday // Adjacent properties should not cause line wrapping issues 303ffb48d48Smydeveloperday verifyFormat("[JsonProperty(\"foo\")]\n" 304ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 305ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 306ffb48d48Smydeveloperday "public string Bar { set; get; }\n" 307ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 308ffb48d48Smydeveloperday "protected string Bar { set; get; }\n" 309ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 310ffb48d48Smydeveloperday "internal string Bar { set; get; }"); 311ffb48d48Smydeveloperday 312ffb48d48Smydeveloperday // Multiple attributes should always be split (not just the first ones) 313ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 314ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 315ffb48d48Smydeveloperday "public string Foo { set; get; }"); 316ffb48d48Smydeveloperday 317ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 318ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 319ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 320ffb48d48Smydeveloperday "[XmlIgnore]\n" 321ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 322ffb48d48Smydeveloperday "public string Bar { set; get; }"); 323ffb48d48Smydeveloperday 324ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 325ffb48d48Smydeveloperday "[ScriptIgnore]\n" 326ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 327ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 328ffb48d48Smydeveloperday "[XmlIgnore]\n" 329ffb48d48Smydeveloperday "[ScriptIgnore]\n" 330ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 331ffb48d48Smydeveloperday "public string Bar { set; get; }"); 332ffb48d48Smydeveloperday 333cbb726d0SPaul Hoad verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server " 334cbb726d0SPaul Hoad "listening on provided host\")]\n" 335f22b0727SJonathan Coe "public string Host { set; get; }"); 33650d8977cSJonathan Coe 337ddc80637Ssstwcw verifyIncompleteFormat( 33850d8977cSJonathan Coe "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n" 33950d8977cSJonathan Coe "// The const char* returned by hello_world must not be deleted.\n" 34050d8977cSJonathan Coe "private static extern IntPtr HelloFromCpp();)"); 341ca1fd460SJonathan Coe 342b46f925dSJonathan Coe // Class attributes go on their own line and do not affect layout of 343b46f925dSJonathan Coe // interfaces. Line wrapping decisions previously caused each interface to be 344b46f925dSJonathan Coe // on its own line. 345b46f925dSJonathan Coe verifyFormat("[SomeAttribute]\n" 346b46f925dSJonathan Coe "[SomeOtherAttribute]\n" 347b46f925dSJonathan Coe "public class A : IShape, IAnimal, IVehicle\n" 348b46f925dSJonathan Coe "{\n" 349b46f925dSJonathan Coe " int X;\n" 350b46f925dSJonathan Coe "}"); 351b46f925dSJonathan Coe 352b46f925dSJonathan Coe // Attributes in a method declaration do not cause line wrapping. 353b46f925dSJonathan Coe verifyFormat("void MethodA([In][Out] ref double x)\n" 354b46f925dSJonathan Coe "{\n" 355b46f925dSJonathan Coe "}"); 356b46f925dSJonathan Coe 357ffb48d48Smydeveloperday verifyFormat("void MethodA([In, Out] ref double x)\n" 358ffb48d48Smydeveloperday "{\n" 359ffb48d48Smydeveloperday "}"); 360ffb48d48Smydeveloperday 361ffb48d48Smydeveloperday verifyFormat("void MethodA([In, Out] double[] x)\n" 362ffb48d48Smydeveloperday "{\n" 363ffb48d48Smydeveloperday "}"); 364ffb48d48Smydeveloperday 365ffb48d48Smydeveloperday verifyFormat("void MethodA([In] double[] x)\n" 366ffb48d48Smydeveloperday "{\n" 367ffb48d48Smydeveloperday "}"); 368ffb48d48Smydeveloperday 369ffb48d48Smydeveloperday verifyFormat("void MethodA(int[] x)\n" 370ffb48d48Smydeveloperday "{\n" 371ffb48d48Smydeveloperday "}"); 372ffb48d48Smydeveloperday verifyFormat("void MethodA(int[][] x)\n" 373ffb48d48Smydeveloperday "{\n" 374ffb48d48Smydeveloperday "}"); 375ffb48d48Smydeveloperday verifyFormat("void MethodA([] x)\n" 376ffb48d48Smydeveloperday "{\n" 377ffb48d48Smydeveloperday "}"); 378ffb48d48Smydeveloperday 379ffb48d48Smydeveloperday verifyFormat("public void Log([CallerLineNumber] int line = -1, " 380ffb48d48Smydeveloperday "[CallerFilePath] string path = null,\n" 381ffb48d48Smydeveloperday " [CallerMemberName] string name = null)\n" 382ffb48d48Smydeveloperday "{\n" 383ffb48d48Smydeveloperday "}"); 384ffb48d48Smydeveloperday 3859f8a7e82SJonathan Coe // [] in an attribute do not cause premature line wrapping or indenting. 3869f8a7e82SJonathan Coe verifyFormat(R"(// 3879f8a7e82SJonathan Coe public class A 3889f8a7e82SJonathan Coe { 3899f8a7e82SJonathan Coe [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)] 3909f8a7e82SJonathan Coe [DoNotSerialize] 3919f8a7e82SJonathan Coe public Data MemberVariable; 3929f8a7e82SJonathan Coe })"); 3939f8a7e82SJonathan Coe 394ca1fd460SJonathan Coe // Unwrappable lines go on a line of their own. 395ca1fd460SJonathan Coe // 'target:' is not treated as a label. 396ca1fd460SJonathan Coe // Modify Style to enforce a column limit. 397ca1fd460SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 398ca1fd460SJonathan Coe Style.ColumnLimit = 10; 399ca1fd460SJonathan Coe verifyFormat(R"([assembly:InternalsVisibleTo( 400ca1fd460SJonathan Coe "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])", 401ca1fd460SJonathan Coe Style); 402cbb726d0SPaul Hoad } 403cbb726d0SPaul Hoad 404719087bbSPaul Hoad TEST_F(FormatTestCSharp, CSharpUsing) { 405719087bbSPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 406719087bbSPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 407719087bbSPaul Hoad verifyFormat("public void foo () {\n" 408719087bbSPaul Hoad " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n" 4091e0174a9SKrasimir Georgiev " using () {}\n" 410719087bbSPaul Hoad "}", 411719087bbSPaul Hoad Style); 412719087bbSPaul Hoad 4131e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 4144c056583SPaul Hoad verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}", 4154c056583SPaul Hoad Style); 4164c056583SPaul Hoad 417719087bbSPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 418719087bbSPaul Hoad verifyFormat("public void foo() {\n" 419719087bbSPaul Hoad " using(StreamWriter sw = new StreamWriter(filenameB)) {}\n" 4201e0174a9SKrasimir Georgiev " using() {}\n" 421719087bbSPaul Hoad "}", 422719087bbSPaul Hoad Style); 4234c056583SPaul Hoad 4241e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 4251e0174a9SKrasimir Georgiev verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}", 4261e0174a9SKrasimir Georgiev Style); 4271e0174a9SKrasimir Georgiev 4281e0174a9SKrasimir Georgiev Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 4291e0174a9SKrasimir Georgiev verifyFormat("public void foo() {\n" 4301e0174a9SKrasimir Georgiev " using (StreamWriter sw = new StreamWriter(filenameA)) {}\n" 4311e0174a9SKrasimir Georgiev " using () {}\n" 4321e0174a9SKrasimir Georgiev "}", 4331e0174a9SKrasimir Georgiev Style); 4341e0174a9SKrasimir Georgiev 4351e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 4361e0174a9SKrasimir Georgiev verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}", 4371e0174a9SKrasimir Georgiev Style); 4381e0174a9SKrasimir Georgiev 4391e0174a9SKrasimir Georgiev Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses; 4401e0174a9SKrasimir Georgiev verifyFormat("public void foo() {\n" 4411e0174a9SKrasimir Georgiev " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n" 4421e0174a9SKrasimir Georgiev " using() {}\n" 4431e0174a9SKrasimir Georgiev "}", 4441e0174a9SKrasimir Georgiev Style); 4451e0174a9SKrasimir Georgiev 4461e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 4474c056583SPaul Hoad verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}", 4484c056583SPaul Hoad Style); 449719087bbSPaul Hoad } 450719087bbSPaul Hoad 451cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpRegions) { 452cbb726d0SPaul Hoad verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa " 453cbb726d0SPaul Hoad "aaaaaaaaaaaaaaa long region"); 454cbb726d0SPaul Hoad } 455cbb726d0SPaul Hoad 456cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) { 457ed367b9dSmydeveloperday // AfterEnum is true by default. 458ed367b9dSmydeveloperday verifyFormat("public enum var\n" 459ed367b9dSmydeveloperday "{\n" 460292058a5SAaron Smith " none,\n" 461292058a5SAaron Smith " @string,\n" 462292058a5SAaron Smith " bool,\n" 463292058a5SAaron Smith " @enum\n" 464292058a5SAaron Smith "}"); 465cbb726d0SPaul Hoad } 466cbb726d0SPaul Hoad 467cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullCoalescing) { 468cbb726d0SPaul Hoad verifyFormat("var test = ABC ?? DEF"); 469cbb726d0SPaul Hoad verifyFormat("string myname = name ?? \"ABC\";"); 470cbb726d0SPaul Hoad verifyFormat("return _name ?? \"DEF\";"); 471cbb726d0SPaul Hoad } 472cbb726d0SPaul Hoad 473a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) { 474a437befaSEliza Velasquez FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 475a437befaSEliza Velasquez Style.SpaceBeforeAssignmentOperators = true; 476a437befaSEliza Velasquez 477a437befaSEliza Velasquez verifyFormat(R"(test ??= ABC;)", Style); 478a437befaSEliza Velasquez verifyFormat(R"(test ??= true;)", Style); 479a437befaSEliza Velasquez 480a437befaSEliza Velasquez Style.SpaceBeforeAssignmentOperators = false; 481a437befaSEliza Velasquez 482a437befaSEliza Velasquez verifyFormat(R"(test??= ABC;)", Style); 483a437befaSEliza Velasquez verifyFormat(R"(test??= true;)", Style); 484a437befaSEliza Velasquez } 485a437befaSEliza Velasquez 486a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullForgiving) { 487a437befaSEliza Velasquez FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 488a437befaSEliza Velasquez 489a437befaSEliza Velasquez verifyFormat("var test = null!;", Style); 490a437befaSEliza Velasquez verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style); 491a437befaSEliza Velasquez verifyFormat("int test = (1! + 2 + bar! + foo())!", Style); 492a437befaSEliza Velasquez verifyFormat(R"(test ??= !foo!;)", Style); 493a437befaSEliza Velasquez verifyFormat("test = !bar! ?? !foo!;", Style); 494a437befaSEliza Velasquez verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && " 495a437befaSEliza Velasquez "!false! && !bar()! + (!foo()))!", 496a437befaSEliza Velasquez Style); 497a437befaSEliza Velasquez 498a437befaSEliza Velasquez // Check that line break keeps identifier with the bang. 499a437befaSEliza Velasquez Style.ColumnLimit = 14; 500a437befaSEliza Velasquez 501a437befaSEliza Velasquez verifyFormat("var test =\n" 502a437befaSEliza Velasquez " foo!;", 503a437befaSEliza Velasquez Style); 504a437befaSEliza Velasquez } 505a437befaSEliza Velasquez 506a2f963bbSPaul Hoad TEST_F(FormatTestCSharp, AttributesIndentation) { 507a2f963bbSPaul Hoad FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 508d821650eSrmarker Style.BreakAfterReturnType = FormatStyle::RTBS_None; 509a2f963bbSPaul Hoad 510a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 511a2f963bbSPaul Hoad "static void Main(string[] args)\n" 512a2f963bbSPaul Hoad "{\n" 513a2f963bbSPaul Hoad "}", 514a2f963bbSPaul Hoad Style); 515a2f963bbSPaul Hoad 516a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 517a2f963bbSPaul Hoad "void " 518a2f963bbSPaul Hoad "veryLooooooooooooooongFunctionName(string[] args)\n" 519a2f963bbSPaul Hoad "{\n" 520a2f963bbSPaul Hoad "}", 521a2f963bbSPaul Hoad Style); 522a2f963bbSPaul Hoad 523a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 524a2f963bbSPaul Hoad "veryLoooooooooooooooooooongReturnType " 525a2f963bbSPaul Hoad "veryLooooooooooooooongFunctionName(string[] args)\n" 526a2f963bbSPaul Hoad "{\n" 527a2f963bbSPaul Hoad "}", 528a2f963bbSPaul Hoad Style); 529a2f963bbSPaul Hoad 530a2f963bbSPaul Hoad verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n" 531a2f963bbSPaul Hoad "public override X Y()\n" 532a2f963bbSPaul Hoad "{\n" 53388934a82SOwen Pan "}", 534a2f963bbSPaul Hoad Style); 535a2f963bbSPaul Hoad 536a2f963bbSPaul Hoad verifyFormat("[SuppressMessage]\n" 537a2f963bbSPaul Hoad "public X Y()\n" 538a2f963bbSPaul Hoad "{\n" 53988934a82SOwen Pan "}", 540a2f963bbSPaul Hoad Style); 541a2f963bbSPaul Hoad 542a2f963bbSPaul Hoad verifyFormat("[SuppressMessage]\n" 543a2f963bbSPaul Hoad "public override X Y()\n" 544a2f963bbSPaul Hoad "{\n" 54588934a82SOwen Pan "}", 546a2f963bbSPaul Hoad Style); 547a2f963bbSPaul Hoad 548a2f963bbSPaul Hoad verifyFormat("public A(B b) : base(b)\n" 549a2f963bbSPaul Hoad "{\n" 550a2f963bbSPaul Hoad " [SuppressMessage]\n" 551a2f963bbSPaul Hoad " public override X Y()\n" 552a2f963bbSPaul Hoad " {\n" 553a2f963bbSPaul Hoad " }\n" 55488934a82SOwen Pan "}", 555a2f963bbSPaul Hoad Style); 5562f209ccfSmydeveloperday 5572f209ccfSmydeveloperday verifyFormat("public A : Base\n" 5582f209ccfSmydeveloperday "{\n" 5592f209ccfSmydeveloperday "}\n" 5602f209ccfSmydeveloperday "[Test]\n" 5612f209ccfSmydeveloperday "public Foo()\n" 5622f209ccfSmydeveloperday "{\n" 56388934a82SOwen Pan "}", 5642f209ccfSmydeveloperday Style); 5652f209ccfSmydeveloperday 5662f209ccfSmydeveloperday verifyFormat("namespace\n" 5672f209ccfSmydeveloperday "{\n" 5682f209ccfSmydeveloperday "public A : Base\n" 5692f209ccfSmydeveloperday "{\n" 5702f209ccfSmydeveloperday "}\n" 5712f209ccfSmydeveloperday "[Test]\n" 5722f209ccfSmydeveloperday "public Foo()\n" 5732f209ccfSmydeveloperday "{\n" 5742f209ccfSmydeveloperday "}\n" 57588934a82SOwen Pan "}", 5762f209ccfSmydeveloperday Style); 577a2f963bbSPaul Hoad } 578a2f963bbSPaul Hoad 5794c056583SPaul Hoad TEST_F(FormatTestCSharp, CSharpSpaceBefore) { 5804c056583SPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 5814c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 5824c056583SPaul Hoad 5834c056583SPaul Hoad verifyFormat("List<string> list;", Style); 5844c056583SPaul Hoad verifyFormat("Dictionary<string, string> dict;", Style); 5854c056583SPaul Hoad 5864c056583SPaul Hoad verifyFormat("for (int i = 0; i < size (); i++) {\n" 5874c056583SPaul Hoad "}", 5884c056583SPaul Hoad Style); 5894c056583SPaul Hoad verifyFormat("foreach (var x in y) {\n" 5904c056583SPaul Hoad "}", 5914c056583SPaul Hoad Style); 5924c056583SPaul Hoad verifyFormat("switch (x) {}", Style); 5934c056583SPaul Hoad verifyFormat("do {\n" 5944c056583SPaul Hoad "} while (x);", 5954c056583SPaul Hoad Style); 5964c056583SPaul Hoad 5974c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 5984c056583SPaul Hoad 5994c056583SPaul Hoad verifyFormat("List<string> list;", Style); 6004c056583SPaul Hoad verifyFormat("Dictionary<string, string> dict;", Style); 6014c056583SPaul Hoad 6024c056583SPaul Hoad verifyFormat("for(int i = 0; i < size(); i++) {\n" 6034c056583SPaul Hoad "}", 6044c056583SPaul Hoad Style); 6054c056583SPaul Hoad verifyFormat("foreach(var x in y) {\n" 6064c056583SPaul Hoad "}", 6074c056583SPaul Hoad Style); 6084c056583SPaul Hoad verifyFormat("switch(x) {}", Style); 6094c056583SPaul Hoad verifyFormat("do {\n" 6104c056583SPaul Hoad "} while(x);", 6114c056583SPaul Hoad Style); 6124c056583SPaul Hoad } 6134c056583SPaul Hoad 614d82adf32Smydeveloperday TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) { 615d82adf32Smydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 616d82adf32Smydeveloperday 617d82adf32Smydeveloperday verifyFormat("(int)x / y;", Style); 618d82adf32Smydeveloperday 619d82adf32Smydeveloperday Style.SpaceAfterCStyleCast = true; 620d82adf32Smydeveloperday verifyFormat("(int) x / y;", Style); 621d82adf32Smydeveloperday } 622d82adf32Smydeveloperday 62336a8f7f6SKrasimir Georgiev TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) { 62436a8f7f6SKrasimir Georgiev FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 62536a8f7f6SKrasimir Georgiev 626f9f0919dSJonathan Coe verifyFormat(R"(string str = @"""";)", Style); 627f9f0919dSJonathan Coe verifyFormat(R"(string str = @"""Hello world""";)", Style); 628f9f0919dSJonathan Coe verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style); 6290ffb3dd3Sowenca verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style); 630b60e7a7fSowenca verifyFormat(R"(return @$"Foo ""/foo?f={Request.Query["f"]}""";)", Style); 631b60e7a7fSowenca verifyFormat(R"(return @$"path\to\{specifiedFile}")", Style); 63236a8f7f6SKrasimir Georgiev } 63336a8f7f6SKrasimir Georgiev 6349d212e83SJonathan Coe TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) { 6359d212e83SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 6369d212e83SJonathan Coe 6379d212e83SJonathan Coe verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style); 6389d212e83SJonathan Coe verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style); 6399d212e83SJonathan Coe verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style); 6409d212e83SJonathan Coe } 6419d212e83SJonathan Coe 642f9f0919dSJonathan Coe TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) { 643f9f0919dSJonathan Coe // Use MS style as Google Style inserts a line break before multiline strings. 644f9f0919dSJonathan Coe 645f9f0919dSJonathan Coe // verifyFormat does not understand multiline C# string-literals 646f9f0919dSJonathan Coe // so check the format explicitly. 647f9f0919dSJonathan Coe 648f9f0919dSJonathan Coe FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 649f9f0919dSJonathan Coe 650f9f0919dSJonathan Coe std::string Code = R"(string s1 = $@"some code: 651f9f0919dSJonathan Coe class {className} {{ 652f9f0919dSJonathan Coe {className}() {{}} 653f9f0919dSJonathan Coe }}";)"; 654f9f0919dSJonathan Coe 655f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 656f9f0919dSJonathan Coe 657f9f0919dSJonathan Coe // Multiline string in the middle of a function call. 658f9f0919dSJonathan Coe Code = R"( 659f9f0919dSJonathan Coe var x = foo(className, $@"some code: 660f9f0919dSJonathan Coe class {className} {{ 661f9f0919dSJonathan Coe {className}() {{}} 662f9f0919dSJonathan Coe }}", 663f9f0919dSJonathan Coe y);)"; // y aligned with `className` arg. 664f9f0919dSJonathan Coe 665f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 666f9f0919dSJonathan Coe 667f9f0919dSJonathan Coe // Interpolated string with embedded multiline string. 668f9f0919dSJonathan Coe Code = R"(Console.WriteLine($"{string.Join(@", 669f9f0919dSJonathan Coe ", values)}");)"; 670f9f0919dSJonathan Coe 671f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 672f9f0919dSJonathan Coe } 673f9f0919dSJonathan Coe 674258d7b86SDanil Sidoruk TEST_F(FormatTestCSharp, CSharpNewOperator) { 675258d7b86SDanil Sidoruk FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp); 676258d7b86SDanil Sidoruk 677258d7b86SDanil Sidoruk verifyFormat("public void F() {\n" 678258d7b86SDanil Sidoruk " var v = new C(() => { var t = 5; });\n" 679258d7b86SDanil Sidoruk "}", 680258d7b86SDanil Sidoruk Style); 681258d7b86SDanil Sidoruk verifyFormat("public void F() {\n" 682258d7b86SDanil Sidoruk " var v = new C(() => {\n" 683258d7b86SDanil Sidoruk " try {\n" 684258d7b86SDanil Sidoruk " } catch {\n" 685258d7b86SDanil Sidoruk " var t = 5;\n" 686258d7b86SDanil Sidoruk " }\n" 687258d7b86SDanil Sidoruk " });\n" 688258d7b86SDanil Sidoruk "}", 689258d7b86SDanil Sidoruk Style); 690258d7b86SDanil Sidoruk } 691258d7b86SDanil Sidoruk 6927117066bSJonathan Coe TEST_F(FormatTestCSharp, CSharpLambdas) { 6937117066bSJonathan Coe FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 6947117066bSJonathan Coe FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 6957117066bSJonathan Coe 6967117066bSJonathan Coe verifyFormat(R"(// 6977117066bSJonathan Coe class MyClass { 6987117066bSJonathan Coe Action<string> greet = name => { 6997117066bSJonathan Coe string greeting = $"Hello {name}!"; 7007117066bSJonathan Coe Console.WriteLine(greeting); 7017117066bSJonathan Coe }; 7027117066bSJonathan Coe })", 7037117066bSJonathan Coe GoogleStyle); 7047117066bSJonathan Coe 7057117066bSJonathan Coe // Microsoft Style: 7067117066bSJonathan Coe // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas 7077117066bSJonathan Coe verifyFormat(R"(// 7087117066bSJonathan Coe class MyClass 7097117066bSJonathan Coe { 7107117066bSJonathan Coe Action<string> greet = name => 7117117066bSJonathan Coe { 7127117066bSJonathan Coe string greeting = $"Hello {name}!"; 7137117066bSJonathan Coe Console.WriteLine(greeting); 7147117066bSJonathan Coe }; 7157117066bSJonathan Coe })", 7167117066bSJonathan Coe MicrosoftStyle); 717f9937106Smydeveloperday 718f9937106Smydeveloperday verifyFormat("void bar()\n" 719f9937106Smydeveloperday "{\n" 720f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 721f9937106Smydeveloperday " {\n" 722f9937106Smydeveloperday " lock (mylock)\n" 723f9937106Smydeveloperday " {\n" 724f9937106Smydeveloperday " if (true)\n" 725f9937106Smydeveloperday " {\n" 726f9937106Smydeveloperday " A.Remove(item);\n" 727f9937106Smydeveloperday " }\n" 728f9937106Smydeveloperday " }\n" 729f9937106Smydeveloperday " }));\n" 730f9937106Smydeveloperday "}", 731f9937106Smydeveloperday MicrosoftStyle); 732f9937106Smydeveloperday 733f9937106Smydeveloperday verifyFormat("void baz()\n" 734f9937106Smydeveloperday "{\n" 735f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 736f9937106Smydeveloperday " {\n" 737f9937106Smydeveloperday " using (var a = new Lock())\n" 738f9937106Smydeveloperday " {\n" 739f9937106Smydeveloperday " if (true)\n" 740f9937106Smydeveloperday " {\n" 741f9937106Smydeveloperday " A.Remove(item);\n" 742f9937106Smydeveloperday " }\n" 743f9937106Smydeveloperday " }\n" 744f9937106Smydeveloperday " }));\n" 745f9937106Smydeveloperday "}", 746f9937106Smydeveloperday MicrosoftStyle); 747f9937106Smydeveloperday 748f9937106Smydeveloperday verifyFormat("void baz()\n" 749f9937106Smydeveloperday "{\n" 750f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 751f9937106Smydeveloperday " {\n" 752f9937106Smydeveloperday " if (true)\n" 753f9937106Smydeveloperday " {\n" 754f9937106Smydeveloperday " A.Remove(item);\n" 755f9937106Smydeveloperday " }\n" 756f9937106Smydeveloperday " }));\n" 757f9937106Smydeveloperday "}", 758f9937106Smydeveloperday MicrosoftStyle); 759f9937106Smydeveloperday 760f9937106Smydeveloperday verifyFormat("void baz()\n" 761f9937106Smydeveloperday "{\n" 762f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 763f9937106Smydeveloperday " {\n" 764f9937106Smydeveloperday " do\n" 765f9937106Smydeveloperday " {\n" 766f9937106Smydeveloperday " A.Remove(item);\n" 767f9937106Smydeveloperday " } while (true)\n" 768f9937106Smydeveloperday " }));\n" 769f9937106Smydeveloperday "}", 770f9937106Smydeveloperday MicrosoftStyle); 771f9937106Smydeveloperday 772f9937106Smydeveloperday verifyFormat("void baz()\n" 773f9937106Smydeveloperday "{\n" 774f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 775f9937106Smydeveloperday " { A.Remove(item); }));\n" 776f9937106Smydeveloperday "}", 777f9937106Smydeveloperday MicrosoftStyle); 778f9937106Smydeveloperday 779f9937106Smydeveloperday verifyFormat("void bar()\n" 780f9937106Smydeveloperday "{\n" 781f9937106Smydeveloperday " Function(Val, (() =>\n" 782f9937106Smydeveloperday " {\n" 783f9937106Smydeveloperday " lock (mylock)\n" 784f9937106Smydeveloperday " {\n" 785f9937106Smydeveloperday " if (true)\n" 786f9937106Smydeveloperday " {\n" 787f9937106Smydeveloperday " A.Remove(item);\n" 788f9937106Smydeveloperday " }\n" 789f9937106Smydeveloperday " }\n" 790f9937106Smydeveloperday " }));\n" 791f9937106Smydeveloperday "}", 792f9937106Smydeveloperday MicrosoftStyle); 793f9937106Smydeveloperday verifyFormat("void bar()\n" 794f9937106Smydeveloperday "{\n" 795f9937106Smydeveloperday " Function((() =>\n" 796f9937106Smydeveloperday " {\n" 797f9937106Smydeveloperday " lock (mylock)\n" 798f9937106Smydeveloperday " {\n" 799f9937106Smydeveloperday " if (true)\n" 800f9937106Smydeveloperday " {\n" 801f9937106Smydeveloperday " A.Remove(item);\n" 802f9937106Smydeveloperday " }\n" 803f9937106Smydeveloperday " }\n" 804f9937106Smydeveloperday " }));\n" 805f9937106Smydeveloperday "}", 806f9937106Smydeveloperday MicrosoftStyle); 807f9937106Smydeveloperday 808f9937106Smydeveloperday MicrosoftStyle.IndentWidth = 2; 809f9937106Smydeveloperday verifyFormat("void bar()\n" 810f9937106Smydeveloperday "{\n" 811f9937106Smydeveloperday " Function((() =>\n" 812f9937106Smydeveloperday " {\n" 813f9937106Smydeveloperday " lock (mylock)\n" 814f9937106Smydeveloperday " {\n" 815f9937106Smydeveloperday " if (true)\n" 816f9937106Smydeveloperday " {\n" 817f9937106Smydeveloperday " A.Remove(item);\n" 818f9937106Smydeveloperday " }\n" 819f9937106Smydeveloperday " }\n" 820f9937106Smydeveloperday " }));\n" 821f9937106Smydeveloperday "}", 822f9937106Smydeveloperday MicrosoftStyle); 823f9937106Smydeveloperday verifyFormat("void bar() {\n" 824f9937106Smydeveloperday " Function((() => {\n" 825f9937106Smydeveloperday " lock (mylock) {\n" 826f9937106Smydeveloperday " if (true) {\n" 827f9937106Smydeveloperday " A.Remove(item);\n" 828f9937106Smydeveloperday " }\n" 829f9937106Smydeveloperday " }\n" 830f9937106Smydeveloperday " }));\n" 831f9937106Smydeveloperday "}", 832f9937106Smydeveloperday GoogleStyle); 8337117066bSJonathan Coe } 8347117066bSJonathan Coe 835163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) { 836163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 837163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 838163c13feSPeter Stys 839163c13feSPeter Stys verifyFormat(R"(// 840163c13feSPeter Stys public class Sample 841163c13feSPeter Stys { 842163c13feSPeter Stys public void Test() 843163c13feSPeter Stys { 844163c13feSPeter Stys while (true) 845163c13feSPeter Stys { 846163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 847163c13feSPeter Stys CodeThatFollowsLambda(); 848163c13feSPeter Stys IsWellAligned(); 849163c13feSPeter Stys } 850163c13feSPeter Stys } 851163c13feSPeter Stys })", 852163c13feSPeter Stys MicrosoftStyle); 853163c13feSPeter Stys 854163c13feSPeter Stys verifyFormat(R"(// 855163c13feSPeter Stys public class Sample { 856163c13feSPeter Stys public void Test() { 857163c13feSPeter Stys while (true) { 858163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 859163c13feSPeter Stys CodeThatFollowsLambda(); 860163c13feSPeter Stys IsWellAligned(); 861163c13feSPeter Stys } 862163c13feSPeter Stys } 863163c13feSPeter Stys })", 864163c13feSPeter Stys GoogleStyle); 865163c13feSPeter Stys } 866163c13feSPeter Stys 867163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) { 868163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 869163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 870163c13feSPeter Stys 871163c13feSPeter Stys verifyFormat(R"(// 872163c13feSPeter Stys public class Test 873163c13feSPeter Stys { 874163c13feSPeter Stys private static void ComplexLambda(BuildReport protoReport) 875163c13feSPeter Stys { 876163c13feSPeter Stys allSelectedScenes = 877163c13feSPeter Stys veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled) 878163c13feSPeter Stys .Select(scene => scene.path) 879163c13feSPeter Stys .ToArray(); 880163c13feSPeter Stys if (allSelectedScenes.Count == 0) 881163c13feSPeter Stys { 882163c13feSPeter Stys return; 883163c13feSPeter Stys } 884163c13feSPeter Stys Functions(); 885163c13feSPeter Stys AreWell(); 886163c13feSPeter Stys Aligned(); 887163c13feSPeter Stys AfterLambdaBlock(); 888163c13feSPeter Stys } 889163c13feSPeter Stys })", 890163c13feSPeter Stys MicrosoftStyle); 891163c13feSPeter Stys 892163c13feSPeter Stys verifyFormat(R"(// 893163c13feSPeter Stys public class Test { 894163c13feSPeter Stys private static void ComplexLambda(BuildReport protoReport) { 895163c13feSPeter Stys allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds 896163c13feSPeter Stys .Where(scene => scene.enabled) 897163c13feSPeter Stys .Select(scene => scene.path) 898163c13feSPeter Stys .ToArray(); 899163c13feSPeter Stys if (allSelectedScenes.Count == 0) { 900163c13feSPeter Stys return; 901163c13feSPeter Stys } 902163c13feSPeter Stys Functions(); 903163c13feSPeter Stys AreWell(); 904163c13feSPeter Stys Aligned(); 905163c13feSPeter Stys AfterLambdaBlock(); 906163c13feSPeter Stys } 907163c13feSPeter Stys })", 908163c13feSPeter Stys GoogleStyle); 909163c13feSPeter Stys } 910163c13feSPeter Stys 911163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) { 912163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 913163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 914163c13feSPeter Stys 915163c13feSPeter Stys verifyFormat(R"(// 916163c13feSPeter Stys public class Test 917163c13feSPeter Stys { 918163c13feSPeter Stys private static void MultipleLambdas(BuildReport protoReport) 919163c13feSPeter Stys { 920163c13feSPeter Stys allSelectedScenes = 921163c13feSPeter Stys veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled) 922163c13feSPeter Stys .Select(scene => scene.path) 923163c13feSPeter Stys .ToArray(); 924163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 925163c13feSPeter Stys if (allSelectedScenes.Count == 0) 926163c13feSPeter Stys { 927163c13feSPeter Stys return; 928163c13feSPeter Stys } 929163c13feSPeter Stys Functions(); 930163c13feSPeter Stys AreWell(); 931163c13feSPeter Stys Aligned(); 932163c13feSPeter Stys AfterLambdaBlock(); 933163c13feSPeter Stys } 934163c13feSPeter Stys })", 935163c13feSPeter Stys MicrosoftStyle); 936163c13feSPeter Stys 937163c13feSPeter Stys verifyFormat(R"(// 938163c13feSPeter Stys public class Test { 939163c13feSPeter Stys private static void MultipleLambdas(BuildReport protoReport) { 940163c13feSPeter Stys allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds 941163c13feSPeter Stys .Where(scene => scene.enabled) 942163c13feSPeter Stys .Select(scene => scene.path) 943163c13feSPeter Stys .ToArray(); 944163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 945163c13feSPeter Stys if (allSelectedScenes.Count == 0) { 946163c13feSPeter Stys return; 947163c13feSPeter Stys } 948163c13feSPeter Stys Functions(); 949163c13feSPeter Stys AreWell(); 950163c13feSPeter Stys Aligned(); 951163c13feSPeter Stys AfterLambdaBlock(); 952163c13feSPeter Stys } 953163c13feSPeter Stys })", 954163c13feSPeter Stys GoogleStyle); 955163c13feSPeter Stys } 956163c13feSPeter Stys 9570bb60e29SJonathan Coe TEST_F(FormatTestCSharp, CSharpObjectInitializers) { 9580bb60e29SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 9590bb60e29SJonathan Coe 960a11ff39bSJonathan Coe // Start code fragments with a comment line so that C++ raw string literals 9610bb60e29SJonathan Coe // as seen are identical to expected formatted code. 9620bb60e29SJonathan Coe 9630bb60e29SJonathan Coe verifyFormat(R"(// 9640bb60e29SJonathan Coe Shape[] shapes = new[] { 9650bb60e29SJonathan Coe new Circle { 9660bb60e29SJonathan Coe Radius = 2.7281, 9670bb60e29SJonathan Coe Colour = Colours.Red, 9680bb60e29SJonathan Coe }, 9690bb60e29SJonathan Coe new Square { 9700bb60e29SJonathan Coe Side = 101.1, 9710bb60e29SJonathan Coe Colour = Colours.Yellow, 9720bb60e29SJonathan Coe }, 9730bb60e29SJonathan Coe };)", 9740bb60e29SJonathan Coe Style); 9750bb60e29SJonathan Coe 9760bb60e29SJonathan Coe // Omitted final `,`s will change the formatting. 9770bb60e29SJonathan Coe verifyFormat(R"(// 9780bb60e29SJonathan Coe Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red }, 979eb682b80SJonathan Coe new Square { Side = 101.1, Colour = Colours.Yellow } };)", 9800bb60e29SJonathan Coe Style); 9817d2fdd3fSJonathan Coe 9827d2fdd3fSJonathan Coe // Lambdas can be supplied as initialiser arguments. 9837d2fdd3fSJonathan Coe verifyFormat(R"(// 9847d2fdd3fSJonathan Coe private Transformer _transformer = new X.Y { 9857d2fdd3fSJonathan Coe Filler = (Shape shape) => { return new Transform.Fill(shape, RED); }, 9867d2fdd3fSJonathan Coe Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); }, 9877d2fdd3fSJonathan Coe };)", 9887d2fdd3fSJonathan Coe Style); 9890c28a093SJonathan Coe 9900c28a093SJonathan Coe // Dictionary initialisation. 9910c28a093SJonathan Coe verifyFormat(R"(// 9920c28a093SJonathan Coe var myDict = new Dictionary<string, string> { 9930c28a093SJonathan Coe ["name"] = _donald, 9940c28a093SJonathan Coe ["age"] = Convert.ToString(DateTime.Today.Year - 1934), 9950c28a093SJonathan Coe ["type"] = _duck, 9960c28a093SJonathan Coe };)", 9970c28a093SJonathan Coe Style); 9980bb60e29SJonathan Coe } 9990bb60e29SJonathan Coe 10005e1a026cSJonathan Coe TEST_F(FormatTestCSharp, CSharpArrayInitializers) { 10015e1a026cSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 10025e1a026cSJonathan Coe 10035e1a026cSJonathan Coe verifyFormat(R"(// 10045e1a026cSJonathan Coe private MySet<Node>[] setPoints = { 10055e1a026cSJonathan Coe new Point<Node>(), 10065e1a026cSJonathan Coe new Point<Node>(), 10075e1a026cSJonathan Coe };)", 10085e1a026cSJonathan Coe Style); 10095e1a026cSJonathan Coe } 10105e1a026cSJonathan Coe 1011a11ff39bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNamedArguments) { 1012a11ff39bSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1013a11ff39bSJonathan Coe 1014a11ff39bSJonathan Coe verifyFormat(R"(// 10159520bf14SJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)", 1016a11ff39bSJonathan Coe Style); 1017a11ff39bSJonathan Coe 1018a11ff39bSJonathan Coe // Ensure that trailing comments do not cause problems. 1019a11ff39bSJonathan Coe verifyFormat(R"(// 1020a11ff39bSJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug", // comment 1021a11ff39bSJonathan Coe sellerName: "Gift Shop");)", 1022a11ff39bSJonathan Coe Style); 10237dfe0cc7SJonathan Coe 10247dfe0cc7SJonathan Coe verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style); 1025a11ff39bSJonathan Coe } 1026a11ff39bSJonathan Coe 10272bd6974aSJonathan Coe TEST_F(FormatTestCSharp, CSharpPropertyAccessors) { 10282bd6974aSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 10292bd6974aSJonathan Coe 10302bd6974aSJonathan Coe verifyFormat("int Value { get }", Style); 10312bd6974aSJonathan Coe verifyFormat("int Value { get; }", Style); 10322bd6974aSJonathan Coe verifyFormat("int Value { internal get; }", Style); 10332bd6974aSJonathan Coe verifyFormat("int Value { get; } = 0", Style); 10342bd6974aSJonathan Coe verifyFormat("int Value { set }", Style); 10352bd6974aSJonathan Coe verifyFormat("int Value { set; }", Style); 10367a54fcebSMarek Kurdej verifyFormat("int Value { init; }", Style); 10372bd6974aSJonathan Coe verifyFormat("int Value { internal set; }", Style); 10382bd6974aSJonathan Coe verifyFormat("int Value { set; } = 0", Style); 10392bd6974aSJonathan Coe verifyFormat("int Value { get; set }", Style); 10407a54fcebSMarek Kurdej verifyFormat("int Value { get; init; }", Style); 10412bd6974aSJonathan Coe verifyFormat("int Value { set; get }", Style); 10422bd6974aSJonathan Coe verifyFormat("int Value { get; private set; }", Style); 10432bd6974aSJonathan Coe verifyFormat("int Value { get; set; }", Style); 10442bd6974aSJonathan Coe verifyFormat("int Value { get; set; } = 0", Style); 10452bd6974aSJonathan Coe verifyFormat("int Value { internal get; internal set; }", Style); 10462bd6974aSJonathan Coe 10472bd6974aSJonathan Coe // Do not wrap expression body definitions. 10482bd6974aSJonathan Coe verifyFormat(R"(// 10492bd6974aSJonathan Coe public string Name { 10502bd6974aSJonathan Coe get => _name; 10512bd6974aSJonathan Coe set => _name = value; 10522bd6974aSJonathan Coe })", 10532bd6974aSJonathan Coe Style); 10547a54fcebSMarek Kurdej verifyFormat(R"(// 10557a54fcebSMarek Kurdej public string Name { 10567a54fcebSMarek Kurdej init => _name = value; 10577a54fcebSMarek Kurdej get => _name; 10587a54fcebSMarek Kurdej })", 10597a54fcebSMarek Kurdej Style); 10607a54fcebSMarek Kurdej verifyFormat(R"(// 10617a54fcebSMarek Kurdej public string Name { 10627a54fcebSMarek Kurdej set => _name = value; 10637a54fcebSMarek Kurdej get => _name; 10647a54fcebSMarek Kurdej })", 10657a54fcebSMarek Kurdej Style); 106644ad58b9SJonathan Coe 106744ad58b9SJonathan Coe // Examples taken from 106844ad58b9SJonathan Coe // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties 106944ad58b9SJonathan Coe verifyFormat(R"( 107044ad58b9SJonathan Coe // Expression body definitions 107144ad58b9SJonathan Coe public class SaleItem { 107244ad58b9SJonathan Coe public decimal Price { 107344ad58b9SJonathan Coe get => _cost; 107444ad58b9SJonathan Coe set => _cost = value; 107544ad58b9SJonathan Coe } 107644ad58b9SJonathan Coe })", 107744ad58b9SJonathan Coe Style); 107844ad58b9SJonathan Coe 107944ad58b9SJonathan Coe verifyFormat(R"( 108044ad58b9SJonathan Coe // Properties with backing fields 108144ad58b9SJonathan Coe class TimePeriod { 108244ad58b9SJonathan Coe public double Hours { 108344ad58b9SJonathan Coe get { return _seconds / 3600; } 108444ad58b9SJonathan Coe set { 108544ad58b9SJonathan Coe if (value < 0 || value > 24) 10869520bf14SJonathan Coe throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24."); 108744ad58b9SJonathan Coe _seconds = value * 3600; 108844ad58b9SJonathan Coe } 108944ad58b9SJonathan Coe } 109044ad58b9SJonathan Coe })", 109144ad58b9SJonathan Coe Style); 109244ad58b9SJonathan Coe 109344ad58b9SJonathan Coe verifyFormat(R"( 109444ad58b9SJonathan Coe // Auto-implemented properties 109544ad58b9SJonathan Coe public class SaleItem { 109644ad58b9SJonathan Coe public decimal Price { get; set; } 109744ad58b9SJonathan Coe })", 109844ad58b9SJonathan Coe Style); 109944ad58b9SJonathan Coe 110044ad58b9SJonathan Coe // Add column limit to wrap long lines. 110144ad58b9SJonathan Coe Style.ColumnLimit = 100; 110244ad58b9SJonathan Coe 110344ad58b9SJonathan Coe // Examples with assignment to default value. 110444ad58b9SJonathan Coe verifyFormat(R"( 110544ad58b9SJonathan Coe // Long assignment to default value 110644ad58b9SJonathan Coe class MyClass { 110744ad58b9SJonathan Coe public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } = 110844ad58b9SJonathan Coe VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument, 110944ad58b9SJonathan Coe DefaultThirdArgument); 111044ad58b9SJonathan Coe })", 111144ad58b9SJonathan Coe Style); 111244ad58b9SJonathan Coe 111344ad58b9SJonathan Coe verifyFormat(R"( 111444ad58b9SJonathan Coe // Long assignment to default value with expression body 111544ad58b9SJonathan Coe class MyClass { 111644ad58b9SJonathan Coe public override VeryLongNamedTypeIndeed VeryLongNamedValue { 111744ad58b9SJonathan Coe get => veryLongNamedField; 111844ad58b9SJonathan Coe set => veryLongNamedField = value; 111944ad58b9SJonathan Coe } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument, 112044ad58b9SJonathan Coe DefaultThirdArgument); 112144ad58b9SJonathan Coe })", 112244ad58b9SJonathan Coe Style); 11238fa743abSJonathan Coe 11248fa743abSJonathan Coe // Brace wrapping and single-lining of accessor can be controlled by config. 11258fa743abSJonathan Coe Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; 11268fa743abSJonathan Coe Style.BreakBeforeBraces = FormatStyle::BS_Custom; 11278fa743abSJonathan Coe Style.BraceWrapping.AfterFunction = true; 11288fa743abSJonathan Coe 11298fa743abSJonathan Coe verifyFormat(R"(// 11308fa743abSJonathan Coe class TimePeriod { 11318fa743abSJonathan Coe public double Hours 11328fa743abSJonathan Coe { 11338fa743abSJonathan Coe get { 11348fa743abSJonathan Coe return _seconds / 3600; 11358fa743abSJonathan Coe } 11368fa743abSJonathan Coe set { 11378fa743abSJonathan Coe _seconds = value * 3600; 11388fa743abSJonathan Coe } 11398fa743abSJonathan Coe } 11408fa743abSJonathan Coe })", 11418fa743abSJonathan Coe Style); 1142f22b0727SJonathan Coe 1143f22b0727SJonathan Coe // Microsoft style trivial property accessors have no line break before the 1144f22b0727SJonathan Coe // opening brace. 1145f22b0727SJonathan Coe auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 1146f22b0727SJonathan Coe verifyFormat(R"(// 1147f22b0727SJonathan Coe public class SaleItem 1148f22b0727SJonathan Coe { 1149f22b0727SJonathan Coe public decimal Price { get; set; } 1150f22b0727SJonathan Coe })", 1151f22b0727SJonathan Coe MicrosoftStyle); 1152d990cc45SOwen Pan 1153d990cc45SOwen Pan verifyFormat("internal class Program\n" 1154d990cc45SOwen Pan "{\n" 1155d990cc45SOwen Pan " bool AutoAllowKnownApps\n" 1156d990cc45SOwen Pan " {\n" 1157d990cc45SOwen Pan " get;\n" 1158d990cc45SOwen Pan " [Simple]\n" 1159d990cc45SOwen Pan " set;\n" 1160d990cc45SOwen Pan " }\n" 1161d990cc45SOwen Pan "}", 1162d990cc45SOwen Pan MicrosoftStyle); 1163e8c5fea2SJonathan Coe } 1164e8c5fea2SJonathan Coe 1165f537a409SMarek Kurdej TEST_F(FormatTestCSharp, DefaultLiteral) { 1166f537a409SMarek Kurdej FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1167f537a409SMarek Kurdej 1168f537a409SMarek Kurdej verifyFormat( 1169f537a409SMarek Kurdej "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style); 1170f537a409SMarek Kurdej verifyFormat("System.Numerics.Complex fillValue = default;", Style); 1171f537a409SMarek Kurdej verifyFormat("int Value { get } = default;", Style); 1172f537a409SMarek Kurdej verifyFormat("int Value { get } = default!;", Style); 1173f537a409SMarek Kurdej verifyFormat(R"(// 1174f537a409SMarek Kurdej public record Person { 1175f537a409SMarek Kurdej public string GetInit { get; init; } = default!; 1176f537a409SMarek Kurdej };)", 1177f537a409SMarek Kurdej Style); 1178f537a409SMarek Kurdej verifyFormat(R"(// 1179f537a409SMarek Kurdej public record Person { 1180f537a409SMarek Kurdej public string GetSet { get; set; } = default!; 1181f537a409SMarek Kurdej };)", 1182f537a409SMarek Kurdej Style); 1183f537a409SMarek Kurdej } 1184f537a409SMarek Kurdej 1185e8c5fea2SJonathan Coe TEST_F(FormatTestCSharp, CSharpSpaces) { 1186e8c5fea2SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1187e8c5fea2SJonathan Coe Style.SpaceBeforeSquareBrackets = false; 1188e8c5fea2SJonathan Coe Style.SpacesInSquareBrackets = false; 1189e8c5fea2SJonathan Coe Style.SpaceBeforeCpp11BracedList = true; 1190e8c5fea2SJonathan Coe Style.Cpp11BracedListStyle = false; 1191e8c5fea2SJonathan Coe Style.SpacesInContainerLiterals = false; 119207c1978bSJonathan Coe Style.SpaceAfterCStyleCast = false; 1193e8c5fea2SJonathan Coe 1194e8c5fea2SJonathan Coe verifyFormat(R"(new Car { "Door", 0.1 })", Style); 1195e8c5fea2SJonathan Coe verifyFormat(R"(new Car { 0.1, "Door" })", Style); 1196e8c5fea2SJonathan Coe verifyFormat(R"(new string[] { "A" })", Style); 1197e8c5fea2SJonathan Coe verifyFormat(R"(new string[] {})", Style); 1198e8c5fea2SJonathan Coe verifyFormat(R"(new Car { someVariableName })", Style); 1199e8c5fea2SJonathan Coe verifyFormat(R"(new Car { someVariableName })", Style); 1200e8c5fea2SJonathan Coe verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)", 1201e8c5fea2SJonathan Coe Style); 1202e8c5fea2SJonathan Coe verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style); 1203e8c5fea2SJonathan Coe verifyFormat(R"(bool[] xs = { true, true };)", Style); 1204ddc80637Ssstwcw verifyIncompleteFormat( 1205ddc80637Ssstwcw R"(taskContext.Factory.Run(async () => doThing(args);)", Style); 1206e8c5fea2SJonathan Coe verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style); 1207548e540dSJonathan Coe verifyFormat(R"(private float[,] Values;)", Style); 12085c917bd9SJonathan Coe verifyFormat(R"(Result this[Index x] => Foo(x);)", Style); 1209548e540dSJonathan Coe 121004336adaSJonathan Coe verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style); 12117443f86eSJonathan Coe verifyFormat(R"(var (key, value))", Style); 121204336adaSJonathan Coe 1213047898c9SJonathan Coe // `&&` is not seen as a reference. 1214047898c9SJonathan Coe verifyFormat(R"(A == typeof(X) && someBool)", Style); 1215047898c9SJonathan Coe 121607c1978bSJonathan Coe // Not seen as a C-style cast. 121707c1978bSJonathan Coe verifyFormat(R"(// 121807c1978bSJonathan Coe foreach ((A a, B b) in someList) { 121907c1978bSJonathan Coe })", 122007c1978bSJonathan Coe Style); 122107c1978bSJonathan Coe 1222a6794991SJonathan Coe // space after lock in `lock (processes)`. 1223a6794991SJonathan Coe verifyFormat("lock (process)", Style); 1224a6794991SJonathan Coe 1225548e540dSJonathan Coe Style.SpacesInSquareBrackets = true; 1226548e540dSJonathan Coe verifyFormat(R"(private float[ , ] Values;)", Style); 12279c4afce7SJonathan Coe verifyFormat(R"(string dirPath = args?[ 0 ];)", Style); 122804336adaSJonathan Coe verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style); 12295f104a80SŁukasz Krawczyk 12305f104a80SŁukasz Krawczyk // Method returning tuple 12315f104a80SŁukasz Krawczyk verifyFormat(R"(public (string name, int age) methodTuple() {})", Style); 12325f104a80SŁukasz Krawczyk verifyFormat(R"(private (string name, int age) methodTuple() {})", Style); 12335f104a80SŁukasz Krawczyk verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style); 12345f104a80SŁukasz Krawczyk verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style); 12355f104a80SŁukasz Krawczyk verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style); 12365f104a80SŁukasz Krawczyk verifyFormat(R"(static (string name, int age) methodTuple() {})", Style); 12375f104a80SŁukasz Krawczyk verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style); 12385f104a80SŁukasz Krawczyk verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style); 12395f104a80SŁukasz Krawczyk verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style); 12405f104a80SŁukasz Krawczyk verifyFormat(R"(override (string name, int age) methodTuple() {})", Style); 12415f104a80SŁukasz Krawczyk verifyFormat(R"(async (string name, int age) methodTuple() {})", Style); 12425f104a80SŁukasz Krawczyk verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style); 124363395cb0Smydeveloperday 124463395cb0Smydeveloperday Style.SpacesInSquareBrackets = false; 124563395cb0Smydeveloperday Style.SpaceBeforeSquareBrackets = true; 124663395cb0Smydeveloperday verifyFormat("return a is [1, 2, 3];", Style); 124763395cb0Smydeveloperday verifyFormat("return a is [..];", Style); 124863395cb0Smydeveloperday Style.SpaceBeforeSquareBrackets = false; 124963395cb0Smydeveloperday verifyFormat("return a is [1, 2, 3];", Style); 125063395cb0Smydeveloperday verifyFormat("return a is [..];", Style); 12515f52a93bSJonathan Coe } 12525f52a93bSJonathan Coe 12535f52a93bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNullableTypes) { 12545f52a93bSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 12555f52a93bSJonathan Coe Style.SpacesInSquareBrackets = false; 12565f52a93bSJonathan Coe 1257fe61bc1aSJonathan Coe verifyFormat(R"(// 1258fe61bc1aSJonathan Coe public class A { 12599520bf14SJonathan Coe void foo() { 12609520bf14SJonathan Coe int? value = some.bar(); 12619520bf14SJonathan Coe } 1262fe61bc1aSJonathan Coe })", 1263fe61bc1aSJonathan Coe Style); // int? is nullable not a conditional expression. 1264fe61bc1aSJonathan Coe 1265fe61bc1aSJonathan Coe verifyFormat(R"(void foo(int? x, int? y, int? z) {})", 1266fe61bc1aSJonathan Coe Style); // Nullables in function definitions. 1267fe61bc1aSJonathan Coe 12685f52a93bSJonathan Coe verifyFormat(R"(public float? Value;)", Style); // no space before `?`. 1269fe61bc1aSJonathan Coe 12705f52a93bSJonathan Coe verifyFormat(R"(int?[] arr = new int?[10];)", 12715f52a93bSJonathan Coe Style); // An array of a nullable type. 12721fb9c298SJonathan Coe 12731fb9c298SJonathan Coe verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type. 12741fb9c298SJonathan Coe 12751fb9c298SJonathan Coe verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics. 1276ec725b30SEliza Velasquez 1277ec725b30SEliza Velasquez verifyFormat(R"(// 1278ec725b30SEliza Velasquez public interface I { 1279ec725b30SEliza Velasquez int? Function(); 1280ec725b30SEliza Velasquez })", 1281ec725b30SEliza Velasquez Style); // Interface methods. 1282ec725b30SEliza Velasquez 1283ec725b30SEliza Velasquez Style.ColumnLimit = 10; 1284ec725b30SEliza Velasquez verifyFormat(R"(// 1285ec725b30SEliza Velasquez public VeryLongType? Function( 1286ec725b30SEliza Velasquez int arg1, 1287ec725b30SEliza Velasquez int arg2) { 1288ec725b30SEliza Velasquez // 1289ec725b30SEliza Velasquez })", 1290ec725b30SEliza Velasquez Style); // ? sticks with identifier. 12912bd6974aSJonathan Coe } 12922bd6974aSJonathan Coe 1293736fef97SJonathan Coe TEST_F(FormatTestCSharp, CSharpArraySubscripts) { 1294736fef97SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1295736fef97SJonathan Coe 1296736fef97SJonathan Coe // Do not format array subscript operators as attributes. 1297b28ed9ceSJonathan Coe verifyFormat(R"(// 1298b28ed9ceSJonathan Coe if (someThings[index].Contains(myThing)) { 1299b28ed9ceSJonathan Coe })", 1300b28ed9ceSJonathan Coe Style); 1301b28ed9ceSJonathan Coe 1302b28ed9ceSJonathan Coe verifyFormat(R"(// 1303b28ed9ceSJonathan Coe if (someThings[i][j][k].Contains(myThing)) { 1304b28ed9ceSJonathan Coe })", 1305b28ed9ceSJonathan Coe Style); 1306736fef97SJonathan Coe } 1307736fef97SJonathan Coe 1308dcbcec48SJonathan Coe TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) { 1309dcbcec48SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1310dcbcec48SJonathan Coe 131100dc97f1Smydeveloperday EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord); 131200dc97f1Smydeveloperday 131300dc97f1Smydeveloperday verifyFormat("class ItemFactory<T>\n" 131400dc97f1Smydeveloperday " where T : new() {\n" 131500dc97f1Smydeveloperday "}", 1316ece7e95fSmydeveloperday Style); 1317dcbcec48SJonathan Coe 1318e3acfbc4Ssstwcw // When the "where" line is not to be formatted, following lines should not 1319e3acfbc4Ssstwcw // take on its indentation. 1320e3acfbc4Ssstwcw verifyFormat("class ItemFactory<T>\n" 1321e3acfbc4Ssstwcw " where T : new() {\n" 1322e3acfbc4Ssstwcw " int f() {}\n" 1323e3acfbc4Ssstwcw "}", 1324e3acfbc4Ssstwcw "class ItemFactory<T>\n" 1325e3acfbc4Ssstwcw " where T : new() {\n" 1326e3acfbc4Ssstwcw " int f() {}\n" 1327e3acfbc4Ssstwcw "}", 1328e3acfbc4Ssstwcw Style, {tooling::Range(43, 13)}); 1329e3acfbc4Ssstwcw 133000dc97f1Smydeveloperday verifyFormat("class Dictionary<TKey, TVal>\n" 133100dc97f1Smydeveloperday " where TKey : IComparable<TKey>\n" 133200dc97f1Smydeveloperday " where TVal : IMyInterface {\n" 133300dc97f1Smydeveloperday " public void MyMethod<T>(T t)\n" 133400dc97f1Smydeveloperday " where T : IMyInterface {\n" 133500dc97f1Smydeveloperday " doThing();\n" 133600dc97f1Smydeveloperday " }\n" 133700dc97f1Smydeveloperday "}", 1338dcbcec48SJonathan Coe Style); 133978e2a3c6SJonathan Coe 134000dc97f1Smydeveloperday verifyFormat("class ItemFactory<T>\n" 134100dc97f1Smydeveloperday " where T : new(), IAnInterface<T>, IAnotherInterface<T>, " 134200dc97f1Smydeveloperday "IAnotherInterfaceStill<T> {\n" 134300dc97f1Smydeveloperday "}", 1344d1b412aeSJonathan Coe Style); 1345d1b412aeSJonathan Coe 1346d1b412aeSJonathan Coe Style.ColumnLimit = 50; // Force lines to be wrapped. 1347d1b412aeSJonathan Coe verifyFormat(R"(// 1348d1b412aeSJonathan Coe class ItemFactory<T, U> 1349d1b412aeSJonathan Coe where T : new(), 1350d1b412aeSJonathan Coe IAnInterface<T>, 1351d1b412aeSJonathan Coe IAnotherInterface<T, U>, 135200dc97f1Smydeveloperday IAnotherInterfaceStill<T, U> { 135300dc97f1Smydeveloperday })", 135478e2a3c6SJonathan Coe Style); 13550574030cSKrasimir Georgiev 13560574030cSKrasimir Georgiev // In other languages `where` can be used as a normal identifier. 13570574030cSKrasimir Georgiev // This example is in C++! 13580574030cSKrasimir Georgiev verifyFormat(R"(// 13590574030cSKrasimir Georgiev class A { 13600574030cSKrasimir Georgiev int f(int where) {} 13610574030cSKrasimir Georgiev };)", 13620574030cSKrasimir Georgiev getGoogleStyle(FormatStyle::LK_Cpp)); 1363dcbcec48SJonathan Coe } 1364dcbcec48SJonathan Coe 1365ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterEnum) { 1366ed367b9dSmydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1367ed367b9dSmydeveloperday Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1368ed367b9dSmydeveloperday Style.BraceWrapping.AfterEnum = false; 1369ed367b9dSmydeveloperday Style.AllowShortEnumsOnASingleLine = false; 1370ed367b9dSmydeveloperday 1371ed367b9dSmydeveloperday verifyFormat("enum MyEnum {\n" 1372ed367b9dSmydeveloperday " Foo,\n" 1373ed367b9dSmydeveloperday " Bar,\n" 1374ed367b9dSmydeveloperday "}", 1375ed367b9dSmydeveloperday Style); 1376ed367b9dSmydeveloperday verifyFormat("internal enum MyEnum {\n" 1377ed367b9dSmydeveloperday " Foo,\n" 1378ed367b9dSmydeveloperday " Bar,\n" 1379ed367b9dSmydeveloperday "}", 1380ed367b9dSmydeveloperday Style); 1381ed367b9dSmydeveloperday verifyFormat("public enum MyEnum {\n" 1382ed367b9dSmydeveloperday " Foo,\n" 1383ed367b9dSmydeveloperday " Bar,\n" 1384ed367b9dSmydeveloperday "}", 1385ed367b9dSmydeveloperday Style); 1386ed367b9dSmydeveloperday verifyFormat("protected enum MyEnum {\n" 1387ed367b9dSmydeveloperday " Foo,\n" 1388ed367b9dSmydeveloperday " Bar,\n" 1389ed367b9dSmydeveloperday "}", 1390ed367b9dSmydeveloperday Style); 1391ed367b9dSmydeveloperday verifyFormat("private enum MyEnum {\n" 1392ed367b9dSmydeveloperday " Foo,\n" 1393ed367b9dSmydeveloperday " Bar,\n" 1394ed367b9dSmydeveloperday "}", 1395ed367b9dSmydeveloperday Style); 1396ed367b9dSmydeveloperday 1397ed367b9dSmydeveloperday Style.BraceWrapping.AfterEnum = true; 1398ed367b9dSmydeveloperday Style.AllowShortEnumsOnASingleLine = false; 1399ed367b9dSmydeveloperday 1400ed367b9dSmydeveloperday verifyFormat("enum MyEnum\n" 1401ed367b9dSmydeveloperday "{\n" 1402ed367b9dSmydeveloperday " Foo,\n" 1403ed367b9dSmydeveloperday " Bar,\n" 1404ed367b9dSmydeveloperday "}", 1405ed367b9dSmydeveloperday Style); 1406ed367b9dSmydeveloperday verifyFormat("internal enum MyEnum\n" 1407ed367b9dSmydeveloperday "{\n" 1408ed367b9dSmydeveloperday " Foo,\n" 1409ed367b9dSmydeveloperday " Bar,\n" 1410ed367b9dSmydeveloperday "}", 1411ed367b9dSmydeveloperday Style); 1412ed367b9dSmydeveloperday verifyFormat("public enum MyEnum\n" 1413ed367b9dSmydeveloperday "{\n" 1414ed367b9dSmydeveloperday " Foo,\n" 1415ed367b9dSmydeveloperday " Bar,\n" 1416ed367b9dSmydeveloperday "}", 1417ed367b9dSmydeveloperday Style); 1418ed367b9dSmydeveloperday verifyFormat("protected enum MyEnum\n" 1419ed367b9dSmydeveloperday "{\n" 1420ed367b9dSmydeveloperday " Foo,\n" 1421ed367b9dSmydeveloperday " Bar,\n" 1422ed367b9dSmydeveloperday "}", 1423ed367b9dSmydeveloperday Style); 1424ed367b9dSmydeveloperday verifyFormat("private enum MyEnum\n" 1425ed367b9dSmydeveloperday "{\n" 1426ed367b9dSmydeveloperday " Foo,\n" 1427ed367b9dSmydeveloperday " Bar,\n" 1428ed367b9dSmydeveloperday "}", 1429ed367b9dSmydeveloperday Style); 1430ed367b9dSmydeveloperday verifyFormat("/* Foo */ private enum MyEnum\n" 1431ed367b9dSmydeveloperday "{\n" 1432ed367b9dSmydeveloperday " Foo,\n" 1433ed367b9dSmydeveloperday " Bar,\n" 1434ed367b9dSmydeveloperday "}", 1435ed367b9dSmydeveloperday Style); 1436ed367b9dSmydeveloperday verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n" 1437ed367b9dSmydeveloperday "{\n" 1438ed367b9dSmydeveloperday " Foo,\n" 1439ed367b9dSmydeveloperday " Bar,\n" 1440ed367b9dSmydeveloperday "}", 1441ed367b9dSmydeveloperday Style); 1442ed367b9dSmydeveloperday } 1443ed367b9dSmydeveloperday 1444ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterClass) { 1445ed367b9dSmydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1446ed367b9dSmydeveloperday Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1447ed367b9dSmydeveloperday Style.BraceWrapping.AfterClass = false; 1448ed367b9dSmydeveloperday 1449ed367b9dSmydeveloperday verifyFormat("class MyClass {\n" 1450ed367b9dSmydeveloperday " int a;\n" 1451ed367b9dSmydeveloperday " int b;\n" 1452ed367b9dSmydeveloperday "}", 1453ed367b9dSmydeveloperday Style); 1454ed367b9dSmydeveloperday verifyFormat("internal class MyClass {\n" 1455ed367b9dSmydeveloperday " int a;\n" 1456ed367b9dSmydeveloperday " int b;\n" 1457ed367b9dSmydeveloperday "}", 1458ed367b9dSmydeveloperday Style); 1459ed367b9dSmydeveloperday verifyFormat("public class MyClass {\n" 1460ed367b9dSmydeveloperday " int a;\n" 1461ed367b9dSmydeveloperday " int b;\n" 1462ed367b9dSmydeveloperday "}", 1463ed367b9dSmydeveloperday Style); 1464ed367b9dSmydeveloperday verifyFormat("protected class MyClass {\n" 1465ed367b9dSmydeveloperday " int a;\n" 1466ed367b9dSmydeveloperday " int b;\n" 1467ed367b9dSmydeveloperday "}", 1468ed367b9dSmydeveloperday Style); 1469ed367b9dSmydeveloperday verifyFormat("private class MyClass {\n" 1470ed367b9dSmydeveloperday " int a;\n" 1471ed367b9dSmydeveloperday " int b;\n" 1472ed367b9dSmydeveloperday "}", 1473ed367b9dSmydeveloperday Style); 1474ed367b9dSmydeveloperday 1475ed367b9dSmydeveloperday verifyFormat("interface Interface {\n" 1476ed367b9dSmydeveloperday " int a;\n" 1477ed367b9dSmydeveloperday " int b;\n" 1478ed367b9dSmydeveloperday "}", 1479ed367b9dSmydeveloperday Style); 1480ed367b9dSmydeveloperday verifyFormat("internal interface Interface {\n" 1481ed367b9dSmydeveloperday " int a;\n" 1482ed367b9dSmydeveloperday " int b;\n" 1483ed367b9dSmydeveloperday "}", 1484ed367b9dSmydeveloperday Style); 1485ed367b9dSmydeveloperday verifyFormat("public interface Interface {\n" 1486ed367b9dSmydeveloperday " int a;\n" 1487ed367b9dSmydeveloperday " int b;\n" 1488ed367b9dSmydeveloperday "}", 1489ed367b9dSmydeveloperday Style); 1490ed367b9dSmydeveloperday verifyFormat("protected interface Interface {\n" 1491ed367b9dSmydeveloperday " int a;\n" 1492ed367b9dSmydeveloperday " int b;\n" 1493ed367b9dSmydeveloperday "}", 1494ed367b9dSmydeveloperday Style); 1495ed367b9dSmydeveloperday verifyFormat("private interface Interface {\n" 1496ed367b9dSmydeveloperday " int a;\n" 1497ed367b9dSmydeveloperday " int b;\n" 1498ed367b9dSmydeveloperday "}", 1499ed367b9dSmydeveloperday Style); 1500ed367b9dSmydeveloperday 1501ed367b9dSmydeveloperday Style.BraceWrapping.AfterClass = true; 1502ed367b9dSmydeveloperday 1503ed367b9dSmydeveloperday verifyFormat("class MyClass\n" 1504ed367b9dSmydeveloperday "{\n" 1505ed367b9dSmydeveloperday " int a;\n" 1506ed367b9dSmydeveloperday " int b;\n" 1507ed367b9dSmydeveloperday "}", 1508ed367b9dSmydeveloperday Style); 1509ed367b9dSmydeveloperday verifyFormat("internal class MyClass\n" 1510ed367b9dSmydeveloperday "{\n" 1511ed367b9dSmydeveloperday " int a;\n" 1512ed367b9dSmydeveloperday " int b;\n" 1513ed367b9dSmydeveloperday "}", 1514ed367b9dSmydeveloperday Style); 1515ed367b9dSmydeveloperday verifyFormat("public class MyClass\n" 1516ed367b9dSmydeveloperday "{\n" 1517ed367b9dSmydeveloperday " int a;\n" 1518ed367b9dSmydeveloperday " int b;\n" 1519ed367b9dSmydeveloperday "}", 1520ed367b9dSmydeveloperday Style); 1521ed367b9dSmydeveloperday verifyFormat("protected class MyClass\n" 1522ed367b9dSmydeveloperday "{\n" 1523ed367b9dSmydeveloperday " int a;\n" 1524ed367b9dSmydeveloperday " int b;\n" 1525ed367b9dSmydeveloperday "}", 1526ed367b9dSmydeveloperday Style); 1527ed367b9dSmydeveloperday verifyFormat("private class MyClass\n" 1528ed367b9dSmydeveloperday "{\n" 1529ed367b9dSmydeveloperday " int a;\n" 1530ed367b9dSmydeveloperday " int b;\n" 1531ed367b9dSmydeveloperday "}", 1532ed367b9dSmydeveloperday Style); 1533ed367b9dSmydeveloperday 1534ed367b9dSmydeveloperday verifyFormat("interface MyInterface\n" 1535ed367b9dSmydeveloperday "{\n" 1536ed367b9dSmydeveloperday " int a;\n" 1537ed367b9dSmydeveloperday " int b;\n" 1538ed367b9dSmydeveloperday "}", 1539ed367b9dSmydeveloperday Style); 1540ed367b9dSmydeveloperday verifyFormat("internal interface MyInterface\n" 1541ed367b9dSmydeveloperday "{\n" 1542ed367b9dSmydeveloperday " int a;\n" 1543ed367b9dSmydeveloperday " int b;\n" 1544ed367b9dSmydeveloperday "}", 1545ed367b9dSmydeveloperday Style); 1546ed367b9dSmydeveloperday verifyFormat("public interface MyInterface\n" 1547ed367b9dSmydeveloperday "{\n" 1548ed367b9dSmydeveloperday " int a;\n" 1549ed367b9dSmydeveloperday " int b;\n" 1550ed367b9dSmydeveloperday "}", 1551ed367b9dSmydeveloperday Style); 1552ed367b9dSmydeveloperday verifyFormat("protected interface MyInterface\n" 1553ed367b9dSmydeveloperday "{\n" 1554ed367b9dSmydeveloperday " int a;\n" 1555ed367b9dSmydeveloperday " int b;\n" 1556ed367b9dSmydeveloperday "}", 1557ed367b9dSmydeveloperday Style); 1558ed367b9dSmydeveloperday verifyFormat("private interface MyInterface\n" 1559ed367b9dSmydeveloperday "{\n" 1560ed367b9dSmydeveloperday " int a;\n" 1561ed367b9dSmydeveloperday " int b;\n" 1562ed367b9dSmydeveloperday "}", 1563ed367b9dSmydeveloperday Style); 1564ed367b9dSmydeveloperday verifyFormat("/* Foo */ private interface MyInterface\n" 1565ed367b9dSmydeveloperday "{\n" 1566ed367b9dSmydeveloperday " int a;\n" 1567ed367b9dSmydeveloperday " int b;\n" 1568ed367b9dSmydeveloperday "}", 1569ed367b9dSmydeveloperday Style); 1570ed367b9dSmydeveloperday verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n" 1571ed367b9dSmydeveloperday "{\n" 1572ed367b9dSmydeveloperday " int a;\n" 1573ed367b9dSmydeveloperday " int b;\n" 1574ed367b9dSmydeveloperday "}", 1575ed367b9dSmydeveloperday Style); 1576ed367b9dSmydeveloperday } 1577ed367b9dSmydeveloperday 15786e58d14eSmydeveloperday TEST_F(FormatTestCSharp, NamespaceIndentation) { 15796e58d14eSmydeveloperday FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 15806e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_None; 15816e58d14eSmydeveloperday 15826e58d14eSmydeveloperday verifyFormat("namespace A\n" 15836e58d14eSmydeveloperday "{\n" 15846e58d14eSmydeveloperday "public interface Name1\n" 15856e58d14eSmydeveloperday "{\n" 15866e58d14eSmydeveloperday "}\n" 158788934a82SOwen Pan "}", 15886e58d14eSmydeveloperday Style); 15896e58d14eSmydeveloperday 15906e58d14eSmydeveloperday verifyFormat("namespace A.B\n" 15916e58d14eSmydeveloperday "{\n" 15926e58d14eSmydeveloperday "public interface Name1\n" 15936e58d14eSmydeveloperday "{\n" 15946e58d14eSmydeveloperday "}\n" 159588934a82SOwen Pan "}", 15966e58d14eSmydeveloperday Style); 15976e58d14eSmydeveloperday 15986e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_Inner; 15996e58d14eSmydeveloperday 16006e58d14eSmydeveloperday verifyFormat("namespace A\n" 16016e58d14eSmydeveloperday "{\n" 16026e58d14eSmydeveloperday "namespace B\n" 16036e58d14eSmydeveloperday "{\n" 16046e58d14eSmydeveloperday " public interface Name1\n" 16056e58d14eSmydeveloperday " {\n" 16066e58d14eSmydeveloperday " }\n" 16076e58d14eSmydeveloperday "}\n" 160888934a82SOwen Pan "}", 16096e58d14eSmydeveloperday Style); 16106e58d14eSmydeveloperday 16116e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_All; 16126e58d14eSmydeveloperday 16136e58d14eSmydeveloperday verifyFormat("namespace A.B\n" 16146e58d14eSmydeveloperday "{\n" 16156e58d14eSmydeveloperday " public interface Name1\n" 16166e58d14eSmydeveloperday " {\n" 16176e58d14eSmydeveloperday " }\n" 161888934a82SOwen Pan "}", 16196e58d14eSmydeveloperday Style); 16206e58d14eSmydeveloperday 16216e58d14eSmydeveloperday verifyFormat("namespace A\n" 16226e58d14eSmydeveloperday "{\n" 16236e58d14eSmydeveloperday " namespace B\n" 16246e58d14eSmydeveloperday " {\n" 16256e58d14eSmydeveloperday " public interface Name1\n" 16266e58d14eSmydeveloperday " {\n" 16276e58d14eSmydeveloperday " }\n" 16286e58d14eSmydeveloperday " }\n" 162988934a82SOwen Pan "}", 16306e58d14eSmydeveloperday Style); 16316e58d14eSmydeveloperday } 16326e58d14eSmydeveloperday 1633ebed0ca7Smydeveloperday TEST_F(FormatTestCSharp, SwitchExpression) { 1634ebed0ca7Smydeveloperday FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 1635ebed0ca7Smydeveloperday verifyFormat("int x = a switch {\n" 1636ebed0ca7Smydeveloperday " 1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n" 1637ebed0ca7Smydeveloperday " 2 => 1,\n" 1638ebed0ca7Smydeveloperday " _ => 2\n" 163988934a82SOwen Pan "};", 1640ebed0ca7Smydeveloperday Style); 1641ebed0ca7Smydeveloperday } 1642ebed0ca7Smydeveloperday 1643a94aab12Smydeveloperday TEST_F(FormatTestCSharp, EmptyShortBlock) { 1644a94aab12Smydeveloperday auto Style = getLLVMStyle(); 1645a94aab12Smydeveloperday Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; 1646a94aab12Smydeveloperday 1647a94aab12Smydeveloperday verifyFormat("try {\n" 1648a94aab12Smydeveloperday " doA();\n" 1649a94aab12Smydeveloperday "} catch (Exception e) {\n" 1650a94aab12Smydeveloperday " e.printStackTrace();\n" 165188934a82SOwen Pan "}", 1652a94aab12Smydeveloperday Style); 1653a94aab12Smydeveloperday 1654a94aab12Smydeveloperday verifyFormat("try {\n" 1655a94aab12Smydeveloperday " doA();\n" 165688934a82SOwen Pan "} catch (Exception e) {}", 1657a94aab12Smydeveloperday Style); 1658a94aab12Smydeveloperday } 1659a94aab12Smydeveloperday 16607af11989SMarek Kurdej TEST_F(FormatTestCSharp, ShortFunctions) { 16617af11989SMarek Kurdej FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp); 16627af11989SMarek Kurdej Style.NamespaceIndentation = FormatStyle::NI_All; 16637af11989SMarek Kurdej Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 16647af11989SMarek Kurdej verifyFormat("interface Interface {\n" 16657af11989SMarek Kurdej " void f() { return; }\n" 16667af11989SMarek Kurdej "};", 16677af11989SMarek Kurdej Style); 16687af11989SMarek Kurdej verifyFormat("public interface Interface {\n" 16697af11989SMarek Kurdej " void f() { return; }\n" 16707af11989SMarek Kurdej "};", 16717af11989SMarek Kurdej Style); 16727af11989SMarek Kurdej verifyFormat("namespace {\n" 16737af11989SMarek Kurdej " void f() {\n" 16747af11989SMarek Kurdej " return;\n" 16757af11989SMarek Kurdej " }\n" 16767af11989SMarek Kurdej "};", 16777af11989SMarek Kurdej Style); 16787af11989SMarek Kurdej // "union" is not a keyword in C#. 16797af11989SMarek Kurdej verifyFormat("namespace union {\n" 16807af11989SMarek Kurdej " void f() {\n" 16817af11989SMarek Kurdej " return;\n" 16827af11989SMarek Kurdej " }\n" 16837af11989SMarek Kurdej "};", 16847af11989SMarek Kurdej Style); 16857af11989SMarek Kurdej } 16867af11989SMarek Kurdej 1687a72609caSSam McCall TEST_F(FormatTestCSharp, BrokenBrackets) { 1688a72609caSSam McCall EXPECT_NE("", format("int where b <")); // reduced from crasher 1689a72609caSSam McCall } 1690a72609caSSam McCall 1691b5bcdb5cSOwen Pan TEST_F(FormatTestCSharp, GotoCaseLabel) { 1692*d005be33SOwen Pan verifyFormat("switch (i)\n" 1693*d005be33SOwen Pan "{\n" 1694*d005be33SOwen Pan "case 0:\n" 1695*d005be33SOwen Pan " goto case 1;\n" 1696*d005be33SOwen Pan "case 1:\n" 1697*d005be33SOwen Pan " j = 0;\n" 1698*d005be33SOwen Pan " {\n" 1699*d005be33SOwen Pan " break;\n" 1700*d005be33SOwen Pan " }\n" 1701*d005be33SOwen Pan "}", 1702*d005be33SOwen Pan "switch (i) {\n" 1703b5bcdb5cSOwen Pan "case 0:\n" 1704b5bcdb5cSOwen Pan " goto case 1;\n" 1705b5bcdb5cSOwen Pan "case 1:\n" 1706b5bcdb5cSOwen Pan " j = 0;\n" 1707b5bcdb5cSOwen Pan " {\n" 1708b5bcdb5cSOwen Pan " break;\n" 1709b5bcdb5cSOwen Pan " }\n" 1710b5bcdb5cSOwen Pan "}"); 1711b5bcdb5cSOwen Pan } 1712b5bcdb5cSOwen Pan 1713ddc80637Ssstwcw } // namespace 1714ddc80637Ssstwcw } // namespace test 1715cbb726d0SPaul Hoad } // namespace format 1716ddc80637Ssstwcw } // namespace clang 1717