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 9cbb726d0SPaul Hoad #include "FormatTestUtils.h" 10cbb726d0SPaul Hoad #include "clang/Format/Format.h" 11cbb726d0SPaul Hoad #include "llvm/Support/Debug.h" 12cbb726d0SPaul Hoad #include "gtest/gtest.h" 13cbb726d0SPaul Hoad 14cbb726d0SPaul Hoad #define DEBUG_TYPE "format-test" 15cbb726d0SPaul Hoad 16cbb726d0SPaul Hoad namespace clang { 17cbb726d0SPaul Hoad namespace format { 18cbb726d0SPaul Hoad 19cbb726d0SPaul Hoad class FormatTestCSharp : public ::testing::Test { 20cbb726d0SPaul Hoad protected: 21cbb726d0SPaul Hoad static std::string format(llvm::StringRef Code, unsigned Offset, 22cbb726d0SPaul Hoad unsigned Length, const FormatStyle &Style) { 23cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << "---\n"); 24cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << Code << "\n\n"); 25cbb726d0SPaul Hoad std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length)); 26cbb726d0SPaul Hoad tooling::Replacements Replaces = reformat(Style, Code, Ranges); 27cbb726d0SPaul Hoad auto Result = applyAllReplacements(Code, Replaces); 28cbb726d0SPaul Hoad EXPECT_TRUE(static_cast<bool>(Result)); 29cbb726d0SPaul Hoad LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); 30cbb726d0SPaul Hoad return *Result; 31cbb726d0SPaul Hoad } 32cbb726d0SPaul Hoad 33cbb726d0SPaul Hoad static std::string 34cbb726d0SPaul Hoad format(llvm::StringRef Code, 35a2f963bbSPaul Hoad const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) { 36cbb726d0SPaul Hoad return format(Code, 0, Code.size(), Style); 37cbb726d0SPaul Hoad } 38cbb726d0SPaul Hoad 39cbb726d0SPaul Hoad static FormatStyle getStyleWithColumns(unsigned ColumnLimit) { 40a2f963bbSPaul Hoad FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 41cbb726d0SPaul Hoad Style.ColumnLimit = ColumnLimit; 42cbb726d0SPaul Hoad return Style; 43cbb726d0SPaul Hoad } 44cbb726d0SPaul Hoad 45cbb726d0SPaul Hoad static void verifyFormat( 46cbb726d0SPaul Hoad llvm::StringRef Code, 47a2f963bbSPaul Hoad const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) { 48cbb726d0SPaul Hoad EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable"; 49cbb726d0SPaul Hoad EXPECT_EQ(Code.str(), format(test::messUp(Code), Style)); 50cbb726d0SPaul Hoad } 51cbb726d0SPaul Hoad }; 52cbb726d0SPaul Hoad 53cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpClass) { 54a2f963bbSPaul Hoad verifyFormat("public class SomeClass\n" 55a2f963bbSPaul Hoad "{\n" 56a2f963bbSPaul Hoad " void f()\n" 57a2f963bbSPaul Hoad " {\n" 58a2f963bbSPaul Hoad " }\n" 59a2f963bbSPaul Hoad " int g()\n" 60a2f963bbSPaul Hoad " {\n" 61a2f963bbSPaul Hoad " return 0;\n" 62a2f963bbSPaul Hoad " }\n" 63a2f963bbSPaul Hoad " void h()\n" 64a2f963bbSPaul Hoad " {\n" 65a2f963bbSPaul Hoad " while (true)\n" 66a2f963bbSPaul Hoad " f();\n" 67a2f963bbSPaul Hoad " for (;;)\n" 68a2f963bbSPaul Hoad " f();\n" 69a2f963bbSPaul Hoad " if (true)\n" 70a2f963bbSPaul Hoad " f();\n" 71cbb726d0SPaul Hoad " }\n" 72cbb726d0SPaul Hoad "}"); 73f40a7972SJonathan Coe 74f40a7972SJonathan Coe // Ensure that small and empty classes are handled correctly with condensed 75f40a7972SJonathan Coe // (Google C++-like) brace-breaking style. 76f40a7972SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 77f40a7972SJonathan Coe Style.BreakBeforeBraces = FormatStyle::BS_Attach; 78f40a7972SJonathan Coe 79f40a7972SJonathan Coe verifyFormat("public class SomeEmptyClass {}", Style); 80f40a7972SJonathan Coe 81f40a7972SJonathan Coe verifyFormat("public class SomeTinyClass {\n" 82f40a7972SJonathan Coe " int X;\n" 83f40a7972SJonathan Coe "}", 84f40a7972SJonathan Coe Style); 85f40a7972SJonathan Coe verifyFormat("private class SomeTinyClass {\n" 86f40a7972SJonathan Coe " int X;\n" 87f40a7972SJonathan Coe "}", 88f40a7972SJonathan Coe Style); 89f40a7972SJonathan Coe verifyFormat("protected class SomeTinyClass {\n" 90f40a7972SJonathan Coe " int X;\n" 91f40a7972SJonathan Coe "}", 92f40a7972SJonathan Coe Style); 93f40a7972SJonathan Coe verifyFormat("internal class SomeTinyClass {\n" 94f40a7972SJonathan Coe " int X;\n" 95f40a7972SJonathan Coe "}", 96f40a7972SJonathan Coe Style); 97cbb726d0SPaul Hoad } 98cbb726d0SPaul Hoad 99cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, AccessModifiers) { 100a2f963bbSPaul Hoad verifyFormat("public String toString()\n" 101a2f963bbSPaul Hoad "{\n" 102a2f963bbSPaul Hoad "}"); 103a2f963bbSPaul Hoad verifyFormat("private String toString()\n" 104a2f963bbSPaul Hoad "{\n" 105a2f963bbSPaul Hoad "}"); 106a2f963bbSPaul Hoad verifyFormat("protected String toString()\n" 107a2f963bbSPaul Hoad "{\n" 108a2f963bbSPaul Hoad "}"); 109a2f963bbSPaul Hoad verifyFormat("internal String toString()\n" 110a2f963bbSPaul Hoad "{\n" 111a2f963bbSPaul Hoad "}"); 112cbb726d0SPaul Hoad 113a2f963bbSPaul Hoad verifyFormat("public override String toString()\n" 114a2f963bbSPaul Hoad "{\n" 115a2f963bbSPaul Hoad "}"); 116a2f963bbSPaul Hoad verifyFormat("private override String toString()\n" 117a2f963bbSPaul Hoad "{\n" 118a2f963bbSPaul Hoad "}"); 119a2f963bbSPaul Hoad verifyFormat("protected override String toString()\n" 120a2f963bbSPaul Hoad "{\n" 121a2f963bbSPaul Hoad "}"); 122a2f963bbSPaul Hoad verifyFormat("internal override String toString()\n" 123a2f963bbSPaul Hoad "{\n" 124a2f963bbSPaul Hoad "}"); 125cbb726d0SPaul Hoad 126a2f963bbSPaul Hoad verifyFormat("internal static String toString()\n" 127a2f963bbSPaul Hoad "{\n" 128a2f963bbSPaul Hoad "}"); 129cbb726d0SPaul Hoad } 130cbb726d0SPaul Hoad 131cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, NoStringLiteralBreaks) { 132cbb726d0SPaul Hoad verifyFormat("foo(" 133cbb726d0SPaul Hoad "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 134cbb726d0SPaul Hoad "aaaaaa\");"); 135cbb726d0SPaul Hoad } 136cbb726d0SPaul Hoad 137cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) { 138cbb726d0SPaul Hoad verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");"); 139cbb726d0SPaul Hoad // @"ABC\" + ToString("B") - handle embedded \ in literal string at 140cbb726d0SPaul Hoad // the end 141cbb726d0SPaul Hoad // 142cbb726d0SPaul Hoad /* 143cbb726d0SPaul Hoad * After removal of Lexer change we are currently not able 144cbb726d0SPaul Hoad * To handle these cases 145cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");"); 146cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\""); 147cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"\""); 148cbb726d0SPaul Hoad verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc"); 149cbb726d0SPaul Hoad */ 150cbb726d0SPaul Hoad } 151cbb726d0SPaul Hoad 152cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) { 153cbb726d0SPaul Hoad verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");"); 154cbb726d0SPaul Hoad verifyFormat("foo($\"aaaa{A}\");"); 155cbb726d0SPaul Hoad verifyFormat( 156cbb726d0SPaul Hoad "foo($\"aaaa{A}" 157cbb726d0SPaul Hoad "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");"); 158cbb726d0SPaul Hoad verifyFormat("Name = $\"{firstName} {lastName}\";"); 159cbb726d0SPaul Hoad 160cbb726d0SPaul Hoad // $"ABC\" + ToString("B") - handle embedded \ in literal string at 161cbb726d0SPaul Hoad // the end 162cbb726d0SPaul Hoad verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");"); 163cbb726d0SPaul Hoad verifyFormat("$\"{domain}\\\\{user}\""); 164cbb726d0SPaul Hoad verifyFormat( 165cbb726d0SPaul Hoad "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";"); 166cbb726d0SPaul Hoad } 167cbb726d0SPaul Hoad 168cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpFatArrows) { 169cbb726d0SPaul Hoad verifyFormat("Task serverTask = Task.Run(async() => {"); 170cbb726d0SPaul Hoad verifyFormat("public override string ToString() => \"{Name}\\{Age}\";"); 171cbb726d0SPaul Hoad } 172cbb726d0SPaul Hoad 173c3af063cSJonathan Coe TEST_F(FormatTestCSharp, CSharpConditionalExpressions) { 174c3af063cSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 175c3af063cSJonathan Coe // conditional expression is not seen as a NullConditional. 176c3af063cSJonathan Coe verifyFormat("var y = A < B ? -1 : 1;", Style); 177c3af063cSJonathan Coe } 178c3af063cSJonathan Coe 179cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullConditional) { 1804c056583SPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1814c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 1824c056583SPaul Hoad 183cbb726d0SPaul Hoad verifyFormat( 184cbb726d0SPaul Hoad "public Person(string firstName, string lastName, int? age = null)"); 185cbb726d0SPaul Hoad 1864c056583SPaul Hoad verifyFormat("foo () {\n" 1874c056583SPaul Hoad " switch (args?.Length) {}\n" 1884c056583SPaul Hoad "}", 1894c056583SPaul Hoad Style); 1904c056583SPaul Hoad 1914c056583SPaul Hoad verifyFormat("switch (args?.Length) {}", Style); 192cbb726d0SPaul Hoad 193a2f963bbSPaul Hoad verifyFormat("public static void Main(string[] args)\n" 194a2f963bbSPaul Hoad "{\n" 195a2f963bbSPaul Hoad " string dirPath = args?[0];\n" 196a2f963bbSPaul Hoad "}"); 1974c056583SPaul Hoad 1984c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 1994c056583SPaul Hoad 2004c056583SPaul Hoad verifyFormat("switch(args?.Length) {}", Style); 201cbb726d0SPaul Hoad } 202cbb726d0SPaul Hoad 203cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, Attributes) { 204cbb726d0SPaul Hoad verifyFormat("[STAThread]\n" 205a2f963bbSPaul Hoad "static void Main(string[] args)\n" 206a2f963bbSPaul Hoad "{\n" 207a2f963bbSPaul Hoad "}"); 208cbb726d0SPaul Hoad 209cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 210a2f963bbSPaul Hoad "private class Test\n" 211a2f963bbSPaul Hoad "{\n" 212a2f963bbSPaul Hoad "}"); 213cbb726d0SPaul Hoad 214cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 215a2f963bbSPaul Hoad "protected class Test\n" 216a2f963bbSPaul Hoad "{\n" 217a2f963bbSPaul Hoad "}"); 218cbb726d0SPaul Hoad 219cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 220a2f963bbSPaul Hoad "internal class Test\n" 221a2f963bbSPaul Hoad "{\n" 222a2f963bbSPaul Hoad "}"); 223cbb726d0SPaul Hoad 224cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 225a2f963bbSPaul Hoad "class Test\n" 226a2f963bbSPaul Hoad "{\n" 227a2f963bbSPaul Hoad "}"); 228cbb726d0SPaul Hoad 229cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 230cbb726d0SPaul Hoad "[DeploymentItem(\"Test.txt\")]\n" 231a2f963bbSPaul Hoad "public class Test\n" 232a2f963bbSPaul Hoad "{\n" 233a2f963bbSPaul Hoad "}"); 234cbb726d0SPaul Hoad 235cbb726d0SPaul Hoad verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n" 236cbb726d0SPaul Hoad "[System.Runtime.InteropServices.ComVisible(true)]\n" 237a2f963bbSPaul Hoad "public sealed class STAThreadAttribute : Attribute\n" 238a2f963bbSPaul Hoad "{\n" 239a2f963bbSPaul Hoad "}"); 240cbb726d0SPaul Hoad 241cbb726d0SPaul Hoad verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on " 242cbb726d0SPaul Hoad "provided port\")]\n" 243a2f963bbSPaul Hoad "class Test\n" 244a2f963bbSPaul Hoad "{\n" 245a2f963bbSPaul Hoad "}"); 246cbb726d0SPaul Hoad 247cbb726d0SPaul Hoad verifyFormat("[TestMethod]\n" 248f22b0727SJonathan Coe "public string Host { set; get; }"); 249cbb726d0SPaul Hoad 250ffb48d48Smydeveloperday // Adjacent properties should not cause line wrapping issues 251ffb48d48Smydeveloperday verifyFormat("[JsonProperty(\"foo\")]\n" 252ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 253ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 254ffb48d48Smydeveloperday "public string Bar { set; get; }\n" 255ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 256ffb48d48Smydeveloperday "protected string Bar { set; get; }\n" 257ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 258ffb48d48Smydeveloperday "internal string Bar { set; get; }"); 259ffb48d48Smydeveloperday 260ffb48d48Smydeveloperday // Multiple attributes should always be split (not just the first ones) 261ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 262ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 263ffb48d48Smydeveloperday "public string Foo { set; get; }"); 264ffb48d48Smydeveloperday 265ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 266ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 267ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 268ffb48d48Smydeveloperday "[XmlIgnore]\n" 269ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 270ffb48d48Smydeveloperday "public string Bar { set; get; }"); 271ffb48d48Smydeveloperday 272ffb48d48Smydeveloperday verifyFormat("[XmlIgnore]\n" 273ffb48d48Smydeveloperday "[ScriptIgnore]\n" 274ffb48d48Smydeveloperday "[JsonProperty(\"foo\")]\n" 275ffb48d48Smydeveloperday "public string Foo { set; get; }\n" 276ffb48d48Smydeveloperday "[XmlIgnore]\n" 277ffb48d48Smydeveloperday "[ScriptIgnore]\n" 278ffb48d48Smydeveloperday "[JsonProperty(\"bar\")]\n" 279ffb48d48Smydeveloperday "public string Bar { set; get; }"); 280ffb48d48Smydeveloperday 281cbb726d0SPaul Hoad verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server " 282cbb726d0SPaul Hoad "listening on provided host\")]\n" 283f22b0727SJonathan Coe "public string Host { set; get; }"); 28450d8977cSJonathan Coe 28550d8977cSJonathan Coe verifyFormat( 28650d8977cSJonathan Coe "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n" 28750d8977cSJonathan Coe "// The const char* returned by hello_world must not be deleted.\n" 28850d8977cSJonathan Coe "private static extern IntPtr HelloFromCpp();)"); 289ca1fd460SJonathan Coe 290b46f925dSJonathan Coe // Class attributes go on their own line and do not affect layout of 291b46f925dSJonathan Coe // interfaces. Line wrapping decisions previously caused each interface to be 292b46f925dSJonathan Coe // on its own line. 293b46f925dSJonathan Coe verifyFormat("[SomeAttribute]\n" 294b46f925dSJonathan Coe "[SomeOtherAttribute]\n" 295b46f925dSJonathan Coe "public class A : IShape, IAnimal, IVehicle\n" 296b46f925dSJonathan Coe "{\n" 297b46f925dSJonathan Coe " int X;\n" 298b46f925dSJonathan Coe "}"); 299b46f925dSJonathan Coe 300b46f925dSJonathan Coe // Attributes in a method declaration do not cause line wrapping. 301b46f925dSJonathan Coe verifyFormat("void MethodA([In][Out] ref double x)\n" 302b46f925dSJonathan Coe "{\n" 303b46f925dSJonathan Coe "}"); 304b46f925dSJonathan Coe 305ffb48d48Smydeveloperday verifyFormat("void MethodA([In, Out] ref double x)\n" 306ffb48d48Smydeveloperday "{\n" 307ffb48d48Smydeveloperday "}"); 308ffb48d48Smydeveloperday 309ffb48d48Smydeveloperday verifyFormat("void MethodA([In, Out] double[] x)\n" 310ffb48d48Smydeveloperday "{\n" 311ffb48d48Smydeveloperday "}"); 312ffb48d48Smydeveloperday 313ffb48d48Smydeveloperday verifyFormat("void MethodA([In] double[] x)\n" 314ffb48d48Smydeveloperday "{\n" 315ffb48d48Smydeveloperday "}"); 316ffb48d48Smydeveloperday 317ffb48d48Smydeveloperday verifyFormat("void MethodA(int[] x)\n" 318ffb48d48Smydeveloperday "{\n" 319ffb48d48Smydeveloperday "}"); 320ffb48d48Smydeveloperday verifyFormat("void MethodA(int[][] x)\n" 321ffb48d48Smydeveloperday "{\n" 322ffb48d48Smydeveloperday "}"); 323ffb48d48Smydeveloperday verifyFormat("void MethodA([] x)\n" 324ffb48d48Smydeveloperday "{\n" 325ffb48d48Smydeveloperday "}"); 326ffb48d48Smydeveloperday 327ffb48d48Smydeveloperday verifyFormat("public void Log([CallerLineNumber] int line = -1, " 328ffb48d48Smydeveloperday "[CallerFilePath] string path = null,\n" 329ffb48d48Smydeveloperday " [CallerMemberName] string name = null)\n" 330ffb48d48Smydeveloperday "{\n" 331ffb48d48Smydeveloperday "}"); 332ffb48d48Smydeveloperday 3339f8a7e82SJonathan Coe // [] in an attribute do not cause premature line wrapping or indenting. 3349f8a7e82SJonathan Coe verifyFormat(R"(// 3359f8a7e82SJonathan Coe public class A 3369f8a7e82SJonathan Coe { 3379f8a7e82SJonathan Coe [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)] 3389f8a7e82SJonathan Coe [DoNotSerialize] 3399f8a7e82SJonathan Coe public Data MemberVariable; 3409f8a7e82SJonathan Coe })"); 3419f8a7e82SJonathan Coe 342ca1fd460SJonathan Coe // Unwrappable lines go on a line of their own. 343ca1fd460SJonathan Coe // 'target:' is not treated as a label. 344ca1fd460SJonathan Coe // Modify Style to enforce a column limit. 345ca1fd460SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 346ca1fd460SJonathan Coe Style.ColumnLimit = 10; 347ca1fd460SJonathan Coe verifyFormat(R"([assembly:InternalsVisibleTo( 348ca1fd460SJonathan Coe "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])", 349ca1fd460SJonathan Coe Style); 350cbb726d0SPaul Hoad } 351cbb726d0SPaul Hoad 352719087bbSPaul Hoad TEST_F(FormatTestCSharp, CSharpUsing) { 353719087bbSPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 354719087bbSPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 355719087bbSPaul Hoad verifyFormat("public void foo () {\n" 356719087bbSPaul Hoad " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n" 3571e0174a9SKrasimir Georgiev " using () {}\n" 358719087bbSPaul Hoad "}", 359719087bbSPaul Hoad Style); 360719087bbSPaul Hoad 3611e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 3624c056583SPaul Hoad verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}", 3634c056583SPaul Hoad Style); 3644c056583SPaul Hoad 365719087bbSPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 366719087bbSPaul Hoad verifyFormat("public void foo() {\n" 367719087bbSPaul Hoad " using(StreamWriter sw = new StreamWriter(filenameB)) {}\n" 3681e0174a9SKrasimir Georgiev " using() {}\n" 369719087bbSPaul Hoad "}", 370719087bbSPaul Hoad Style); 3714c056583SPaul Hoad 3721e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 3731e0174a9SKrasimir Georgiev verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}", 3741e0174a9SKrasimir Georgiev Style); 3751e0174a9SKrasimir Georgiev 3761e0174a9SKrasimir Georgiev Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements; 3771e0174a9SKrasimir Georgiev verifyFormat("public void foo() {\n" 3781e0174a9SKrasimir Georgiev " using (StreamWriter sw = new StreamWriter(filenameA)) {}\n" 3791e0174a9SKrasimir Georgiev " using () {}\n" 3801e0174a9SKrasimir Georgiev "}", 3811e0174a9SKrasimir Georgiev Style); 3821e0174a9SKrasimir Georgiev 3831e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 3841e0174a9SKrasimir Georgiev verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}", 3851e0174a9SKrasimir Georgiev Style); 3861e0174a9SKrasimir Georgiev 3871e0174a9SKrasimir Georgiev Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses; 3881e0174a9SKrasimir Georgiev verifyFormat("public void foo() {\n" 3891e0174a9SKrasimir Georgiev " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n" 3901e0174a9SKrasimir Georgiev " using() {}\n" 3911e0174a9SKrasimir Georgiev "}", 3921e0174a9SKrasimir Georgiev Style); 3931e0174a9SKrasimir Georgiev 3941e0174a9SKrasimir Georgiev // Ensure clang-format affects top-level snippets correctly. 3954c056583SPaul Hoad verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}", 3964c056583SPaul Hoad Style); 397719087bbSPaul Hoad } 398719087bbSPaul Hoad 399cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpRegions) { 400cbb726d0SPaul Hoad verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa " 401cbb726d0SPaul Hoad "aaaaaaaaaaaaaaa long region"); 402cbb726d0SPaul Hoad } 403cbb726d0SPaul Hoad 404cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) { 405ed367b9dSmydeveloperday // AfterEnum is true by default. 406ed367b9dSmydeveloperday verifyFormat("public enum var\n" 407ed367b9dSmydeveloperday "{\n" 408292058a5SAaron Smith " none,\n" 409292058a5SAaron Smith " @string,\n" 410292058a5SAaron Smith " bool,\n" 411292058a5SAaron Smith " @enum\n" 412292058a5SAaron Smith "}"); 413cbb726d0SPaul Hoad } 414cbb726d0SPaul Hoad 415cbb726d0SPaul Hoad TEST_F(FormatTestCSharp, CSharpNullCoalescing) { 416cbb726d0SPaul Hoad verifyFormat("var test = ABC ?? DEF"); 417cbb726d0SPaul Hoad verifyFormat("string myname = name ?? \"ABC\";"); 418cbb726d0SPaul Hoad verifyFormat("return _name ?? \"DEF\";"); 419cbb726d0SPaul Hoad } 420cbb726d0SPaul Hoad 421a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) { 422a437befaSEliza Velasquez FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 423a437befaSEliza Velasquez Style.SpaceBeforeAssignmentOperators = true; 424a437befaSEliza Velasquez 425a437befaSEliza Velasquez verifyFormat(R"(test ??= ABC;)", Style); 426a437befaSEliza Velasquez verifyFormat(R"(test ??= true;)", Style); 427a437befaSEliza Velasquez 428a437befaSEliza Velasquez Style.SpaceBeforeAssignmentOperators = false; 429a437befaSEliza Velasquez 430a437befaSEliza Velasquez verifyFormat(R"(test??= ABC;)", Style); 431a437befaSEliza Velasquez verifyFormat(R"(test??= true;)", Style); 432a437befaSEliza Velasquez } 433a437befaSEliza Velasquez 434a437befaSEliza Velasquez TEST_F(FormatTestCSharp, CSharpNullForgiving) { 435a437befaSEliza Velasquez FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 436a437befaSEliza Velasquez 437a437befaSEliza Velasquez verifyFormat("var test = null!;", Style); 438a437befaSEliza Velasquez verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style); 439a437befaSEliza Velasquez verifyFormat("int test = (1! + 2 + bar! + foo())!", Style); 440a437befaSEliza Velasquez verifyFormat(R"(test ??= !foo!;)", Style); 441a437befaSEliza Velasquez verifyFormat("test = !bar! ?? !foo!;", Style); 442a437befaSEliza Velasquez verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && " 443a437befaSEliza Velasquez "!false! && !bar()! + (!foo()))!", 444a437befaSEliza Velasquez Style); 445a437befaSEliza Velasquez 446a437befaSEliza Velasquez // Check that line break keeps identifier with the bang. 447a437befaSEliza Velasquez Style.ColumnLimit = 14; 448a437befaSEliza Velasquez 449a437befaSEliza Velasquez verifyFormat("var test =\n" 450a437befaSEliza Velasquez " foo!;", 451a437befaSEliza Velasquez Style); 452a437befaSEliza Velasquez } 453a437befaSEliza Velasquez 454a2f963bbSPaul Hoad TEST_F(FormatTestCSharp, AttributesIndentation) { 455a2f963bbSPaul Hoad FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 456a2f963bbSPaul Hoad Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None; 457a2f963bbSPaul Hoad 458a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 459a2f963bbSPaul Hoad "static void Main(string[] args)\n" 460a2f963bbSPaul Hoad "{\n" 461a2f963bbSPaul Hoad "}", 462a2f963bbSPaul Hoad Style); 463a2f963bbSPaul Hoad 464a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 465a2f963bbSPaul Hoad "void " 466a2f963bbSPaul Hoad "veryLooooooooooooooongFunctionName(string[] args)\n" 467a2f963bbSPaul Hoad "{\n" 468a2f963bbSPaul Hoad "}", 469a2f963bbSPaul Hoad Style); 470a2f963bbSPaul Hoad 471a2f963bbSPaul Hoad verifyFormat("[STAThread]\n" 472a2f963bbSPaul Hoad "veryLoooooooooooooooooooongReturnType " 473a2f963bbSPaul Hoad "veryLooooooooooooooongFunctionName(string[] args)\n" 474a2f963bbSPaul Hoad "{\n" 475a2f963bbSPaul Hoad "}", 476a2f963bbSPaul Hoad Style); 477a2f963bbSPaul Hoad 478a2f963bbSPaul Hoad verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n" 479a2f963bbSPaul Hoad "public override X Y()\n" 480a2f963bbSPaul Hoad "{\n" 481a2f963bbSPaul Hoad "}\n", 482a2f963bbSPaul Hoad Style); 483a2f963bbSPaul Hoad 484a2f963bbSPaul Hoad verifyFormat("[SuppressMessage]\n" 485a2f963bbSPaul Hoad "public X Y()\n" 486a2f963bbSPaul Hoad "{\n" 487a2f963bbSPaul Hoad "}\n", 488a2f963bbSPaul Hoad Style); 489a2f963bbSPaul Hoad 490a2f963bbSPaul Hoad verifyFormat("[SuppressMessage]\n" 491a2f963bbSPaul Hoad "public override X Y()\n" 492a2f963bbSPaul Hoad "{\n" 493a2f963bbSPaul Hoad "}\n", 494a2f963bbSPaul Hoad Style); 495a2f963bbSPaul Hoad 496a2f963bbSPaul Hoad verifyFormat("public A(B b) : base(b)\n" 497a2f963bbSPaul Hoad "{\n" 498a2f963bbSPaul Hoad " [SuppressMessage]\n" 499a2f963bbSPaul Hoad " public override X Y()\n" 500a2f963bbSPaul Hoad " {\n" 501a2f963bbSPaul Hoad " }\n" 502a2f963bbSPaul Hoad "}\n", 503a2f963bbSPaul Hoad Style); 5042f209ccfSmydeveloperday 5052f209ccfSmydeveloperday verifyFormat("public A : Base\n" 5062f209ccfSmydeveloperday "{\n" 5072f209ccfSmydeveloperday "}\n" 5082f209ccfSmydeveloperday "[Test]\n" 5092f209ccfSmydeveloperday "public Foo()\n" 5102f209ccfSmydeveloperday "{\n" 5112f209ccfSmydeveloperday "}\n", 5122f209ccfSmydeveloperday Style); 5132f209ccfSmydeveloperday 5142f209ccfSmydeveloperday verifyFormat("namespace\n" 5152f209ccfSmydeveloperday "{\n" 5162f209ccfSmydeveloperday "public A : Base\n" 5172f209ccfSmydeveloperday "{\n" 5182f209ccfSmydeveloperday "}\n" 5192f209ccfSmydeveloperday "[Test]\n" 5202f209ccfSmydeveloperday "public Foo()\n" 5212f209ccfSmydeveloperday "{\n" 5222f209ccfSmydeveloperday "}\n" 5232f209ccfSmydeveloperday "}\n", 5242f209ccfSmydeveloperday Style); 525a2f963bbSPaul Hoad } 526a2f963bbSPaul Hoad 5274c056583SPaul Hoad TEST_F(FormatTestCSharp, CSharpSpaceBefore) { 5284c056583SPaul Hoad FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 5294c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Always; 5304c056583SPaul Hoad 5314c056583SPaul Hoad verifyFormat("List<string> list;", Style); 5324c056583SPaul Hoad verifyFormat("Dictionary<string, string> dict;", Style); 5334c056583SPaul Hoad 5344c056583SPaul Hoad verifyFormat("for (int i = 0; i < size (); i++) {\n" 5354c056583SPaul Hoad "}", 5364c056583SPaul Hoad Style); 5374c056583SPaul Hoad verifyFormat("foreach (var x in y) {\n" 5384c056583SPaul Hoad "}", 5394c056583SPaul Hoad Style); 5404c056583SPaul Hoad verifyFormat("switch (x) {}", Style); 5414c056583SPaul Hoad verifyFormat("do {\n" 5424c056583SPaul Hoad "} while (x);", 5434c056583SPaul Hoad Style); 5444c056583SPaul Hoad 5454c056583SPaul Hoad Style.SpaceBeforeParens = FormatStyle::SBPO_Never; 5464c056583SPaul Hoad 5474c056583SPaul Hoad verifyFormat("List<string> list;", Style); 5484c056583SPaul Hoad verifyFormat("Dictionary<string, string> dict;", Style); 5494c056583SPaul Hoad 5504c056583SPaul Hoad verifyFormat("for(int i = 0; i < size(); i++) {\n" 5514c056583SPaul Hoad "}", 5524c056583SPaul Hoad Style); 5534c056583SPaul Hoad verifyFormat("foreach(var x in y) {\n" 5544c056583SPaul Hoad "}", 5554c056583SPaul Hoad Style); 5564c056583SPaul Hoad verifyFormat("switch(x) {}", Style); 5574c056583SPaul Hoad verifyFormat("do {\n" 5584c056583SPaul Hoad "} while(x);", 5594c056583SPaul Hoad Style); 5604c056583SPaul Hoad } 5614c056583SPaul Hoad 562d82adf32Smydeveloperday TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) { 563d82adf32Smydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 564d82adf32Smydeveloperday 565d82adf32Smydeveloperday verifyFormat("(int)x / y;", Style); 566d82adf32Smydeveloperday 567d82adf32Smydeveloperday Style.SpaceAfterCStyleCast = true; 568d82adf32Smydeveloperday verifyFormat("(int) x / y;", Style); 569d82adf32Smydeveloperday } 570d82adf32Smydeveloperday 57136a8f7f6SKrasimir Georgiev TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) { 57236a8f7f6SKrasimir Georgiev FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 57336a8f7f6SKrasimir Georgiev 574f9f0919dSJonathan Coe verifyFormat(R"(string str = @"""";)", Style); 575f9f0919dSJonathan Coe verifyFormat(R"(string str = @"""Hello world""";)", Style); 576f9f0919dSJonathan Coe verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style); 577*0ffb3dd3Sowenca verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style); 57836a8f7f6SKrasimir Georgiev } 57936a8f7f6SKrasimir Georgiev 5809d212e83SJonathan Coe TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) { 5819d212e83SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 5829d212e83SJonathan Coe 5839d212e83SJonathan Coe verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style); 5849d212e83SJonathan Coe verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style); 5859d212e83SJonathan Coe verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style); 5869d212e83SJonathan Coe } 5879d212e83SJonathan Coe 588f9f0919dSJonathan Coe TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) { 589f9f0919dSJonathan Coe // Use MS style as Google Style inserts a line break before multiline strings. 590f9f0919dSJonathan Coe 591f9f0919dSJonathan Coe // verifyFormat does not understand multiline C# string-literals 592f9f0919dSJonathan Coe // so check the format explicitly. 593f9f0919dSJonathan Coe 594f9f0919dSJonathan Coe FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 595f9f0919dSJonathan Coe 596f9f0919dSJonathan Coe std::string Code = R"(string s1 = $@"some code: 597f9f0919dSJonathan Coe class {className} {{ 598f9f0919dSJonathan Coe {className}() {{}} 599f9f0919dSJonathan Coe }}";)"; 600f9f0919dSJonathan Coe 601f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 602f9f0919dSJonathan Coe 603f9f0919dSJonathan Coe // Multiline string in the middle of a function call. 604f9f0919dSJonathan Coe Code = R"( 605f9f0919dSJonathan Coe var x = foo(className, $@"some code: 606f9f0919dSJonathan Coe class {className} {{ 607f9f0919dSJonathan Coe {className}() {{}} 608f9f0919dSJonathan Coe }}", 609f9f0919dSJonathan Coe y);)"; // y aligned with `className` arg. 610f9f0919dSJonathan Coe 611f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 612f9f0919dSJonathan Coe 613f9f0919dSJonathan Coe // Interpolated string with embedded multiline string. 614f9f0919dSJonathan Coe Code = R"(Console.WriteLine($"{string.Join(@", 615f9f0919dSJonathan Coe ", values)}");)"; 616f9f0919dSJonathan Coe 617f9f0919dSJonathan Coe EXPECT_EQ(Code, format(Code, Style)); 618f9f0919dSJonathan Coe } 619f9f0919dSJonathan Coe 6207117066bSJonathan Coe TEST_F(FormatTestCSharp, CSharpLambdas) { 6217117066bSJonathan Coe FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 6227117066bSJonathan Coe FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 6237117066bSJonathan Coe 6247117066bSJonathan Coe verifyFormat(R"(// 6257117066bSJonathan Coe class MyClass { 6267117066bSJonathan Coe Action<string> greet = name => { 6277117066bSJonathan Coe string greeting = $"Hello {name}!"; 6287117066bSJonathan Coe Console.WriteLine(greeting); 6297117066bSJonathan Coe }; 6307117066bSJonathan Coe })", 6317117066bSJonathan Coe GoogleStyle); 6327117066bSJonathan Coe 6337117066bSJonathan Coe // Microsoft Style: 6347117066bSJonathan Coe // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas 6357117066bSJonathan Coe verifyFormat(R"(// 6367117066bSJonathan Coe class MyClass 6377117066bSJonathan Coe { 6387117066bSJonathan Coe Action<string> greet = name => 6397117066bSJonathan Coe { 6407117066bSJonathan Coe string greeting = $"Hello {name}!"; 6417117066bSJonathan Coe Console.WriteLine(greeting); 6427117066bSJonathan Coe }; 6437117066bSJonathan Coe })", 6447117066bSJonathan Coe MicrosoftStyle); 645f9937106Smydeveloperday 646f9937106Smydeveloperday verifyFormat("void bar()\n" 647f9937106Smydeveloperday "{\n" 648f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 649f9937106Smydeveloperday " {\n" 650f9937106Smydeveloperday " lock (mylock)\n" 651f9937106Smydeveloperday " {\n" 652f9937106Smydeveloperday " if (true)\n" 653f9937106Smydeveloperday " {\n" 654f9937106Smydeveloperday " A.Remove(item);\n" 655f9937106Smydeveloperday " }\n" 656f9937106Smydeveloperday " }\n" 657f9937106Smydeveloperday " }));\n" 658f9937106Smydeveloperday "}", 659f9937106Smydeveloperday MicrosoftStyle); 660f9937106Smydeveloperday 661f9937106Smydeveloperday verifyFormat("void baz()\n" 662f9937106Smydeveloperday "{\n" 663f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 664f9937106Smydeveloperday " {\n" 665f9937106Smydeveloperday " using (var a = new Lock())\n" 666f9937106Smydeveloperday " {\n" 667f9937106Smydeveloperday " if (true)\n" 668f9937106Smydeveloperday " {\n" 669f9937106Smydeveloperday " A.Remove(item);\n" 670f9937106Smydeveloperday " }\n" 671f9937106Smydeveloperday " }\n" 672f9937106Smydeveloperday " }));\n" 673f9937106Smydeveloperday "}", 674f9937106Smydeveloperday MicrosoftStyle); 675f9937106Smydeveloperday 676f9937106Smydeveloperday verifyFormat("void baz()\n" 677f9937106Smydeveloperday "{\n" 678f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 679f9937106Smydeveloperday " {\n" 680f9937106Smydeveloperday " if (true)\n" 681f9937106Smydeveloperday " {\n" 682f9937106Smydeveloperday " A.Remove(item);\n" 683f9937106Smydeveloperday " }\n" 684f9937106Smydeveloperday " }));\n" 685f9937106Smydeveloperday "}", 686f9937106Smydeveloperday MicrosoftStyle); 687f9937106Smydeveloperday 688f9937106Smydeveloperday verifyFormat("void baz()\n" 689f9937106Smydeveloperday "{\n" 690f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 691f9937106Smydeveloperday " {\n" 692f9937106Smydeveloperday " do\n" 693f9937106Smydeveloperday " {\n" 694f9937106Smydeveloperday " A.Remove(item);\n" 695f9937106Smydeveloperday " } while (true)\n" 696f9937106Smydeveloperday " }));\n" 697f9937106Smydeveloperday "}", 698f9937106Smydeveloperday MicrosoftStyle); 699f9937106Smydeveloperday 700f9937106Smydeveloperday verifyFormat("void baz()\n" 701f9937106Smydeveloperday "{\n" 702f9937106Smydeveloperday " Function(Val, (Action)(() =>\n" 703f9937106Smydeveloperday " { A.Remove(item); }));\n" 704f9937106Smydeveloperday "}", 705f9937106Smydeveloperday MicrosoftStyle); 706f9937106Smydeveloperday 707f9937106Smydeveloperday verifyFormat("void bar()\n" 708f9937106Smydeveloperday "{\n" 709f9937106Smydeveloperday " Function(Val, (() =>\n" 710f9937106Smydeveloperday " {\n" 711f9937106Smydeveloperday " lock (mylock)\n" 712f9937106Smydeveloperday " {\n" 713f9937106Smydeveloperday " if (true)\n" 714f9937106Smydeveloperday " {\n" 715f9937106Smydeveloperday " A.Remove(item);\n" 716f9937106Smydeveloperday " }\n" 717f9937106Smydeveloperday " }\n" 718f9937106Smydeveloperday " }));\n" 719f9937106Smydeveloperday "}", 720f9937106Smydeveloperday MicrosoftStyle); 721f9937106Smydeveloperday verifyFormat("void bar()\n" 722f9937106Smydeveloperday "{\n" 723f9937106Smydeveloperday " Function((() =>\n" 724f9937106Smydeveloperday " {\n" 725f9937106Smydeveloperday " lock (mylock)\n" 726f9937106Smydeveloperday " {\n" 727f9937106Smydeveloperday " if (true)\n" 728f9937106Smydeveloperday " {\n" 729f9937106Smydeveloperday " A.Remove(item);\n" 730f9937106Smydeveloperday " }\n" 731f9937106Smydeveloperday " }\n" 732f9937106Smydeveloperday " }));\n" 733f9937106Smydeveloperday "}", 734f9937106Smydeveloperday MicrosoftStyle); 735f9937106Smydeveloperday 736f9937106Smydeveloperday MicrosoftStyle.IndentWidth = 2; 737f9937106Smydeveloperday verifyFormat("void bar()\n" 738f9937106Smydeveloperday "{\n" 739f9937106Smydeveloperday " Function((() =>\n" 740f9937106Smydeveloperday " {\n" 741f9937106Smydeveloperday " lock (mylock)\n" 742f9937106Smydeveloperday " {\n" 743f9937106Smydeveloperday " if (true)\n" 744f9937106Smydeveloperday " {\n" 745f9937106Smydeveloperday " A.Remove(item);\n" 746f9937106Smydeveloperday " }\n" 747f9937106Smydeveloperday " }\n" 748f9937106Smydeveloperday " }));\n" 749f9937106Smydeveloperday "}", 750f9937106Smydeveloperday MicrosoftStyle); 751f9937106Smydeveloperday verifyFormat("void bar() {\n" 752f9937106Smydeveloperday " Function((() => {\n" 753f9937106Smydeveloperday " lock (mylock) {\n" 754f9937106Smydeveloperday " if (true) {\n" 755f9937106Smydeveloperday " A.Remove(item);\n" 756f9937106Smydeveloperday " }\n" 757f9937106Smydeveloperday " }\n" 758f9937106Smydeveloperday " }));\n" 759f9937106Smydeveloperday "}", 760f9937106Smydeveloperday GoogleStyle); 7617117066bSJonathan Coe } 7627117066bSJonathan Coe 763163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) { 764163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 765163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 766163c13feSPeter Stys 767163c13feSPeter Stys verifyFormat(R"(// 768163c13feSPeter Stys public class Sample 769163c13feSPeter Stys { 770163c13feSPeter Stys public void Test() 771163c13feSPeter Stys { 772163c13feSPeter Stys while (true) 773163c13feSPeter Stys { 774163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 775163c13feSPeter Stys CodeThatFollowsLambda(); 776163c13feSPeter Stys IsWellAligned(); 777163c13feSPeter Stys } 778163c13feSPeter Stys } 779163c13feSPeter Stys })", 780163c13feSPeter Stys MicrosoftStyle); 781163c13feSPeter Stys 782163c13feSPeter Stys verifyFormat(R"(// 783163c13feSPeter Stys public class Sample { 784163c13feSPeter Stys public void Test() { 785163c13feSPeter Stys while (true) { 786163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 787163c13feSPeter Stys CodeThatFollowsLambda(); 788163c13feSPeter Stys IsWellAligned(); 789163c13feSPeter Stys } 790163c13feSPeter Stys } 791163c13feSPeter Stys })", 792163c13feSPeter Stys GoogleStyle); 793163c13feSPeter Stys } 794163c13feSPeter Stys 795163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) { 796163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 797163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 798163c13feSPeter Stys 799163c13feSPeter Stys verifyFormat(R"(// 800163c13feSPeter Stys public class Test 801163c13feSPeter Stys { 802163c13feSPeter Stys private static void ComplexLambda(BuildReport protoReport) 803163c13feSPeter Stys { 804163c13feSPeter Stys allSelectedScenes = 805163c13feSPeter Stys veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled) 806163c13feSPeter Stys .Select(scene => scene.path) 807163c13feSPeter Stys .ToArray(); 808163c13feSPeter Stys if (allSelectedScenes.Count == 0) 809163c13feSPeter Stys { 810163c13feSPeter Stys return; 811163c13feSPeter Stys } 812163c13feSPeter Stys Functions(); 813163c13feSPeter Stys AreWell(); 814163c13feSPeter Stys Aligned(); 815163c13feSPeter Stys AfterLambdaBlock(); 816163c13feSPeter Stys } 817163c13feSPeter Stys })", 818163c13feSPeter Stys MicrosoftStyle); 819163c13feSPeter Stys 820163c13feSPeter Stys verifyFormat(R"(// 821163c13feSPeter Stys public class Test { 822163c13feSPeter Stys private static void ComplexLambda(BuildReport protoReport) { 823163c13feSPeter Stys allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds 824163c13feSPeter Stys .Where(scene => scene.enabled) 825163c13feSPeter Stys .Select(scene => scene.path) 826163c13feSPeter Stys .ToArray(); 827163c13feSPeter Stys if (allSelectedScenes.Count == 0) { 828163c13feSPeter Stys return; 829163c13feSPeter Stys } 830163c13feSPeter Stys Functions(); 831163c13feSPeter Stys AreWell(); 832163c13feSPeter Stys Aligned(); 833163c13feSPeter Stys AfterLambdaBlock(); 834163c13feSPeter Stys } 835163c13feSPeter Stys })", 836163c13feSPeter Stys GoogleStyle); 837163c13feSPeter Stys } 838163c13feSPeter Stys 839163c13feSPeter Stys TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) { 840163c13feSPeter Stys FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp); 841163c13feSPeter Stys FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 842163c13feSPeter Stys 843163c13feSPeter Stys verifyFormat(R"(// 844163c13feSPeter Stys public class Test 845163c13feSPeter Stys { 846163c13feSPeter Stys private static void MultipleLambdas(BuildReport protoReport) 847163c13feSPeter Stys { 848163c13feSPeter Stys allSelectedScenes = 849163c13feSPeter Stys veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled) 850163c13feSPeter Stys .Select(scene => scene.path) 851163c13feSPeter Stys .ToArray(); 852163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 853163c13feSPeter Stys if (allSelectedScenes.Count == 0) 854163c13feSPeter Stys { 855163c13feSPeter Stys return; 856163c13feSPeter Stys } 857163c13feSPeter Stys Functions(); 858163c13feSPeter Stys AreWell(); 859163c13feSPeter Stys Aligned(); 860163c13feSPeter Stys AfterLambdaBlock(); 861163c13feSPeter Stys } 862163c13feSPeter Stys })", 863163c13feSPeter Stys MicrosoftStyle); 864163c13feSPeter Stys 865163c13feSPeter Stys verifyFormat(R"(// 866163c13feSPeter Stys public class Test { 867163c13feSPeter Stys private static void MultipleLambdas(BuildReport protoReport) { 868163c13feSPeter Stys allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds 869163c13feSPeter Stys .Where(scene => scene.enabled) 870163c13feSPeter Stys .Select(scene => scene.path) 871163c13feSPeter Stys .ToArray(); 872163c13feSPeter Stys preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext()); 873163c13feSPeter Stys if (allSelectedScenes.Count == 0) { 874163c13feSPeter Stys return; 875163c13feSPeter Stys } 876163c13feSPeter Stys Functions(); 877163c13feSPeter Stys AreWell(); 878163c13feSPeter Stys Aligned(); 879163c13feSPeter Stys AfterLambdaBlock(); 880163c13feSPeter Stys } 881163c13feSPeter Stys })", 882163c13feSPeter Stys GoogleStyle); 883163c13feSPeter Stys } 884163c13feSPeter Stys 8850bb60e29SJonathan Coe TEST_F(FormatTestCSharp, CSharpObjectInitializers) { 8860bb60e29SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 8870bb60e29SJonathan Coe 888a11ff39bSJonathan Coe // Start code fragments with a comment line so that C++ raw string literals 8890bb60e29SJonathan Coe // as seen are identical to expected formatted code. 8900bb60e29SJonathan Coe 8910bb60e29SJonathan Coe verifyFormat(R"(// 8920bb60e29SJonathan Coe Shape[] shapes = new[] { 8930bb60e29SJonathan Coe new Circle { 8940bb60e29SJonathan Coe Radius = 2.7281, 8950bb60e29SJonathan Coe Colour = Colours.Red, 8960bb60e29SJonathan Coe }, 8970bb60e29SJonathan Coe new Square { 8980bb60e29SJonathan Coe Side = 101.1, 8990bb60e29SJonathan Coe Colour = Colours.Yellow, 9000bb60e29SJonathan Coe }, 9010bb60e29SJonathan Coe };)", 9020bb60e29SJonathan Coe Style); 9030bb60e29SJonathan Coe 9040bb60e29SJonathan Coe // Omitted final `,`s will change the formatting. 9050bb60e29SJonathan Coe verifyFormat(R"(// 9060bb60e29SJonathan Coe Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red }, 907eb682b80SJonathan Coe new Square { Side = 101.1, Colour = Colours.Yellow } };)", 9080bb60e29SJonathan Coe Style); 9097d2fdd3fSJonathan Coe 9107d2fdd3fSJonathan Coe // Lambdas can be supplied as initialiser arguments. 9117d2fdd3fSJonathan Coe verifyFormat(R"(// 9127d2fdd3fSJonathan Coe private Transformer _transformer = new X.Y { 9137d2fdd3fSJonathan Coe Filler = (Shape shape) => { return new Transform.Fill(shape, RED); }, 9147d2fdd3fSJonathan Coe Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); }, 9157d2fdd3fSJonathan Coe };)", 9167d2fdd3fSJonathan Coe Style); 9170c28a093SJonathan Coe 9180c28a093SJonathan Coe // Dictionary initialisation. 9190c28a093SJonathan Coe verifyFormat(R"(// 9200c28a093SJonathan Coe var myDict = new Dictionary<string, string> { 9210c28a093SJonathan Coe ["name"] = _donald, 9220c28a093SJonathan Coe ["age"] = Convert.ToString(DateTime.Today.Year - 1934), 9230c28a093SJonathan Coe ["type"] = _duck, 9240c28a093SJonathan Coe };)", 9250c28a093SJonathan Coe Style); 9260bb60e29SJonathan Coe } 9270bb60e29SJonathan Coe 9285e1a026cSJonathan Coe TEST_F(FormatTestCSharp, CSharpArrayInitializers) { 9295e1a026cSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 9305e1a026cSJonathan Coe 9315e1a026cSJonathan Coe verifyFormat(R"(// 9325e1a026cSJonathan Coe private MySet<Node>[] setPoints = { 9335e1a026cSJonathan Coe new Point<Node>(), 9345e1a026cSJonathan Coe new Point<Node>(), 9355e1a026cSJonathan Coe };)", 9365e1a026cSJonathan Coe Style); 9375e1a026cSJonathan Coe } 9385e1a026cSJonathan Coe 939a11ff39bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNamedArguments) { 940a11ff39bSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 941a11ff39bSJonathan Coe 942a11ff39bSJonathan Coe verifyFormat(R"(// 9439520bf14SJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)", 944a11ff39bSJonathan Coe Style); 945a11ff39bSJonathan Coe 946a11ff39bSJonathan Coe // Ensure that trailing comments do not cause problems. 947a11ff39bSJonathan Coe verifyFormat(R"(// 948a11ff39bSJonathan Coe PrintOrderDetails(orderNum: 31, productName: "Red Mug", // comment 949a11ff39bSJonathan Coe sellerName: "Gift Shop");)", 950a11ff39bSJonathan Coe Style); 9517dfe0cc7SJonathan Coe 9527dfe0cc7SJonathan Coe verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style); 953a11ff39bSJonathan Coe } 954a11ff39bSJonathan Coe 9552bd6974aSJonathan Coe TEST_F(FormatTestCSharp, CSharpPropertyAccessors) { 9562bd6974aSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 9572bd6974aSJonathan Coe 9582bd6974aSJonathan Coe verifyFormat("int Value { get }", Style); 9592bd6974aSJonathan Coe verifyFormat("int Value { get; }", Style); 9602bd6974aSJonathan Coe verifyFormat("int Value { internal get; }", Style); 9612bd6974aSJonathan Coe verifyFormat("int Value { get; } = 0", Style); 9622bd6974aSJonathan Coe verifyFormat("int Value { set }", Style); 9632bd6974aSJonathan Coe verifyFormat("int Value { set; }", Style); 9647a54fcebSMarek Kurdej verifyFormat("int Value { init; }", Style); 9652bd6974aSJonathan Coe verifyFormat("int Value { internal set; }", Style); 9662bd6974aSJonathan Coe verifyFormat("int Value { set; } = 0", Style); 9672bd6974aSJonathan Coe verifyFormat("int Value { get; set }", Style); 9687a54fcebSMarek Kurdej verifyFormat("int Value { get; init; }", Style); 9692bd6974aSJonathan Coe verifyFormat("int Value { set; get }", Style); 9702bd6974aSJonathan Coe verifyFormat("int Value { get; private set; }", Style); 9712bd6974aSJonathan Coe verifyFormat("int Value { get; set; }", Style); 9722bd6974aSJonathan Coe verifyFormat("int Value { get; set; } = 0", Style); 9732bd6974aSJonathan Coe verifyFormat("int Value { internal get; internal set; }", Style); 9742bd6974aSJonathan Coe 9752bd6974aSJonathan Coe // Do not wrap expression body definitions. 9762bd6974aSJonathan Coe verifyFormat(R"(// 9772bd6974aSJonathan Coe public string Name { 9782bd6974aSJonathan Coe get => _name; 9792bd6974aSJonathan Coe set => _name = value; 9802bd6974aSJonathan Coe })", 9812bd6974aSJonathan Coe Style); 9827a54fcebSMarek Kurdej verifyFormat(R"(// 9837a54fcebSMarek Kurdej public string Name { 9847a54fcebSMarek Kurdej init => _name = value; 9857a54fcebSMarek Kurdej get => _name; 9867a54fcebSMarek Kurdej })", 9877a54fcebSMarek Kurdej Style); 9887a54fcebSMarek Kurdej verifyFormat(R"(// 9897a54fcebSMarek Kurdej public string Name { 9907a54fcebSMarek Kurdej set => _name = value; 9917a54fcebSMarek Kurdej get => _name; 9927a54fcebSMarek Kurdej })", 9937a54fcebSMarek Kurdej Style); 99444ad58b9SJonathan Coe 99544ad58b9SJonathan Coe // Examples taken from 99644ad58b9SJonathan Coe // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties 99744ad58b9SJonathan Coe verifyFormat(R"( 99844ad58b9SJonathan Coe // Expression body definitions 99944ad58b9SJonathan Coe public class SaleItem { 100044ad58b9SJonathan Coe public decimal Price { 100144ad58b9SJonathan Coe get => _cost; 100244ad58b9SJonathan Coe set => _cost = value; 100344ad58b9SJonathan Coe } 100444ad58b9SJonathan Coe })", 100544ad58b9SJonathan Coe Style); 100644ad58b9SJonathan Coe 100744ad58b9SJonathan Coe verifyFormat(R"( 100844ad58b9SJonathan Coe // Properties with backing fields 100944ad58b9SJonathan Coe class TimePeriod { 101044ad58b9SJonathan Coe public double Hours { 101144ad58b9SJonathan Coe get { return _seconds / 3600; } 101244ad58b9SJonathan Coe set { 101344ad58b9SJonathan Coe if (value < 0 || value > 24) 10149520bf14SJonathan Coe throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24."); 101544ad58b9SJonathan Coe _seconds = value * 3600; 101644ad58b9SJonathan Coe } 101744ad58b9SJonathan Coe } 101844ad58b9SJonathan Coe })", 101944ad58b9SJonathan Coe Style); 102044ad58b9SJonathan Coe 102144ad58b9SJonathan Coe verifyFormat(R"( 102244ad58b9SJonathan Coe // Auto-implemented properties 102344ad58b9SJonathan Coe public class SaleItem { 102444ad58b9SJonathan Coe public decimal Price { get; set; } 102544ad58b9SJonathan Coe })", 102644ad58b9SJonathan Coe Style); 102744ad58b9SJonathan Coe 102844ad58b9SJonathan Coe // Add column limit to wrap long lines. 102944ad58b9SJonathan Coe Style.ColumnLimit = 100; 103044ad58b9SJonathan Coe 103144ad58b9SJonathan Coe // Examples with assignment to default value. 103244ad58b9SJonathan Coe verifyFormat(R"( 103344ad58b9SJonathan Coe // Long assignment to default value 103444ad58b9SJonathan Coe class MyClass { 103544ad58b9SJonathan Coe public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } = 103644ad58b9SJonathan Coe VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument, 103744ad58b9SJonathan Coe DefaultThirdArgument); 103844ad58b9SJonathan Coe })", 103944ad58b9SJonathan Coe Style); 104044ad58b9SJonathan Coe 104144ad58b9SJonathan Coe verifyFormat(R"( 104244ad58b9SJonathan Coe // Long assignment to default value with expression body 104344ad58b9SJonathan Coe class MyClass { 104444ad58b9SJonathan Coe public override VeryLongNamedTypeIndeed VeryLongNamedValue { 104544ad58b9SJonathan Coe get => veryLongNamedField; 104644ad58b9SJonathan Coe set => veryLongNamedField = value; 104744ad58b9SJonathan Coe } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument, 104844ad58b9SJonathan Coe DefaultThirdArgument); 104944ad58b9SJonathan Coe })", 105044ad58b9SJonathan Coe Style); 10518fa743abSJonathan Coe 10528fa743abSJonathan Coe // Brace wrapping and single-lining of accessor can be controlled by config. 10538fa743abSJonathan Coe Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never; 10548fa743abSJonathan Coe Style.BreakBeforeBraces = FormatStyle::BS_Custom; 10558fa743abSJonathan Coe Style.BraceWrapping.AfterFunction = true; 10568fa743abSJonathan Coe 10578fa743abSJonathan Coe verifyFormat(R"(// 10588fa743abSJonathan Coe class TimePeriod { 10598fa743abSJonathan Coe public double Hours 10608fa743abSJonathan Coe { 10618fa743abSJonathan Coe get { 10628fa743abSJonathan Coe return _seconds / 3600; 10638fa743abSJonathan Coe } 10648fa743abSJonathan Coe set { 10658fa743abSJonathan Coe _seconds = value * 3600; 10668fa743abSJonathan Coe } 10678fa743abSJonathan Coe } 10688fa743abSJonathan Coe })", 10698fa743abSJonathan Coe Style); 1070f22b0727SJonathan Coe 1071f22b0727SJonathan Coe // Microsoft style trivial property accessors have no line break before the 1072f22b0727SJonathan Coe // opening brace. 1073f22b0727SJonathan Coe auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp); 1074f22b0727SJonathan Coe verifyFormat(R"(// 1075f22b0727SJonathan Coe public class SaleItem 1076f22b0727SJonathan Coe { 1077f22b0727SJonathan Coe public decimal Price { get; set; } 1078f22b0727SJonathan Coe })", 1079f22b0727SJonathan Coe MicrosoftStyle); 1080e8c5fea2SJonathan Coe } 1081e8c5fea2SJonathan Coe 1082f537a409SMarek Kurdej TEST_F(FormatTestCSharp, DefaultLiteral) { 1083f537a409SMarek Kurdej FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1084f537a409SMarek Kurdej 1085f537a409SMarek Kurdej verifyFormat( 1086f537a409SMarek Kurdej "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style); 1087f537a409SMarek Kurdej verifyFormat("System.Numerics.Complex fillValue = default;", Style); 1088f537a409SMarek Kurdej verifyFormat("int Value { get } = default;", Style); 1089f537a409SMarek Kurdej verifyFormat("int Value { get } = default!;", Style); 1090f537a409SMarek Kurdej verifyFormat(R"(// 1091f537a409SMarek Kurdej public record Person { 1092f537a409SMarek Kurdej public string GetInit { get; init; } = default!; 1093f537a409SMarek Kurdej };)", 1094f537a409SMarek Kurdej Style); 1095f537a409SMarek Kurdej verifyFormat(R"(// 1096f537a409SMarek Kurdej public record Person { 1097f537a409SMarek Kurdej public string GetSet { get; set; } = default!; 1098f537a409SMarek Kurdej };)", 1099f537a409SMarek Kurdej Style); 1100f537a409SMarek Kurdej } 1101f537a409SMarek Kurdej 1102e8c5fea2SJonathan Coe TEST_F(FormatTestCSharp, CSharpSpaces) { 1103e8c5fea2SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1104e8c5fea2SJonathan Coe Style.SpaceBeforeSquareBrackets = false; 1105e8c5fea2SJonathan Coe Style.SpacesInSquareBrackets = false; 1106e8c5fea2SJonathan Coe Style.SpaceBeforeCpp11BracedList = true; 1107e8c5fea2SJonathan Coe Style.Cpp11BracedListStyle = false; 1108e8c5fea2SJonathan Coe Style.SpacesInContainerLiterals = false; 110907c1978bSJonathan Coe Style.SpaceAfterCStyleCast = false; 1110e8c5fea2SJonathan Coe 1111e8c5fea2SJonathan Coe verifyFormat(R"(new Car { "Door", 0.1 })", Style); 1112e8c5fea2SJonathan Coe verifyFormat(R"(new Car { 0.1, "Door" })", Style); 1113e8c5fea2SJonathan Coe verifyFormat(R"(new string[] { "A" })", Style); 1114e8c5fea2SJonathan Coe verifyFormat(R"(new string[] {})", Style); 1115e8c5fea2SJonathan Coe verifyFormat(R"(new Car { someVariableName })", Style); 1116e8c5fea2SJonathan Coe verifyFormat(R"(new Car { someVariableName })", Style); 1117e8c5fea2SJonathan Coe verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)", 1118e8c5fea2SJonathan Coe Style); 1119e8c5fea2SJonathan Coe verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style); 1120e8c5fea2SJonathan Coe verifyFormat(R"(bool[] xs = { true, true };)", Style); 1121e8c5fea2SJonathan Coe verifyFormat(R"(taskContext.Factory.Run(async () => doThing(args);)", Style); 1122e8c5fea2SJonathan Coe verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style); 1123548e540dSJonathan Coe verifyFormat(R"(private float[,] Values;)", Style); 11245c917bd9SJonathan Coe verifyFormat(R"(Result this[Index x] => Foo(x);)", Style); 1125548e540dSJonathan Coe 112604336adaSJonathan Coe verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style); 11277443f86eSJonathan Coe verifyFormat(R"(var (key, value))", Style); 112804336adaSJonathan Coe 1129047898c9SJonathan Coe // `&&` is not seen as a reference. 1130047898c9SJonathan Coe verifyFormat(R"(A == typeof(X) && someBool)", Style); 1131047898c9SJonathan Coe 113207c1978bSJonathan Coe // Not seen as a C-style cast. 113307c1978bSJonathan Coe verifyFormat(R"(// 113407c1978bSJonathan Coe foreach ((A a, B b) in someList) { 113507c1978bSJonathan Coe })", 113607c1978bSJonathan Coe Style); 113707c1978bSJonathan Coe 1138a6794991SJonathan Coe // space after lock in `lock (processes)`. 1139a6794991SJonathan Coe verifyFormat("lock (process)", Style); 1140a6794991SJonathan Coe 1141548e540dSJonathan Coe Style.SpacesInSquareBrackets = true; 1142548e540dSJonathan Coe verifyFormat(R"(private float[ , ] Values;)", Style); 11439c4afce7SJonathan Coe verifyFormat(R"(string dirPath = args?[ 0 ];)", Style); 114404336adaSJonathan Coe verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style); 11455f104a80SŁukasz Krawczyk 11465f104a80SŁukasz Krawczyk // Method returning tuple 11475f104a80SŁukasz Krawczyk verifyFormat(R"(public (string name, int age) methodTuple() {})", Style); 11485f104a80SŁukasz Krawczyk verifyFormat(R"(private (string name, int age) methodTuple() {})", Style); 11495f104a80SŁukasz Krawczyk verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style); 11505f104a80SŁukasz Krawczyk verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style); 11515f104a80SŁukasz Krawczyk verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style); 11525f104a80SŁukasz Krawczyk verifyFormat(R"(static (string name, int age) methodTuple() {})", Style); 11535f104a80SŁukasz Krawczyk verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style); 11545f104a80SŁukasz Krawczyk verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style); 11555f104a80SŁukasz Krawczyk verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style); 11565f104a80SŁukasz Krawczyk verifyFormat(R"(override (string name, int age) methodTuple() {})", Style); 11575f104a80SŁukasz Krawczyk verifyFormat(R"(async (string name, int age) methodTuple() {})", Style); 11585f104a80SŁukasz Krawczyk verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style); 11595f52a93bSJonathan Coe } 11605f52a93bSJonathan Coe 11615f52a93bSJonathan Coe TEST_F(FormatTestCSharp, CSharpNullableTypes) { 11625f52a93bSJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 11635f52a93bSJonathan Coe Style.SpacesInSquareBrackets = false; 11645f52a93bSJonathan Coe 1165fe61bc1aSJonathan Coe verifyFormat(R"(// 1166fe61bc1aSJonathan Coe public class A { 11679520bf14SJonathan Coe void foo() { 11689520bf14SJonathan Coe int? value = some.bar(); 11699520bf14SJonathan Coe } 1170fe61bc1aSJonathan Coe })", 1171fe61bc1aSJonathan Coe Style); // int? is nullable not a conditional expression. 1172fe61bc1aSJonathan Coe 1173fe61bc1aSJonathan Coe verifyFormat(R"(void foo(int? x, int? y, int? z) {})", 1174fe61bc1aSJonathan Coe Style); // Nullables in function definitions. 1175fe61bc1aSJonathan Coe 11765f52a93bSJonathan Coe verifyFormat(R"(public float? Value;)", Style); // no space before `?`. 1177fe61bc1aSJonathan Coe 11785f52a93bSJonathan Coe verifyFormat(R"(int?[] arr = new int?[10];)", 11795f52a93bSJonathan Coe Style); // An array of a nullable type. 11801fb9c298SJonathan Coe 11811fb9c298SJonathan Coe verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type. 11821fb9c298SJonathan Coe 11831fb9c298SJonathan Coe verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics. 1184ec725b30SEliza Velasquez 1185ec725b30SEliza Velasquez verifyFormat(R"(// 1186ec725b30SEliza Velasquez public interface I { 1187ec725b30SEliza Velasquez int? Function(); 1188ec725b30SEliza Velasquez })", 1189ec725b30SEliza Velasquez Style); // Interface methods. 1190ec725b30SEliza Velasquez 1191ec725b30SEliza Velasquez Style.ColumnLimit = 10; 1192ec725b30SEliza Velasquez verifyFormat(R"(// 1193ec725b30SEliza Velasquez public VeryLongType? Function( 1194ec725b30SEliza Velasquez int arg1, 1195ec725b30SEliza Velasquez int arg2) { 1196ec725b30SEliza Velasquez // 1197ec725b30SEliza Velasquez })", 1198ec725b30SEliza Velasquez Style); // ? sticks with identifier. 11992bd6974aSJonathan Coe } 12002bd6974aSJonathan Coe 1201736fef97SJonathan Coe TEST_F(FormatTestCSharp, CSharpArraySubscripts) { 1202736fef97SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1203736fef97SJonathan Coe 1204736fef97SJonathan Coe // Do not format array subscript operators as attributes. 1205b28ed9ceSJonathan Coe verifyFormat(R"(// 1206b28ed9ceSJonathan Coe if (someThings[index].Contains(myThing)) { 1207b28ed9ceSJonathan Coe })", 1208b28ed9ceSJonathan Coe Style); 1209b28ed9ceSJonathan Coe 1210b28ed9ceSJonathan Coe verifyFormat(R"(// 1211b28ed9ceSJonathan Coe if (someThings[i][j][k].Contains(myThing)) { 1212b28ed9ceSJonathan Coe })", 1213b28ed9ceSJonathan Coe Style); 1214736fef97SJonathan Coe } 1215736fef97SJonathan Coe 1216dcbcec48SJonathan Coe TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) { 1217dcbcec48SJonathan Coe FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1218dcbcec48SJonathan Coe 121900dc97f1Smydeveloperday EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord); 122000dc97f1Smydeveloperday 122100dc97f1Smydeveloperday verifyFormat("class ItemFactory<T>\n" 122200dc97f1Smydeveloperday " where T : new() {\n" 122300dc97f1Smydeveloperday "}", 1224ece7e95fSmydeveloperday Style); 1225dcbcec48SJonathan Coe 122600dc97f1Smydeveloperday verifyFormat("class Dictionary<TKey, TVal>\n" 122700dc97f1Smydeveloperday " where TKey : IComparable<TKey>\n" 122800dc97f1Smydeveloperday " where TVal : IMyInterface {\n" 122900dc97f1Smydeveloperday " public void MyMethod<T>(T t)\n" 123000dc97f1Smydeveloperday " where T : IMyInterface {\n" 123100dc97f1Smydeveloperday " doThing();\n" 123200dc97f1Smydeveloperday " }\n" 123300dc97f1Smydeveloperday "}", 1234dcbcec48SJonathan Coe Style); 123578e2a3c6SJonathan Coe 123600dc97f1Smydeveloperday verifyFormat("class ItemFactory<T>\n" 123700dc97f1Smydeveloperday " where T : new(), IAnInterface<T>, IAnotherInterface<T>, " 123800dc97f1Smydeveloperday "IAnotherInterfaceStill<T> {\n" 123900dc97f1Smydeveloperday "}", 1240d1b412aeSJonathan Coe Style); 1241d1b412aeSJonathan Coe 1242d1b412aeSJonathan Coe Style.ColumnLimit = 50; // Force lines to be wrapped. 1243d1b412aeSJonathan Coe verifyFormat(R"(// 1244d1b412aeSJonathan Coe class ItemFactory<T, U> 1245d1b412aeSJonathan Coe where T : new(), 1246d1b412aeSJonathan Coe IAnInterface<T>, 1247d1b412aeSJonathan Coe IAnotherInterface<T, U>, 124800dc97f1Smydeveloperday IAnotherInterfaceStill<T, U> { 124900dc97f1Smydeveloperday })", 125078e2a3c6SJonathan Coe Style); 12510574030cSKrasimir Georgiev 12520574030cSKrasimir Georgiev // In other languages `where` can be used as a normal identifier. 12530574030cSKrasimir Georgiev // This example is in C++! 12540574030cSKrasimir Georgiev verifyFormat(R"(// 12550574030cSKrasimir Georgiev class A { 12560574030cSKrasimir Georgiev int f(int where) {} 12570574030cSKrasimir Georgiev };)", 12580574030cSKrasimir Georgiev getGoogleStyle(FormatStyle::LK_Cpp)); 1259dcbcec48SJonathan Coe } 1260dcbcec48SJonathan Coe 1261ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterEnum) { 1262ed367b9dSmydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1263ed367b9dSmydeveloperday Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1264ed367b9dSmydeveloperday Style.BraceWrapping.AfterEnum = false; 1265ed367b9dSmydeveloperday Style.AllowShortEnumsOnASingleLine = false; 1266ed367b9dSmydeveloperday 1267ed367b9dSmydeveloperday verifyFormat("enum MyEnum {\n" 1268ed367b9dSmydeveloperday " Foo,\n" 1269ed367b9dSmydeveloperday " Bar,\n" 1270ed367b9dSmydeveloperday "}", 1271ed367b9dSmydeveloperday Style); 1272ed367b9dSmydeveloperday verifyFormat("internal enum MyEnum {\n" 1273ed367b9dSmydeveloperday " Foo,\n" 1274ed367b9dSmydeveloperday " Bar,\n" 1275ed367b9dSmydeveloperday "}", 1276ed367b9dSmydeveloperday Style); 1277ed367b9dSmydeveloperday verifyFormat("public enum MyEnum {\n" 1278ed367b9dSmydeveloperday " Foo,\n" 1279ed367b9dSmydeveloperday " Bar,\n" 1280ed367b9dSmydeveloperday "}", 1281ed367b9dSmydeveloperday Style); 1282ed367b9dSmydeveloperday verifyFormat("protected enum MyEnum {\n" 1283ed367b9dSmydeveloperday " Foo,\n" 1284ed367b9dSmydeveloperday " Bar,\n" 1285ed367b9dSmydeveloperday "}", 1286ed367b9dSmydeveloperday Style); 1287ed367b9dSmydeveloperday verifyFormat("private enum MyEnum {\n" 1288ed367b9dSmydeveloperday " Foo,\n" 1289ed367b9dSmydeveloperday " Bar,\n" 1290ed367b9dSmydeveloperday "}", 1291ed367b9dSmydeveloperday Style); 1292ed367b9dSmydeveloperday 1293ed367b9dSmydeveloperday Style.BraceWrapping.AfterEnum = true; 1294ed367b9dSmydeveloperday Style.AllowShortEnumsOnASingleLine = false; 1295ed367b9dSmydeveloperday 1296ed367b9dSmydeveloperday verifyFormat("enum MyEnum\n" 1297ed367b9dSmydeveloperday "{\n" 1298ed367b9dSmydeveloperday " Foo,\n" 1299ed367b9dSmydeveloperday " Bar,\n" 1300ed367b9dSmydeveloperday "}", 1301ed367b9dSmydeveloperday Style); 1302ed367b9dSmydeveloperday verifyFormat("internal enum MyEnum\n" 1303ed367b9dSmydeveloperday "{\n" 1304ed367b9dSmydeveloperday " Foo,\n" 1305ed367b9dSmydeveloperday " Bar,\n" 1306ed367b9dSmydeveloperday "}", 1307ed367b9dSmydeveloperday Style); 1308ed367b9dSmydeveloperday verifyFormat("public enum MyEnum\n" 1309ed367b9dSmydeveloperday "{\n" 1310ed367b9dSmydeveloperday " Foo,\n" 1311ed367b9dSmydeveloperday " Bar,\n" 1312ed367b9dSmydeveloperday "}", 1313ed367b9dSmydeveloperday Style); 1314ed367b9dSmydeveloperday verifyFormat("protected enum MyEnum\n" 1315ed367b9dSmydeveloperday "{\n" 1316ed367b9dSmydeveloperday " Foo,\n" 1317ed367b9dSmydeveloperday " Bar,\n" 1318ed367b9dSmydeveloperday "}", 1319ed367b9dSmydeveloperday Style); 1320ed367b9dSmydeveloperday verifyFormat("private enum MyEnum\n" 1321ed367b9dSmydeveloperday "{\n" 1322ed367b9dSmydeveloperday " Foo,\n" 1323ed367b9dSmydeveloperday " Bar,\n" 1324ed367b9dSmydeveloperday "}", 1325ed367b9dSmydeveloperday Style); 1326ed367b9dSmydeveloperday verifyFormat("/* Foo */ private enum MyEnum\n" 1327ed367b9dSmydeveloperday "{\n" 1328ed367b9dSmydeveloperday " Foo,\n" 1329ed367b9dSmydeveloperday " Bar,\n" 1330ed367b9dSmydeveloperday "}", 1331ed367b9dSmydeveloperday Style); 1332ed367b9dSmydeveloperday verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n" 1333ed367b9dSmydeveloperday "{\n" 1334ed367b9dSmydeveloperday " Foo,\n" 1335ed367b9dSmydeveloperday " Bar,\n" 1336ed367b9dSmydeveloperday "}", 1337ed367b9dSmydeveloperday Style); 1338ed367b9dSmydeveloperday } 1339ed367b9dSmydeveloperday 1340ed367b9dSmydeveloperday TEST_F(FormatTestCSharp, CSharpAfterClass) { 1341ed367b9dSmydeveloperday FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); 1342ed367b9dSmydeveloperday Style.BreakBeforeBraces = FormatStyle::BS_Custom; 1343ed367b9dSmydeveloperday Style.BraceWrapping.AfterClass = false; 1344ed367b9dSmydeveloperday 1345ed367b9dSmydeveloperday verifyFormat("class MyClass {\n" 1346ed367b9dSmydeveloperday " int a;\n" 1347ed367b9dSmydeveloperday " int b;\n" 1348ed367b9dSmydeveloperday "}", 1349ed367b9dSmydeveloperday Style); 1350ed367b9dSmydeveloperday verifyFormat("internal class MyClass {\n" 1351ed367b9dSmydeveloperday " int a;\n" 1352ed367b9dSmydeveloperday " int b;\n" 1353ed367b9dSmydeveloperday "}", 1354ed367b9dSmydeveloperday Style); 1355ed367b9dSmydeveloperday verifyFormat("public class MyClass {\n" 1356ed367b9dSmydeveloperday " int a;\n" 1357ed367b9dSmydeveloperday " int b;\n" 1358ed367b9dSmydeveloperday "}", 1359ed367b9dSmydeveloperday Style); 1360ed367b9dSmydeveloperday verifyFormat("protected class MyClass {\n" 1361ed367b9dSmydeveloperday " int a;\n" 1362ed367b9dSmydeveloperday " int b;\n" 1363ed367b9dSmydeveloperday "}", 1364ed367b9dSmydeveloperday Style); 1365ed367b9dSmydeveloperday verifyFormat("private class MyClass {\n" 1366ed367b9dSmydeveloperday " int a;\n" 1367ed367b9dSmydeveloperday " int b;\n" 1368ed367b9dSmydeveloperday "}", 1369ed367b9dSmydeveloperday Style); 1370ed367b9dSmydeveloperday 1371ed367b9dSmydeveloperday verifyFormat("interface Interface {\n" 1372ed367b9dSmydeveloperday " int a;\n" 1373ed367b9dSmydeveloperday " int b;\n" 1374ed367b9dSmydeveloperday "}", 1375ed367b9dSmydeveloperday Style); 1376ed367b9dSmydeveloperday verifyFormat("internal interface Interface {\n" 1377ed367b9dSmydeveloperday " int a;\n" 1378ed367b9dSmydeveloperday " int b;\n" 1379ed367b9dSmydeveloperday "}", 1380ed367b9dSmydeveloperday Style); 1381ed367b9dSmydeveloperday verifyFormat("public interface Interface {\n" 1382ed367b9dSmydeveloperday " int a;\n" 1383ed367b9dSmydeveloperday " int b;\n" 1384ed367b9dSmydeveloperday "}", 1385ed367b9dSmydeveloperday Style); 1386ed367b9dSmydeveloperday verifyFormat("protected interface Interface {\n" 1387ed367b9dSmydeveloperday " int a;\n" 1388ed367b9dSmydeveloperday " int b;\n" 1389ed367b9dSmydeveloperday "}", 1390ed367b9dSmydeveloperday Style); 1391ed367b9dSmydeveloperday verifyFormat("private interface Interface {\n" 1392ed367b9dSmydeveloperday " int a;\n" 1393ed367b9dSmydeveloperday " int b;\n" 1394ed367b9dSmydeveloperday "}", 1395ed367b9dSmydeveloperday Style); 1396ed367b9dSmydeveloperday 1397ed367b9dSmydeveloperday Style.BraceWrapping.AfterClass = true; 1398ed367b9dSmydeveloperday 1399ed367b9dSmydeveloperday verifyFormat("class MyClass\n" 1400ed367b9dSmydeveloperday "{\n" 1401ed367b9dSmydeveloperday " int a;\n" 1402ed367b9dSmydeveloperday " int b;\n" 1403ed367b9dSmydeveloperday "}", 1404ed367b9dSmydeveloperday Style); 1405ed367b9dSmydeveloperday verifyFormat("internal class MyClass\n" 1406ed367b9dSmydeveloperday "{\n" 1407ed367b9dSmydeveloperday " int a;\n" 1408ed367b9dSmydeveloperday " int b;\n" 1409ed367b9dSmydeveloperday "}", 1410ed367b9dSmydeveloperday Style); 1411ed367b9dSmydeveloperday verifyFormat("public class MyClass\n" 1412ed367b9dSmydeveloperday "{\n" 1413ed367b9dSmydeveloperday " int a;\n" 1414ed367b9dSmydeveloperday " int b;\n" 1415ed367b9dSmydeveloperday "}", 1416ed367b9dSmydeveloperday Style); 1417ed367b9dSmydeveloperday verifyFormat("protected class MyClass\n" 1418ed367b9dSmydeveloperday "{\n" 1419ed367b9dSmydeveloperday " int a;\n" 1420ed367b9dSmydeveloperday " int b;\n" 1421ed367b9dSmydeveloperday "}", 1422ed367b9dSmydeveloperday Style); 1423ed367b9dSmydeveloperday verifyFormat("private class MyClass\n" 1424ed367b9dSmydeveloperday "{\n" 1425ed367b9dSmydeveloperday " int a;\n" 1426ed367b9dSmydeveloperday " int b;\n" 1427ed367b9dSmydeveloperday "}", 1428ed367b9dSmydeveloperday Style); 1429ed367b9dSmydeveloperday 1430ed367b9dSmydeveloperday verifyFormat("interface MyInterface\n" 1431ed367b9dSmydeveloperday "{\n" 1432ed367b9dSmydeveloperday " int a;\n" 1433ed367b9dSmydeveloperday " int b;\n" 1434ed367b9dSmydeveloperday "}", 1435ed367b9dSmydeveloperday Style); 1436ed367b9dSmydeveloperday verifyFormat("internal interface MyInterface\n" 1437ed367b9dSmydeveloperday "{\n" 1438ed367b9dSmydeveloperday " int a;\n" 1439ed367b9dSmydeveloperday " int b;\n" 1440ed367b9dSmydeveloperday "}", 1441ed367b9dSmydeveloperday Style); 1442ed367b9dSmydeveloperday verifyFormat("public interface MyInterface\n" 1443ed367b9dSmydeveloperday "{\n" 1444ed367b9dSmydeveloperday " int a;\n" 1445ed367b9dSmydeveloperday " int b;\n" 1446ed367b9dSmydeveloperday "}", 1447ed367b9dSmydeveloperday Style); 1448ed367b9dSmydeveloperday verifyFormat("protected interface MyInterface\n" 1449ed367b9dSmydeveloperday "{\n" 1450ed367b9dSmydeveloperday " int a;\n" 1451ed367b9dSmydeveloperday " int b;\n" 1452ed367b9dSmydeveloperday "}", 1453ed367b9dSmydeveloperday Style); 1454ed367b9dSmydeveloperday verifyFormat("private interface MyInterface\n" 1455ed367b9dSmydeveloperday "{\n" 1456ed367b9dSmydeveloperday " int a;\n" 1457ed367b9dSmydeveloperday " int b;\n" 1458ed367b9dSmydeveloperday "}", 1459ed367b9dSmydeveloperday Style); 1460ed367b9dSmydeveloperday verifyFormat("/* Foo */ private interface MyInterface\n" 1461ed367b9dSmydeveloperday "{\n" 1462ed367b9dSmydeveloperday " int a;\n" 1463ed367b9dSmydeveloperday " int b;\n" 1464ed367b9dSmydeveloperday "}", 1465ed367b9dSmydeveloperday Style); 1466ed367b9dSmydeveloperday verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n" 1467ed367b9dSmydeveloperday "{\n" 1468ed367b9dSmydeveloperday " int a;\n" 1469ed367b9dSmydeveloperday " int b;\n" 1470ed367b9dSmydeveloperday "}", 1471ed367b9dSmydeveloperday Style); 1472ed367b9dSmydeveloperday } 1473ed367b9dSmydeveloperday 14746e58d14eSmydeveloperday TEST_F(FormatTestCSharp, NamespaceIndentation) { 14756e58d14eSmydeveloperday FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 14766e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_None; 14776e58d14eSmydeveloperday 14786e58d14eSmydeveloperday verifyFormat("namespace A\n" 14796e58d14eSmydeveloperday "{\n" 14806e58d14eSmydeveloperday "public interface Name1\n" 14816e58d14eSmydeveloperday "{\n" 14826e58d14eSmydeveloperday "}\n" 14836e58d14eSmydeveloperday "}\n", 14846e58d14eSmydeveloperday Style); 14856e58d14eSmydeveloperday 14866e58d14eSmydeveloperday verifyFormat("namespace A.B\n" 14876e58d14eSmydeveloperday "{\n" 14886e58d14eSmydeveloperday "public interface Name1\n" 14896e58d14eSmydeveloperday "{\n" 14906e58d14eSmydeveloperday "}\n" 14916e58d14eSmydeveloperday "}\n", 14926e58d14eSmydeveloperday Style); 14936e58d14eSmydeveloperday 14946e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_Inner; 14956e58d14eSmydeveloperday 14966e58d14eSmydeveloperday verifyFormat("namespace A\n" 14976e58d14eSmydeveloperday "{\n" 14986e58d14eSmydeveloperday "namespace B\n" 14996e58d14eSmydeveloperday "{\n" 15006e58d14eSmydeveloperday " public interface Name1\n" 15016e58d14eSmydeveloperday " {\n" 15026e58d14eSmydeveloperday " }\n" 15036e58d14eSmydeveloperday "}\n" 15046e58d14eSmydeveloperday "}\n", 15056e58d14eSmydeveloperday Style); 15066e58d14eSmydeveloperday 15076e58d14eSmydeveloperday Style.NamespaceIndentation = FormatStyle::NI_All; 15086e58d14eSmydeveloperday 15096e58d14eSmydeveloperday verifyFormat("namespace A.B\n" 15106e58d14eSmydeveloperday "{\n" 15116e58d14eSmydeveloperday " public interface Name1\n" 15126e58d14eSmydeveloperday " {\n" 15136e58d14eSmydeveloperday " }\n" 15146e58d14eSmydeveloperday "}\n", 15156e58d14eSmydeveloperday Style); 15166e58d14eSmydeveloperday 15176e58d14eSmydeveloperday verifyFormat("namespace A\n" 15186e58d14eSmydeveloperday "{\n" 15196e58d14eSmydeveloperday " namespace B\n" 15206e58d14eSmydeveloperday " {\n" 15216e58d14eSmydeveloperday " public interface Name1\n" 15226e58d14eSmydeveloperday " {\n" 15236e58d14eSmydeveloperday " }\n" 15246e58d14eSmydeveloperday " }\n" 15256e58d14eSmydeveloperday "}\n", 15266e58d14eSmydeveloperday Style); 15276e58d14eSmydeveloperday } 15286e58d14eSmydeveloperday 1529ebed0ca7Smydeveloperday TEST_F(FormatTestCSharp, SwitchExpression) { 1530ebed0ca7Smydeveloperday FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp); 1531ebed0ca7Smydeveloperday verifyFormat("int x = a switch {\n" 1532ebed0ca7Smydeveloperday " 1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n" 1533ebed0ca7Smydeveloperday " 2 => 1,\n" 1534ebed0ca7Smydeveloperday " _ => 2\n" 1535ebed0ca7Smydeveloperday "};\n", 1536ebed0ca7Smydeveloperday Style); 1537ebed0ca7Smydeveloperday } 1538ebed0ca7Smydeveloperday 1539a94aab12Smydeveloperday TEST_F(FormatTestCSharp, EmptyShortBlock) { 1540a94aab12Smydeveloperday auto Style = getLLVMStyle(); 1541a94aab12Smydeveloperday Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty; 1542a94aab12Smydeveloperday 1543a94aab12Smydeveloperday verifyFormat("try {\n" 1544a94aab12Smydeveloperday " doA();\n" 1545a94aab12Smydeveloperday "} catch (Exception e) {\n" 1546a94aab12Smydeveloperday " e.printStackTrace();\n" 1547a94aab12Smydeveloperday "}\n", 1548a94aab12Smydeveloperday Style); 1549a94aab12Smydeveloperday 1550a94aab12Smydeveloperday verifyFormat("try {\n" 1551a94aab12Smydeveloperday " doA();\n" 1552a94aab12Smydeveloperday "} catch (Exception e) {}\n", 1553a94aab12Smydeveloperday Style); 1554a94aab12Smydeveloperday } 1555a94aab12Smydeveloperday 15567af11989SMarek Kurdej TEST_F(FormatTestCSharp, ShortFunctions) { 15577af11989SMarek Kurdej FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp); 15587af11989SMarek Kurdej Style.NamespaceIndentation = FormatStyle::NI_All; 15597af11989SMarek Kurdej Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline; 15607af11989SMarek Kurdej verifyFormat("interface Interface {\n" 15617af11989SMarek Kurdej " void f() { return; }\n" 15627af11989SMarek Kurdej "};", 15637af11989SMarek Kurdej Style); 15647af11989SMarek Kurdej verifyFormat("public interface Interface {\n" 15657af11989SMarek Kurdej " void f() { return; }\n" 15667af11989SMarek Kurdej "};", 15677af11989SMarek Kurdej Style); 15687af11989SMarek Kurdej verifyFormat("namespace {\n" 15697af11989SMarek Kurdej " void f() {\n" 15707af11989SMarek Kurdej " return;\n" 15717af11989SMarek Kurdej " }\n" 15727af11989SMarek Kurdej "};", 15737af11989SMarek Kurdej Style); 15747af11989SMarek Kurdej // "union" is not a keyword in C#. 15757af11989SMarek Kurdej verifyFormat("namespace union {\n" 15767af11989SMarek Kurdej " void f() {\n" 15777af11989SMarek Kurdej " return;\n" 15787af11989SMarek Kurdej " }\n" 15797af11989SMarek Kurdej "};", 15807af11989SMarek Kurdej Style); 15817af11989SMarek Kurdej } 15827af11989SMarek Kurdej 1583cbb726d0SPaul Hoad } // namespace format 1584cbb726d0SPaul Hoad } // end namespace clang 1585