[AMDGPU][AsmParser][NFC] Get rid of custom default operand handlers.
[llvm-project.git] / clang / unittests / Format / FormatTestCSharp.cpp
blob9f912624d16582dc311063033e3399d620f93de3
1 //===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "FormatTestUtils.h"
10 #include "clang/Format/Format.h"
11 #include "llvm/Support/Debug.h"
12 #include "gtest/gtest.h"
14 #define DEBUG_TYPE "format-test"
16 namespace clang {
17 namespace format {
19 class FormatTestCSharp : public ::testing::Test {
20 protected:
21 static std::string format(llvm::StringRef Code, unsigned Offset,
22 unsigned Length, const FormatStyle &Style) {
23 LLVM_DEBUG(llvm::errs() << "---\n");
24 LLVM_DEBUG(llvm::errs() << Code << "\n\n");
25 std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
26 tooling::Replacements Replaces = reformat(Style, Code, Ranges);
27 auto Result = applyAllReplacements(Code, Replaces);
28 EXPECT_TRUE(static_cast<bool>(Result));
29 LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
30 return *Result;
33 static std::string
34 format(llvm::StringRef Code,
35 const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
36 return format(Code, 0, Code.size(), Style);
39 static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
40 FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
41 Style.ColumnLimit = ColumnLimit;
42 return Style;
45 static void verifyFormat(
46 llvm::StringRef Code,
47 const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
48 EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
49 EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
53 TEST_F(FormatTestCSharp, CSharpClass) {
54 verifyFormat("public class SomeClass\n"
55 "{\n"
56 " void f()\n"
57 " {\n"
58 " }\n"
59 " int g()\n"
60 " {\n"
61 " return 0;\n"
62 " }\n"
63 " void h()\n"
64 " {\n"
65 " while (true)\n"
66 " f();\n"
67 " for (;;)\n"
68 " f();\n"
69 " if (true)\n"
70 " f();\n"
71 " }\n"
72 "}");
74 // Ensure that small and empty classes are handled correctly with condensed
75 // (Google C++-like) brace-breaking style.
76 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
77 Style.BreakBeforeBraces = FormatStyle::BS_Attach;
79 verifyFormat("public class SomeEmptyClass {}", Style);
81 verifyFormat("public class SomeTinyClass {\n"
82 " int X;\n"
83 "}",
84 Style);
85 verifyFormat("private class SomeTinyClass {\n"
86 " int X;\n"
87 "}",
88 Style);
89 verifyFormat("protected class SomeTinyClass {\n"
90 " int X;\n"
91 "}",
92 Style);
93 verifyFormat("internal class SomeTinyClass {\n"
94 " int X;\n"
95 "}",
96 Style);
99 TEST_F(FormatTestCSharp, AccessModifiers) {
100 verifyFormat("public String toString()\n"
101 "{\n"
102 "}");
103 verifyFormat("private String toString()\n"
104 "{\n"
105 "}");
106 verifyFormat("protected String toString()\n"
107 "{\n"
108 "}");
109 verifyFormat("internal String toString()\n"
110 "{\n"
111 "}");
113 verifyFormat("public override String toString()\n"
114 "{\n"
115 "}");
116 verifyFormat("private override String toString()\n"
117 "{\n"
118 "}");
119 verifyFormat("protected override String toString()\n"
120 "{\n"
121 "}");
122 verifyFormat("internal override String toString()\n"
123 "{\n"
124 "}");
126 verifyFormat("internal static String toString()\n"
127 "{\n"
128 "}");
131 TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
132 verifyFormat("foo("
133 "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
134 "aaaaaa\");");
137 TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
138 verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
139 // @"ABC\" + ToString("B") - handle embedded \ in literal string at
140 // the end
143 * After removal of Lexer change we are currently not able
144 * To handle these cases
145 verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
146 verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
147 verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
148 verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
152 TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
153 verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
154 verifyFormat("foo($\"aaaa{A}\");");
155 verifyFormat(
156 "foo($\"aaaa{A}"
157 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
158 verifyFormat("Name = $\"{firstName} {lastName}\";");
160 // $"ABC\" + ToString("B") - handle embedded \ in literal string at
161 // the end
162 verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
163 verifyFormat("$\"{domain}\\\\{user}\"");
164 verifyFormat(
165 "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
168 TEST_F(FormatTestCSharp, CSharpFatArrows) {
169 verifyFormat("Task serverTask = Task.Run(async() => {");
170 verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
173 TEST_F(FormatTestCSharp, CSharpConditionalExpressions) {
174 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
175 // conditional expression is not seen as a NullConditional.
176 verifyFormat("var y = A < B ? -1 : 1;", Style);
179 TEST_F(FormatTestCSharp, CSharpNullConditional) {
180 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
181 Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
183 verifyFormat(
184 "public Person(string firstName, string lastName, int? age = null)");
186 verifyFormat("foo () {\n"
187 " switch (args?.Length) {}\n"
188 "}",
189 Style);
191 verifyFormat("switch (args?.Length) {}", Style);
193 verifyFormat("public static void Main(string[] args)\n"
194 "{\n"
195 " string dirPath = args?[0];\n"
196 "}");
198 Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
200 verifyFormat("switch(args?.Length) {}", Style);
203 TEST_F(FormatTestCSharp, Attributes) {
204 verifyFormat("[STAThread]\n"
205 "static void Main(string[] args)\n"
206 "{\n"
207 "}");
209 verifyFormat("[TestMethod]\n"
210 "private class Test\n"
211 "{\n"
212 "}");
214 verifyFormat("[TestMethod]\n"
215 "protected class Test\n"
216 "{\n"
217 "}");
219 verifyFormat("[TestMethod]\n"
220 "internal class Test\n"
221 "{\n"
222 "}");
224 verifyFormat("[TestMethod]\n"
225 "class Test\n"
226 "{\n"
227 "}");
229 verifyFormat("[TestMethod]\n"
230 "[DeploymentItem(\"Test.txt\")]\n"
231 "public class Test\n"
232 "{\n"
233 "}");
235 verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
236 "[System.Runtime.InteropServices.ComVisible(true)]\n"
237 "public sealed class STAThreadAttribute : Attribute\n"
238 "{\n"
239 "}");
241 verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
242 "provided port\")]\n"
243 "class Test\n"
244 "{\n"
245 "}");
247 verifyFormat("[TestMethod]\n"
248 "public string Host { set; get; }");
250 // Adjacent properties should not cause line wrapping issues
251 verifyFormat("[JsonProperty(\"foo\")]\n"
252 "public string Foo { set; get; }\n"
253 "[JsonProperty(\"bar\")]\n"
254 "public string Bar { set; get; }\n"
255 "[JsonProperty(\"bar\")]\n"
256 "protected string Bar { set; get; }\n"
257 "[JsonProperty(\"bar\")]\n"
258 "internal string Bar { set; get; }");
260 // Multiple attributes should always be split (not just the first ones)
261 verifyFormat("[XmlIgnore]\n"
262 "[JsonProperty(\"foo\")]\n"
263 "public string Foo { set; get; }");
265 verifyFormat("[XmlIgnore]\n"
266 "[JsonProperty(\"foo\")]\n"
267 "public string Foo { set; get; }\n"
268 "[XmlIgnore]\n"
269 "[JsonProperty(\"bar\")]\n"
270 "public string Bar { set; get; }");
272 verifyFormat("[XmlIgnore]\n"
273 "[ScriptIgnore]\n"
274 "[JsonProperty(\"foo\")]\n"
275 "public string Foo { set; get; }\n"
276 "[XmlIgnore]\n"
277 "[ScriptIgnore]\n"
278 "[JsonProperty(\"bar\")]\n"
279 "public string Bar { set; get; }");
281 verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
282 "listening on provided host\")]\n"
283 "public string Host { set; get; }");
285 verifyFormat(
286 "[DllImport(\"Hello\", EntryPoint = \"hello_world\")]\n"
287 "// The const char* returned by hello_world must not be deleted.\n"
288 "private static extern IntPtr HelloFromCpp();)");
290 // Class attributes go on their own line and do not affect layout of
291 // interfaces. Line wrapping decisions previously caused each interface to be
292 // on its own line.
293 verifyFormat("[SomeAttribute]\n"
294 "[SomeOtherAttribute]\n"
295 "public class A : IShape, IAnimal, IVehicle\n"
296 "{\n"
297 " int X;\n"
298 "}");
300 // Attributes in a method declaration do not cause line wrapping.
301 verifyFormat("void MethodA([In][Out] ref double x)\n"
302 "{\n"
303 "}");
305 verifyFormat("void MethodA([In, Out] ref double x)\n"
306 "{\n"
307 "}");
309 verifyFormat("void MethodA([In, Out] double[] x)\n"
310 "{\n"
311 "}");
313 verifyFormat("void MethodA([In] double[] x)\n"
314 "{\n"
315 "}");
317 verifyFormat("void MethodA(int[] x)\n"
318 "{\n"
319 "}");
320 verifyFormat("void MethodA(int[][] x)\n"
321 "{\n"
322 "}");
323 verifyFormat("void MethodA([] x)\n"
324 "{\n"
325 "}");
327 verifyFormat("public void Log([CallerLineNumber] int line = -1, "
328 "[CallerFilePath] string path = null,\n"
329 " [CallerMemberName] string name = null)\n"
330 "{\n"
331 "}");
333 // [] in an attribute do not cause premature line wrapping or indenting.
334 verifyFormat(R"(//
335 public class A
337 [SomeAttribute(new[] { RED, GREEN, BLUE }, -1.0f, 1.0f)]
338 [DoNotSerialize]
339 public Data MemberVariable;
340 })");
342 // Unwrappable lines go on a line of their own.
343 // 'target:' is not treated as a label.
344 // Modify Style to enforce a column limit.
345 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
346 Style.ColumnLimit = 10;
347 verifyFormat(R"([assembly:InternalsVisibleTo(
348 "SomeAssembly, PublicKey=SomePublicKeyThatExceedsTheColumnLimit")])",
349 Style);
352 TEST_F(FormatTestCSharp, CSharpUsing) {
353 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
354 Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
355 verifyFormat("public void foo () {\n"
356 " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
357 " using () {}\n"
358 "}",
359 Style);
361 // Ensure clang-format affects top-level snippets correctly.
362 verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
363 Style);
365 Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
366 verifyFormat("public void foo() {\n"
367 " using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"
368 " using() {}\n"
369 "}",
370 Style);
372 // Ensure clang-format affects top-level snippets correctly.
373 verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",
374 Style);
376 Style.SpaceBeforeParens = FormatStyle::SBPO_ControlStatements;
377 verifyFormat("public void foo() {\n"
378 " using (StreamWriter sw = new StreamWriter(filenameA)) {}\n"
379 " using () {}\n"
380 "}",
381 Style);
383 // Ensure clang-format affects top-level snippets correctly.
384 verifyFormat("using (StreamWriter sw = new StreamWriter(filenameB)) {}",
385 Style);
387 Style.SpaceBeforeParens = FormatStyle::SBPO_NonEmptyParentheses;
388 verifyFormat("public void foo() {\n"
389 " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
390 " using() {}\n"
391 "}",
392 Style);
394 // Ensure clang-format affects top-level snippets correctly.
395 verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
396 Style);
399 TEST_F(FormatTestCSharp, CSharpRegions) {
400 verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
401 "aaaaaaaaaaaaaaa long region");
404 TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
405 // AfterEnum is true by default.
406 verifyFormat("public enum var\n"
407 "{\n"
408 " none,\n"
409 " @string,\n"
410 " bool,\n"
411 " @enum\n"
412 "}");
415 TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
416 verifyFormat("var test = ABC ?? DEF");
417 verifyFormat("string myname = name ?? \"ABC\";");
418 verifyFormat("return _name ?? \"DEF\";");
421 TEST_F(FormatTestCSharp, CSharpNullCoalescingAssignment) {
422 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
423 Style.SpaceBeforeAssignmentOperators = true;
425 verifyFormat(R"(test ??= ABC;)", Style);
426 verifyFormat(R"(test ??= true;)", Style);
428 Style.SpaceBeforeAssignmentOperators = false;
430 verifyFormat(R"(test??= ABC;)", Style);
431 verifyFormat(R"(test??= true;)", Style);
434 TEST_F(FormatTestCSharp, CSharpNullForgiving) {
435 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
437 verifyFormat("var test = null!;", Style);
438 verifyFormat("string test = someFunctionCall()! + \"ABC\"!", Style);
439 verifyFormat("int test = (1! + 2 + bar! + foo())!", Style);
440 verifyFormat(R"(test ??= !foo!;)", Style);
441 verifyFormat("test = !bar! ?? !foo!;", Style);
442 verifyFormat("bool test = !(!true && !true! || !null && !null! || !false && "
443 "!false! && !bar()! + (!foo()))!",
444 Style);
446 // Check that line break keeps identifier with the bang.
447 Style.ColumnLimit = 14;
449 verifyFormat("var test =\n"
450 " foo!;",
451 Style);
454 TEST_F(FormatTestCSharp, AttributesIndentation) {
455 FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
456 Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
458 verifyFormat("[STAThread]\n"
459 "static void Main(string[] args)\n"
460 "{\n"
461 "}",
462 Style);
464 verifyFormat("[STAThread]\n"
465 "void "
466 "veryLooooooooooooooongFunctionName(string[] args)\n"
467 "{\n"
468 "}",
469 Style);
471 verifyFormat("[STAThread]\n"
472 "veryLoooooooooooooooooooongReturnType "
473 "veryLooooooooooooooongFunctionName(string[] args)\n"
474 "{\n"
475 "}",
476 Style);
478 verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"
479 "public override X Y()\n"
480 "{\n"
481 "}\n",
482 Style);
484 verifyFormat("[SuppressMessage]\n"
485 "public X Y()\n"
486 "{\n"
487 "}\n",
488 Style);
490 verifyFormat("[SuppressMessage]\n"
491 "public override X Y()\n"
492 "{\n"
493 "}\n",
494 Style);
496 verifyFormat("public A(B b) : base(b)\n"
497 "{\n"
498 " [SuppressMessage]\n"
499 " public override X Y()\n"
500 " {\n"
501 " }\n"
502 "}\n",
503 Style);
505 verifyFormat("public A : Base\n"
506 "{\n"
507 "}\n"
508 "[Test]\n"
509 "public Foo()\n"
510 "{\n"
511 "}\n",
512 Style);
514 verifyFormat("namespace\n"
515 "{\n"
516 "public A : Base\n"
517 "{\n"
518 "}\n"
519 "[Test]\n"
520 "public Foo()\n"
521 "{\n"
522 "}\n"
523 "}\n",
524 Style);
527 TEST_F(FormatTestCSharp, CSharpSpaceBefore) {
528 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
529 Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
531 verifyFormat("List<string> list;", Style);
532 verifyFormat("Dictionary<string, string> dict;", Style);
534 verifyFormat("for (int i = 0; i < size (); i++) {\n"
535 "}",
536 Style);
537 verifyFormat("foreach (var x in y) {\n"
538 "}",
539 Style);
540 verifyFormat("switch (x) {}", Style);
541 verifyFormat("do {\n"
542 "} while (x);",
543 Style);
545 Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
547 verifyFormat("List<string> list;", Style);
548 verifyFormat("Dictionary<string, string> dict;", Style);
550 verifyFormat("for(int i = 0; i < size(); i++) {\n"
551 "}",
552 Style);
553 verifyFormat("foreach(var x in y) {\n"
554 "}",
555 Style);
556 verifyFormat("switch(x) {}", Style);
557 verifyFormat("do {\n"
558 "} while(x);",
559 Style);
562 TEST_F(FormatTestCSharp, CSharpSpaceAfterCStyleCast) {
563 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
565 verifyFormat("(int)x / y;", Style);
567 Style.SpaceAfterCStyleCast = true;
568 verifyFormat("(int) x / y;", Style);
571 TEST_F(FormatTestCSharp, CSharpEscapedQuotesInVerbatimStrings) {
572 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
574 verifyFormat(R"(string str = @"""";)", Style);
575 verifyFormat(R"(string str = @"""Hello world""";)", Style);
576 verifyFormat(R"(string str = $@"""Hello {friend}""";)", Style);
577 verifyFormat(R"(return $@"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
578 verifyFormat(R"(return @$"Foo ""/foo?f={Request.Query["f"]}""";)", Style);
579 verifyFormat(R"(return @$"path\to\{specifiedFile}")", Style);
582 TEST_F(FormatTestCSharp, CSharpQuotesInInterpolatedStrings) {
583 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
585 verifyFormat(R"(string str1 = $"{null ?? "null"}";)", Style);
586 verifyFormat(R"(string str2 = $"{{{braceCount} braces";)", Style);
587 verifyFormat(R"(string str3 = $"{braceCount}}} braces";)", Style);
590 TEST_F(FormatTestCSharp, CSharpNewlinesInVerbatimStrings) {
591 // Use MS style as Google Style inserts a line break before multiline strings.
593 // verifyFormat does not understand multiline C# string-literals
594 // so check the format explicitly.
596 FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
598 std::string Code = R"(string s1 = $@"some code:
599 class {className} {{
600 {className}() {{}}
601 }}";)";
603 EXPECT_EQ(Code, format(Code, Style));
605 // Multiline string in the middle of a function call.
606 Code = R"(
607 var x = foo(className, $@"some code:
608 class {className} {{
609 {className}() {{}}
610 }}",
611 y);)"; // y aligned with `className` arg.
613 EXPECT_EQ(Code, format(Code, Style));
615 // Interpolated string with embedded multiline string.
616 Code = R"(Console.WriteLine($"{string.Join(@",
617 ", values)}");)";
619 EXPECT_EQ(Code, format(Code, Style));
622 TEST_F(FormatTestCSharp, CSharpNewOperator) {
623 FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
625 verifyFormat("public void F() {\n"
626 " var v = new C(() => { var t = 5; });\n"
627 "}",
628 Style);
629 verifyFormat("public void F() {\n"
630 " var v = new C(() => {\n"
631 " try {\n"
632 " } catch {\n"
633 " var t = 5;\n"
634 " }\n"
635 " });\n"
636 "}",
637 Style);
640 TEST_F(FormatTestCSharp, CSharpLambdas) {
641 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
642 FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
644 verifyFormat(R"(//
645 class MyClass {
646 Action<string> greet = name => {
647 string greeting = $"Hello {name}!";
648 Console.WriteLine(greeting);
650 })",
651 GoogleStyle);
653 // Microsoft Style:
654 // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions#statement-lambdas
655 verifyFormat(R"(//
656 class MyClass
658 Action<string> greet = name =>
660 string greeting = $"Hello {name}!";
661 Console.WriteLine(greeting);
663 })",
664 MicrosoftStyle);
666 verifyFormat("void bar()\n"
667 "{\n"
668 " Function(Val, (Action)(() =>\n"
669 " {\n"
670 " lock (mylock)\n"
671 " {\n"
672 " if (true)\n"
673 " {\n"
674 " A.Remove(item);\n"
675 " }\n"
676 " }\n"
677 " }));\n"
678 "}",
679 MicrosoftStyle);
681 verifyFormat("void baz()\n"
682 "{\n"
683 " Function(Val, (Action)(() =>\n"
684 " {\n"
685 " using (var a = new Lock())\n"
686 " {\n"
687 " if (true)\n"
688 " {\n"
689 " A.Remove(item);\n"
690 " }\n"
691 " }\n"
692 " }));\n"
693 "}",
694 MicrosoftStyle);
696 verifyFormat("void baz()\n"
697 "{\n"
698 " Function(Val, (Action)(() =>\n"
699 " {\n"
700 " if (true)\n"
701 " {\n"
702 " A.Remove(item);\n"
703 " }\n"
704 " }));\n"
705 "}",
706 MicrosoftStyle);
708 verifyFormat("void baz()\n"
709 "{\n"
710 " Function(Val, (Action)(() =>\n"
711 " {\n"
712 " do\n"
713 " {\n"
714 " A.Remove(item);\n"
715 " } while (true)\n"
716 " }));\n"
717 "}",
718 MicrosoftStyle);
720 verifyFormat("void baz()\n"
721 "{\n"
722 " Function(Val, (Action)(() =>\n"
723 " { A.Remove(item); }));\n"
724 "}",
725 MicrosoftStyle);
727 verifyFormat("void bar()\n"
728 "{\n"
729 " Function(Val, (() =>\n"
730 " {\n"
731 " lock (mylock)\n"
732 " {\n"
733 " if (true)\n"
734 " {\n"
735 " A.Remove(item);\n"
736 " }\n"
737 " }\n"
738 " }));\n"
739 "}",
740 MicrosoftStyle);
741 verifyFormat("void bar()\n"
742 "{\n"
743 " Function((() =>\n"
744 " {\n"
745 " lock (mylock)\n"
746 " {\n"
747 " if (true)\n"
748 " {\n"
749 " A.Remove(item);\n"
750 " }\n"
751 " }\n"
752 " }));\n"
753 "}",
754 MicrosoftStyle);
756 MicrosoftStyle.IndentWidth = 2;
757 verifyFormat("void bar()\n"
758 "{\n"
759 " Function((() =>\n"
760 " {\n"
761 " lock (mylock)\n"
762 " {\n"
763 " if (true)\n"
764 " {\n"
765 " A.Remove(item);\n"
766 " }\n"
767 " }\n"
768 " }));\n"
769 "}",
770 MicrosoftStyle);
771 verifyFormat("void bar() {\n"
772 " Function((() => {\n"
773 " lock (mylock) {\n"
774 " if (true) {\n"
775 " A.Remove(item);\n"
776 " }\n"
777 " }\n"
778 " }));\n"
779 "}",
780 GoogleStyle);
783 TEST_F(FormatTestCSharp, CSharpLambdasDontBreakFollowingCodeAlignment) {
784 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
785 FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
787 verifyFormat(R"(//
788 public class Sample
790 public void Test()
792 while (true)
794 preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
795 CodeThatFollowsLambda();
796 IsWellAligned();
799 })",
800 MicrosoftStyle);
802 verifyFormat(R"(//
803 public class Sample {
804 public void Test() {
805 while (true) {
806 preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
807 CodeThatFollowsLambda();
808 IsWellAligned();
811 })",
812 GoogleStyle);
815 TEST_F(FormatTestCSharp, CSharpLambdasComplexLambdasDontBreakAlignment) {
816 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
817 FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
819 verifyFormat(R"(//
820 public class Test
822 private static void ComplexLambda(BuildReport protoReport)
824 allSelectedScenes =
825 veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)
826 .Select(scene => scene.path)
827 .ToArray();
828 if (allSelectedScenes.Count == 0)
830 return;
832 Functions();
833 AreWell();
834 Aligned();
835 AfterLambdaBlock();
837 })",
838 MicrosoftStyle);
840 verifyFormat(R"(//
841 public class Test {
842 private static void ComplexLambda(BuildReport protoReport) {
843 allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds
844 .Where(scene => scene.enabled)
845 .Select(scene => scene.path)
846 .ToArray();
847 if (allSelectedScenes.Count == 0) {
848 return;
850 Functions();
851 AreWell();
852 Aligned();
853 AfterLambdaBlock();
855 })",
856 GoogleStyle);
859 TEST_F(FormatTestCSharp, CSharpLambdasMulipleLambdasDontBreakAlignment) {
860 FormatStyle GoogleStyle = getGoogleStyle(FormatStyle::LK_CSharp);
861 FormatStyle MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
863 verifyFormat(R"(//
864 public class Test
866 private static void MultipleLambdas(BuildReport protoReport)
868 allSelectedScenes =
869 veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds.Where(scene => scene.enabled)
870 .Select(scene => scene.path)
871 .ToArray();
872 preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
873 if (allSelectedScenes.Count == 0)
875 return;
877 Functions();
878 AreWell();
879 Aligned();
880 AfterLambdaBlock();
882 })",
883 MicrosoftStyle);
885 verifyFormat(R"(//
886 public class Test {
887 private static void MultipleLambdas(BuildReport protoReport) {
888 allSelectedScenes = veryVeryLongCollectionNameThatPutsTheLineLenghtAboveTheThresholds
889 .Where(scene => scene.enabled)
890 .Select(scene => scene.path)
891 .ToArray();
892 preBindEnumerators.RemoveAll(enumerator => !enumerator.MoveNext());
893 if (allSelectedScenes.Count == 0) {
894 return;
896 Functions();
897 AreWell();
898 Aligned();
899 AfterLambdaBlock();
901 })",
902 GoogleStyle);
905 TEST_F(FormatTestCSharp, CSharpObjectInitializers) {
906 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
908 // Start code fragments with a comment line so that C++ raw string literals
909 // as seen are identical to expected formatted code.
911 verifyFormat(R"(//
912 Shape[] shapes = new[] {
913 new Circle {
914 Radius = 2.7281,
915 Colour = Colours.Red,
917 new Square {
918 Side = 101.1,
919 Colour = Colours.Yellow,
921 };)",
922 Style);
924 // Omitted final `,`s will change the formatting.
925 verifyFormat(R"(//
926 Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red },
927 new Square { Side = 101.1, Colour = Colours.Yellow } };)",
928 Style);
930 // Lambdas can be supplied as initialiser arguments.
931 verifyFormat(R"(//
932 private Transformer _transformer = new X.Y {
933 Filler = (Shape shape) => { return new Transform.Fill(shape, RED); },
934 Scaler = (Shape shape) => { return new Transform.Resize(shape, 0.1); },
935 };)",
936 Style);
938 // Dictionary initialisation.
939 verifyFormat(R"(//
940 var myDict = new Dictionary<string, string> {
941 ["name"] = _donald,
942 ["age"] = Convert.ToString(DateTime.Today.Year - 1934),
943 ["type"] = _duck,
944 };)",
945 Style);
948 TEST_F(FormatTestCSharp, CSharpArrayInitializers) {
949 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
951 verifyFormat(R"(//
952 private MySet<Node>[] setPoints = {
953 new Point<Node>(),
954 new Point<Node>(),
955 };)",
956 Style);
959 TEST_F(FormatTestCSharp, CSharpNamedArguments) {
960 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
962 verifyFormat(R"(//
963 PrintOrderDetails(orderNum: 31, productName: "Red Mug", sellerName: "Gift Shop");)",
964 Style);
966 // Ensure that trailing comments do not cause problems.
967 verifyFormat(R"(//
968 PrintOrderDetails(orderNum: 31, productName: "Red Mug", // comment
969 sellerName: "Gift Shop");)",
970 Style);
972 verifyFormat(R"(foreach (var tickCount in task.Begin(seed: 0)) {)", Style);
975 TEST_F(FormatTestCSharp, CSharpPropertyAccessors) {
976 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
978 verifyFormat("int Value { get }", Style);
979 verifyFormat("int Value { get; }", Style);
980 verifyFormat("int Value { internal get; }", Style);
981 verifyFormat("int Value { get; } = 0", Style);
982 verifyFormat("int Value { set }", Style);
983 verifyFormat("int Value { set; }", Style);
984 verifyFormat("int Value { init; }", Style);
985 verifyFormat("int Value { internal set; }", Style);
986 verifyFormat("int Value { set; } = 0", Style);
987 verifyFormat("int Value { get; set }", Style);
988 verifyFormat("int Value { get; init; }", Style);
989 verifyFormat("int Value { set; get }", Style);
990 verifyFormat("int Value { get; private set; }", Style);
991 verifyFormat("int Value { get; set; }", Style);
992 verifyFormat("int Value { get; set; } = 0", Style);
993 verifyFormat("int Value { internal get; internal set; }", Style);
995 // Do not wrap expression body definitions.
996 verifyFormat(R"(//
997 public string Name {
998 get => _name;
999 set => _name = value;
1000 })",
1001 Style);
1002 verifyFormat(R"(//
1003 public string Name {
1004 init => _name = value;
1005 get => _name;
1006 })",
1007 Style);
1008 verifyFormat(R"(//
1009 public string Name {
1010 set => _name = value;
1011 get => _name;
1012 })",
1013 Style);
1015 // Examples taken from
1016 // https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
1017 verifyFormat(R"(
1018 // Expression body definitions
1019 public class SaleItem {
1020 public decimal Price {
1021 get => _cost;
1022 set => _cost = value;
1024 })",
1025 Style);
1027 verifyFormat(R"(
1028 // Properties with backing fields
1029 class TimePeriod {
1030 public double Hours {
1031 get { return _seconds / 3600; }
1032 set {
1033 if (value < 0 || value > 24)
1034 throw new ArgumentOutOfRangeException($"{nameof(value)} must be between 0 and 24.");
1035 _seconds = value * 3600;
1038 })",
1039 Style);
1041 verifyFormat(R"(
1042 // Auto-implemented properties
1043 public class SaleItem {
1044 public decimal Price { get; set; }
1045 })",
1046 Style);
1048 // Add column limit to wrap long lines.
1049 Style.ColumnLimit = 100;
1051 // Examples with assignment to default value.
1052 verifyFormat(R"(
1053 // Long assignment to default value
1054 class MyClass {
1055 public override VeryLongNamedTypeIndeed VeryLongNamedValue { get; set } =
1056 VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
1057 DefaultThirdArgument);
1058 })",
1059 Style);
1061 verifyFormat(R"(
1062 // Long assignment to default value with expression body
1063 class MyClass {
1064 public override VeryLongNamedTypeIndeed VeryLongNamedValue {
1065 get => veryLongNamedField;
1066 set => veryLongNamedField = value;
1067 } = VeryLongNamedTypeIndeed.Create(DefaultFirstArgument, DefaultSecondArgument,
1068 DefaultThirdArgument);
1069 })",
1070 Style);
1072 // Brace wrapping and single-lining of accessor can be controlled by config.
1073 Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Never;
1074 Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1075 Style.BraceWrapping.AfterFunction = true;
1077 verifyFormat(R"(//
1078 class TimePeriod {
1079 public double Hours
1081 get {
1082 return _seconds / 3600;
1084 set {
1085 _seconds = value * 3600;
1088 })",
1089 Style);
1091 // Microsoft style trivial property accessors have no line break before the
1092 // opening brace.
1093 auto MicrosoftStyle = getMicrosoftStyle(FormatStyle::LK_CSharp);
1094 verifyFormat(R"(//
1095 public class SaleItem
1097 public decimal Price { get; set; }
1098 })",
1099 MicrosoftStyle);
1102 TEST_F(FormatTestCSharp, DefaultLiteral) {
1103 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1105 verifyFormat(
1106 "T[] InitializeArray<T>(int length, T initialValue = default) {}", Style);
1107 verifyFormat("System.Numerics.Complex fillValue = default;", Style);
1108 verifyFormat("int Value { get } = default;", Style);
1109 verifyFormat("int Value { get } = default!;", Style);
1110 verifyFormat(R"(//
1111 public record Person {
1112 public string GetInit { get; init; } = default!;
1113 };)",
1114 Style);
1115 verifyFormat(R"(//
1116 public record Person {
1117 public string GetSet { get; set; } = default!;
1118 };)",
1119 Style);
1122 TEST_F(FormatTestCSharp, CSharpSpaces) {
1123 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1124 Style.SpaceBeforeSquareBrackets = false;
1125 Style.SpacesInSquareBrackets = false;
1126 Style.SpaceBeforeCpp11BracedList = true;
1127 Style.Cpp11BracedListStyle = false;
1128 Style.SpacesInContainerLiterals = false;
1129 Style.SpaceAfterCStyleCast = false;
1131 verifyFormat(R"(new Car { "Door", 0.1 })", Style);
1132 verifyFormat(R"(new Car { 0.1, "Door" })", Style);
1133 verifyFormat(R"(new string[] { "A" })", Style);
1134 verifyFormat(R"(new string[] {})", Style);
1135 verifyFormat(R"(new Car { someVariableName })", Style);
1136 verifyFormat(R"(new Car { someVariableName })", Style);
1137 verifyFormat(R"(new Dictionary<string, string> { ["Key"] = "Value" };)",
1138 Style);
1139 verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style);
1140 verifyFormat(R"(bool[] xs = { true, true };)", Style);
1141 verifyFormat(R"(taskContext.Factory.Run(async () => doThing(args);)", Style);
1142 verifyFormat(R"(catch (TestException) when (innerFinallyExecuted))", Style);
1143 verifyFormat(R"(private float[,] Values;)", Style);
1144 verifyFormat(R"(Result this[Index x] => Foo(x);)", Style);
1146 verifyFormat(R"(char[,,] rawCharArray = MakeCharacterGrid();)", Style);
1147 verifyFormat(R"(var (key, value))", Style);
1149 // `&&` is not seen as a reference.
1150 verifyFormat(R"(A == typeof(X) && someBool)", Style);
1152 // Not seen as a C-style cast.
1153 verifyFormat(R"(//
1154 foreach ((A a, B b) in someList) {
1155 })",
1156 Style);
1158 // space after lock in `lock (processes)`.
1159 verifyFormat("lock (process)", Style);
1161 Style.SpacesInSquareBrackets = true;
1162 verifyFormat(R"(private float[ , ] Values;)", Style);
1163 verifyFormat(R"(string dirPath = args?[ 0 ];)", Style);
1164 verifyFormat(R"(char[ ,, ] rawCharArray = MakeCharacterGrid();)", Style);
1166 // Method returning tuple
1167 verifyFormat(R"(public (string name, int age) methodTuple() {})", Style);
1168 verifyFormat(R"(private (string name, int age) methodTuple() {})", Style);
1169 verifyFormat(R"(protected (string name, int age) methodTuple() {})", Style);
1170 verifyFormat(R"(virtual (string name, int age) methodTuple() {})", Style);
1171 verifyFormat(R"(extern (string name, int age) methodTuple() {})", Style);
1172 verifyFormat(R"(static (string name, int age) methodTuple() {})", Style);
1173 verifyFormat(R"(internal (string name, int age) methodTuple() {})", Style);
1174 verifyFormat(R"(abstract (string name, int age) methodTuple() {})", Style);
1175 verifyFormat(R"(sealed (string name, int age) methodTuple() {})", Style);
1176 verifyFormat(R"(override (string name, int age) methodTuple() {})", Style);
1177 verifyFormat(R"(async (string name, int age) methodTuple() {})", Style);
1178 verifyFormat(R"(unsafe (string name, int age) methodTuple() {})", Style);
1180 Style.SpacesInSquareBrackets = false;
1181 Style.SpaceBeforeSquareBrackets = true;
1182 verifyFormat("return a is [1, 2, 3];", Style);
1183 verifyFormat("return a is [..];", Style);
1184 Style.SpaceBeforeSquareBrackets = false;
1185 verifyFormat("return a is [1, 2, 3];", Style);
1186 verifyFormat("return a is [..];", Style);
1189 TEST_F(FormatTestCSharp, CSharpNullableTypes) {
1190 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1191 Style.SpacesInSquareBrackets = false;
1193 verifyFormat(R"(//
1194 public class A {
1195 void foo() {
1196 int? value = some.bar();
1198 })",
1199 Style); // int? is nullable not a conditional expression.
1201 verifyFormat(R"(void foo(int? x, int? y, int? z) {})",
1202 Style); // Nullables in function definitions.
1204 verifyFormat(R"(public float? Value;)", Style); // no space before `?`.
1206 verifyFormat(R"(int?[] arr = new int?[10];)",
1207 Style); // An array of a nullable type.
1209 verifyFormat(R"(var x = (int?)y;)", Style); // Cast to a nullable type.
1211 verifyFormat(R"(var x = new MyContainer<int?>();)", Style); // Generics.
1213 verifyFormat(R"(//
1214 public interface I {
1215 int? Function();
1216 })",
1217 Style); // Interface methods.
1219 Style.ColumnLimit = 10;
1220 verifyFormat(R"(//
1221 public VeryLongType? Function(
1222 int arg1,
1223 int arg2) {
1225 })",
1226 Style); // ? sticks with identifier.
1229 TEST_F(FormatTestCSharp, CSharpArraySubscripts) {
1230 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1232 // Do not format array subscript operators as attributes.
1233 verifyFormat(R"(//
1234 if (someThings[index].Contains(myThing)) {
1235 })",
1236 Style);
1238 verifyFormat(R"(//
1239 if (someThings[i][j][k].Contains(myThing)) {
1240 })",
1241 Style);
1244 TEST_F(FormatTestCSharp, CSharpGenericTypeConstraints) {
1245 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1247 EXPECT_TRUE(Style.BraceWrapping.SplitEmptyRecord);
1249 verifyFormat("class ItemFactory<T>\n"
1250 " where T : new() {\n"
1251 "}",
1252 Style);
1254 verifyFormat("class Dictionary<TKey, TVal>\n"
1255 " where TKey : IComparable<TKey>\n"
1256 " where TVal : IMyInterface {\n"
1257 " public void MyMethod<T>(T t)\n"
1258 " where T : IMyInterface {\n"
1259 " doThing();\n"
1260 " }\n"
1261 "}",
1262 Style);
1264 verifyFormat("class ItemFactory<T>\n"
1265 " where T : new(), IAnInterface<T>, IAnotherInterface<T>, "
1266 "IAnotherInterfaceStill<T> {\n"
1267 "}",
1268 Style);
1270 Style.ColumnLimit = 50; // Force lines to be wrapped.
1271 verifyFormat(R"(//
1272 class ItemFactory<T, U>
1273 where T : new(),
1274 IAnInterface<T>,
1275 IAnotherInterface<T, U>,
1276 IAnotherInterfaceStill<T, U> {
1277 })",
1278 Style);
1280 // In other languages `where` can be used as a normal identifier.
1281 // This example is in C++!
1282 verifyFormat(R"(//
1283 class A {
1284 int f(int where) {}
1285 };)",
1286 getGoogleStyle(FormatStyle::LK_Cpp));
1289 TEST_F(FormatTestCSharp, CSharpAfterEnum) {
1290 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1291 Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1292 Style.BraceWrapping.AfterEnum = false;
1293 Style.AllowShortEnumsOnASingleLine = false;
1295 verifyFormat("enum MyEnum {\n"
1296 " Foo,\n"
1297 " Bar,\n"
1298 "}",
1299 Style);
1300 verifyFormat("internal enum MyEnum {\n"
1301 " Foo,\n"
1302 " Bar,\n"
1303 "}",
1304 Style);
1305 verifyFormat("public enum MyEnum {\n"
1306 " Foo,\n"
1307 " Bar,\n"
1308 "}",
1309 Style);
1310 verifyFormat("protected enum MyEnum {\n"
1311 " Foo,\n"
1312 " Bar,\n"
1313 "}",
1314 Style);
1315 verifyFormat("private enum MyEnum {\n"
1316 " Foo,\n"
1317 " Bar,\n"
1318 "}",
1319 Style);
1321 Style.BraceWrapping.AfterEnum = true;
1322 Style.AllowShortEnumsOnASingleLine = false;
1324 verifyFormat("enum MyEnum\n"
1325 "{\n"
1326 " Foo,\n"
1327 " Bar,\n"
1328 "}",
1329 Style);
1330 verifyFormat("internal enum MyEnum\n"
1331 "{\n"
1332 " Foo,\n"
1333 " Bar,\n"
1334 "}",
1335 Style);
1336 verifyFormat("public enum MyEnum\n"
1337 "{\n"
1338 " Foo,\n"
1339 " Bar,\n"
1340 "}",
1341 Style);
1342 verifyFormat("protected enum MyEnum\n"
1343 "{\n"
1344 " Foo,\n"
1345 " Bar,\n"
1346 "}",
1347 Style);
1348 verifyFormat("private enum MyEnum\n"
1349 "{\n"
1350 " Foo,\n"
1351 " Bar,\n"
1352 "}",
1353 Style);
1354 verifyFormat("/* Foo */ private enum MyEnum\n"
1355 "{\n"
1356 " Foo,\n"
1357 " Bar,\n"
1358 "}",
1359 Style);
1360 verifyFormat("/* Foo */ /* Bar */ private enum MyEnum\n"
1361 "{\n"
1362 " Foo,\n"
1363 " Bar,\n"
1364 "}",
1365 Style);
1368 TEST_F(FormatTestCSharp, CSharpAfterClass) {
1369 FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
1370 Style.BreakBeforeBraces = FormatStyle::BS_Custom;
1371 Style.BraceWrapping.AfterClass = false;
1373 verifyFormat("class MyClass {\n"
1374 " int a;\n"
1375 " int b;\n"
1376 "}",
1377 Style);
1378 verifyFormat("internal class MyClass {\n"
1379 " int a;\n"
1380 " int b;\n"
1381 "}",
1382 Style);
1383 verifyFormat("public class MyClass {\n"
1384 " int a;\n"
1385 " int b;\n"
1386 "}",
1387 Style);
1388 verifyFormat("protected class MyClass {\n"
1389 " int a;\n"
1390 " int b;\n"
1391 "}",
1392 Style);
1393 verifyFormat("private class MyClass {\n"
1394 " int a;\n"
1395 " int b;\n"
1396 "}",
1397 Style);
1399 verifyFormat("interface Interface {\n"
1400 " int a;\n"
1401 " int b;\n"
1402 "}",
1403 Style);
1404 verifyFormat("internal interface Interface {\n"
1405 " int a;\n"
1406 " int b;\n"
1407 "}",
1408 Style);
1409 verifyFormat("public interface Interface {\n"
1410 " int a;\n"
1411 " int b;\n"
1412 "}",
1413 Style);
1414 verifyFormat("protected interface Interface {\n"
1415 " int a;\n"
1416 " int b;\n"
1417 "}",
1418 Style);
1419 verifyFormat("private interface Interface {\n"
1420 " int a;\n"
1421 " int b;\n"
1422 "}",
1423 Style);
1425 Style.BraceWrapping.AfterClass = true;
1427 verifyFormat("class MyClass\n"
1428 "{\n"
1429 " int a;\n"
1430 " int b;\n"
1431 "}",
1432 Style);
1433 verifyFormat("internal class MyClass\n"
1434 "{\n"
1435 " int a;\n"
1436 " int b;\n"
1437 "}",
1438 Style);
1439 verifyFormat("public class MyClass\n"
1440 "{\n"
1441 " int a;\n"
1442 " int b;\n"
1443 "}",
1444 Style);
1445 verifyFormat("protected class MyClass\n"
1446 "{\n"
1447 " int a;\n"
1448 " int b;\n"
1449 "}",
1450 Style);
1451 verifyFormat("private class MyClass\n"
1452 "{\n"
1453 " int a;\n"
1454 " int b;\n"
1455 "}",
1456 Style);
1458 verifyFormat("interface MyInterface\n"
1459 "{\n"
1460 " int a;\n"
1461 " int b;\n"
1462 "}",
1463 Style);
1464 verifyFormat("internal interface MyInterface\n"
1465 "{\n"
1466 " int a;\n"
1467 " int b;\n"
1468 "}",
1469 Style);
1470 verifyFormat("public interface MyInterface\n"
1471 "{\n"
1472 " int a;\n"
1473 " int b;\n"
1474 "}",
1475 Style);
1476 verifyFormat("protected interface MyInterface\n"
1477 "{\n"
1478 " int a;\n"
1479 " int b;\n"
1480 "}",
1481 Style);
1482 verifyFormat("private interface MyInterface\n"
1483 "{\n"
1484 " int a;\n"
1485 " int b;\n"
1486 "}",
1487 Style);
1488 verifyFormat("/* Foo */ private interface MyInterface\n"
1489 "{\n"
1490 " int a;\n"
1491 " int b;\n"
1492 "}",
1493 Style);
1494 verifyFormat("/* Foo */ /* Bar */ private interface MyInterface\n"
1495 "{\n"
1496 " int a;\n"
1497 " int b;\n"
1498 "}",
1499 Style);
1502 TEST_F(FormatTestCSharp, NamespaceIndentation) {
1503 FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
1504 Style.NamespaceIndentation = FormatStyle::NI_None;
1506 verifyFormat("namespace A\n"
1507 "{\n"
1508 "public interface Name1\n"
1509 "{\n"
1510 "}\n"
1511 "}\n",
1512 Style);
1514 verifyFormat("namespace A.B\n"
1515 "{\n"
1516 "public interface Name1\n"
1517 "{\n"
1518 "}\n"
1519 "}\n",
1520 Style);
1522 Style.NamespaceIndentation = FormatStyle::NI_Inner;
1524 verifyFormat("namespace A\n"
1525 "{\n"
1526 "namespace B\n"
1527 "{\n"
1528 " public interface Name1\n"
1529 " {\n"
1530 " }\n"
1531 "}\n"
1532 "}\n",
1533 Style);
1535 Style.NamespaceIndentation = FormatStyle::NI_All;
1537 verifyFormat("namespace A.B\n"
1538 "{\n"
1539 " public interface Name1\n"
1540 " {\n"
1541 " }\n"
1542 "}\n",
1543 Style);
1545 verifyFormat("namespace A\n"
1546 "{\n"
1547 " namespace B\n"
1548 " {\n"
1549 " public interface Name1\n"
1550 " {\n"
1551 " }\n"
1552 " }\n"
1553 "}\n",
1554 Style);
1557 TEST_F(FormatTestCSharp, SwitchExpression) {
1558 FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
1559 verifyFormat("int x = a switch {\n"
1560 " 1 => (0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0),\n"
1561 " 2 => 1,\n"
1562 " _ => 2\n"
1563 "};\n",
1564 Style);
1567 TEST_F(FormatTestCSharp, EmptyShortBlock) {
1568 auto Style = getLLVMStyle();
1569 Style.AllowShortBlocksOnASingleLine = FormatStyle::SBS_Empty;
1571 verifyFormat("try {\n"
1572 " doA();\n"
1573 "} catch (Exception e) {\n"
1574 " e.printStackTrace();\n"
1575 "}\n",
1576 Style);
1578 verifyFormat("try {\n"
1579 " doA();\n"
1580 "} catch (Exception e) {}\n",
1581 Style);
1584 TEST_F(FormatTestCSharp, ShortFunctions) {
1585 FormatStyle Style = getLLVMStyle(FormatStyle::LK_CSharp);
1586 Style.NamespaceIndentation = FormatStyle::NI_All;
1587 Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Inline;
1588 verifyFormat("interface Interface {\n"
1589 " void f() { return; }\n"
1590 "};",
1591 Style);
1592 verifyFormat("public interface Interface {\n"
1593 " void f() { return; }\n"
1594 "};",
1595 Style);
1596 verifyFormat("namespace {\n"
1597 " void f() {\n"
1598 " return;\n"
1599 " }\n"
1600 "};",
1601 Style);
1602 // "union" is not a keyword in C#.
1603 verifyFormat("namespace union {\n"
1604 " void f() {\n"
1605 " return;\n"
1606 " }\n"
1607 "};",
1608 Style);
1611 TEST_F(FormatTestCSharp, BrokenBrackets) {
1612 EXPECT_NE("", format("int where b <")); // reduced from crasher
1615 } // namespace format
1616 } // end namespace clang