123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- //===- unittest/Format/FormatTestCSharp.cpp - Formatting tests for CSharp -===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "FormatTestUtils.h"
- #include "clang/Format/Format.h"
- #include "llvm/Support/Debug.h"
- #include "gtest/gtest.h"
- #define DEBUG_TYPE "format-test"
- namespace clang {
- namespace format {
- class FormatTestCSharp : public ::testing::Test {
- protected:
- static std::string format(llvm::StringRef Code, unsigned Offset,
- unsigned Length, const FormatStyle &Style) {
- LLVM_DEBUG(llvm::errs() << "---\n");
- LLVM_DEBUG(llvm::errs() << Code << "\n\n");
- std::vector<tooling::Range> Ranges(1, tooling::Range(Offset, Length));
- tooling::Replacements Replaces = reformat(Style, Code, Ranges);
- auto Result = applyAllReplacements(Code, Replaces);
- EXPECT_TRUE(static_cast<bool>(Result));
- LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
- return *Result;
- }
- static std::string
- format(llvm::StringRef Code,
- const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
- return format(Code, 0, Code.size(), Style);
- }
- static FormatStyle getStyleWithColumns(unsigned ColumnLimit) {
- FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
- Style.ColumnLimit = ColumnLimit;
- return Style;
- }
- static void verifyFormat(
- llvm::StringRef Code,
- const FormatStyle &Style = getMicrosoftStyle(FormatStyle::LK_CSharp)) {
- EXPECT_EQ(Code.str(), format(Code, Style)) << "Expected code is not stable";
- EXPECT_EQ(Code.str(), format(test::messUp(Code), Style));
- }
- };
- TEST_F(FormatTestCSharp, CSharpClass) {
- verifyFormat("public class SomeClass\n"
- "{\n"
- " void f()\n"
- " {\n"
- " }\n"
- " int g()\n"
- " {\n"
- " return 0;\n"
- " }\n"
- " void h()\n"
- " {\n"
- " while (true)\n"
- " f();\n"
- " for (;;)\n"
- " f();\n"
- " if (true)\n"
- " f();\n"
- " }\n"
- "}");
- }
- TEST_F(FormatTestCSharp, AccessModifiers) {
- verifyFormat("public String toString()\n"
- "{\n"
- "}");
- verifyFormat("private String toString()\n"
- "{\n"
- "}");
- verifyFormat("protected String toString()\n"
- "{\n"
- "}");
- verifyFormat("internal String toString()\n"
- "{\n"
- "}");
- verifyFormat("public override String toString()\n"
- "{\n"
- "}");
- verifyFormat("private override String toString()\n"
- "{\n"
- "}");
- verifyFormat("protected override String toString()\n"
- "{\n"
- "}");
- verifyFormat("internal override String toString()\n"
- "{\n"
- "}");
- verifyFormat("internal static String toString()\n"
- "{\n"
- "}");
- }
- TEST_F(FormatTestCSharp, NoStringLiteralBreaks) {
- verifyFormat("foo("
- "\"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
- "aaaaaa\");");
- }
- TEST_F(FormatTestCSharp, CSharpVerbatiumStringLiterals) {
- verifyFormat("foo(@\"aaaaaaaa\\abc\\aaaa\");");
- // @"ABC\" + ToString("B") - handle embedded \ in literal string at
- // the end
- //
- /*
- * After removal of Lexer change we are currently not able
- * To handle these cases
- verifyFormat("string s = @\"ABC\\\" + ToString(\"B\");");
- verifyFormat("string s = @\"ABC\"\"DEF\"\"GHI\"");
- verifyFormat("string s = @\"ABC\"\"DEF\"\"\"");
- verifyFormat("string s = @\"ABC\"\"DEF\"\"\" + abc");
- */
- }
- TEST_F(FormatTestCSharp, CSharpInterpolatedStringLiterals) {
- verifyFormat("foo($\"aaaaaaaa{aaa}aaaa\");");
- verifyFormat("foo($\"aaaa{A}\");");
- verifyFormat(
- "foo($\"aaaa{A}"
- "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\");");
- verifyFormat("Name = $\"{firstName} {lastName}\";");
- // $"ABC\" + ToString("B") - handle embedded \ in literal string at
- // the end
- verifyFormat("string s = $\"A{abc}BC\" + ToString(\"B\");");
- verifyFormat("$\"{domain}\\\\{user}\"");
- verifyFormat(
- "var verbatimInterpolated = $@\"C:\\Users\\{userName}\\Documents\\\";");
- }
- TEST_F(FormatTestCSharp, CSharpFatArrows) {
- verifyFormat("Task serverTask = Task.Run(async() => {");
- verifyFormat("public override string ToString() => \"{Name}\\{Age}\";");
- }
- TEST_F(FormatTestCSharp, CSharpNullConditional) {
- FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
- Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
- verifyFormat(
- "public Person(string firstName, string lastName, int? age=null)");
- verifyFormat("foo () {\n"
- " switch (args?.Length) {}\n"
- "}",
- Style);
- verifyFormat("switch (args?.Length) {}", Style);
- verifyFormat("public static void Main(string[] args)\n"
- "{\n"
- " string dirPath = args?[0];\n"
- "}");
- Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
- verifyFormat("switch(args?.Length) {}", Style);
- }
- TEST_F(FormatTestCSharp, Attributes) {
- verifyFormat("[STAThread]\n"
- "static void Main(string[] args)\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "private class Test\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "protected class Test\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "internal class Test\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "class Test\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "[DeploymentItem(\"Test.txt\")]\n"
- "public class Test\n"
- "{\n"
- "}");
- verifyFormat("[System.AttributeUsage(System.AttributeTargets.Method)]\n"
- "[System.Runtime.InteropServices.ComVisible(true)]\n"
- "public sealed class STAThreadAttribute : Attribute\n"
- "{\n"
- "}");
- verifyFormat("[Verb(\"start\", HelpText = \"Starts the server listening on "
- "provided port\")]\n"
- "class Test\n"
- "{\n"
- "}");
- verifyFormat("[TestMethod]\n"
- "public string Host\n"
- "{\n"
- " set;\n"
- " get;\n"
- "}");
- verifyFormat("[TestMethod(\"start\", HelpText = \"Starts the server "
- "listening on provided host\")]\n"
- "public string Host\n"
- "{\n"
- " set;\n"
- " get;\n"
- "}");
- }
- TEST_F(FormatTestCSharp, CSharpUsing) {
- FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
- Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
- verifyFormat("public void foo () {\n"
- " using (StreamWriter sw = new StreamWriter (filenameA)) {}\n"
- "}",
- Style);
- verifyFormat("using (StreamWriter sw = new StreamWriter (filenameB)) {}",
- Style);
- Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
- verifyFormat("public void foo() {\n"
- " using(StreamWriter sw = new StreamWriter(filenameB)) {}\n"
- "}",
- Style);
- verifyFormat("using(StreamWriter sw = new StreamWriter(filenameB)) {}",
- Style);
- }
- TEST_F(FormatTestCSharp, CSharpRegions) {
- verifyFormat("#region aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaa "
- "aaaaaaaaaaaaaaa long region");
- }
- TEST_F(FormatTestCSharp, CSharpKeyWordEscaping) {
- verifyFormat("public enum var { none, @string, bool, @enum }");
- }
- TEST_F(FormatTestCSharp, CSharpNullCoalescing) {
- verifyFormat("var test = ABC ?? DEF");
- verifyFormat("string myname = name ?? \"ABC\";");
- verifyFormat("return _name ?? \"DEF\";");
- }
- TEST_F(FormatTestCSharp, AttributesIndentation) {
- FormatStyle Style = getMicrosoftStyle(FormatStyle::LK_CSharp);
- Style.AlwaysBreakAfterReturnType = FormatStyle::RTBS_None;
- verifyFormat("[STAThread]\n"
- "static void Main(string[] args)\n"
- "{\n"
- "}",
- Style);
- verifyFormat("[STAThread]\n"
- "void "
- "veryLooooooooooooooongFunctionName(string[] args)\n"
- "{\n"
- "}",
- Style);
- verifyFormat("[STAThread]\n"
- "veryLoooooooooooooooooooongReturnType "
- "veryLooooooooooooooongFunctionName(string[] args)\n"
- "{\n"
- "}",
- Style);
- verifyFormat("[SuppressMessage(\"A\", \"B\", Justification = \"C\")]\n"
- "public override X Y()\n"
- "{\n"
- "}\n",
- Style);
- verifyFormat("[SuppressMessage]\n"
- "public X Y()\n"
- "{\n"
- "}\n",
- Style);
- verifyFormat("[SuppressMessage]\n"
- "public override X Y()\n"
- "{\n"
- "}\n",
- Style);
- verifyFormat("public A(B b) : base(b)\n"
- "{\n"
- " [SuppressMessage]\n"
- " public override X Y()\n"
- " {\n"
- " }\n"
- "}\n",
- Style);
- }
- TEST_F(FormatTestCSharp, CSharpSpaceBefore) {
- FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp);
- Style.SpaceBeforeParens = FormatStyle::SBPO_Always;
- verifyFormat("List<string> list;", Style);
- verifyFormat("Dictionary<string, string> dict;", Style);
- verifyFormat("for (int i = 0; i < size (); i++) {\n"
- "}",
- Style);
- verifyFormat("foreach (var x in y) {\n"
- "}",
- Style);
- verifyFormat("switch (x) {}", Style);
- verifyFormat("do {\n"
- "} while (x);",
- Style);
- Style.SpaceBeforeParens = FormatStyle::SBPO_Never;
- verifyFormat("List<string> list;", Style);
- verifyFormat("Dictionary<string, string> dict;", Style);
- verifyFormat("for(int i = 0; i < size(); i++) {\n"
- "}",
- Style);
- verifyFormat("foreach(var x in y) {\n"
- "}",
- Style);
- verifyFormat("switch(x) {}", Style);
- verifyFormat("do {\n"
- "} while(x);",
- Style);
- }
- } // namespace format
- } // end namespace clang
|