Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -2836,6 +2836,36 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, const FormatToken &Right) { const FormatToken &Left = *Right.Previous; + if (Style.isCSharp()) { + // Require spaces around '{' and before '}' unless they appear in + // interpolated strings. Interpolated strings are merged into a single token + // so cannot have spaces inserted by this function. + + // Space before { + if (Left.isOneOf(tok::identifier, tok::r_paren, tok::r_square, + tok::greater) && + Right.is(tok::l_brace)) + return true; + + // Spaces inside braces. + if (Left.is(tok::l_brace) && + Right.isOneOf(tok::kw_new, tok::identifier, tok::string_literal, + tok::r_paren, tok::l_square, tok::numeric_constant, + tok::kw_true, tok::kw_false, tok::kw_typeof)) + return true; + if (Left.isOneOf(tok::identifier, tok::string_literal, tok::r_paren, + tok::r_square, tok::numeric_constant, tok::kw_true, + tok::kw_false) && + Right.is(tok::r_brace)) + return true; + + // Spaces around '=>'. + if (Left.is(TT_JsFatArrow) || Right.is(TT_JsFatArrow)) + return true; + // No space between identifier and '['. + if (Left.is(tok::identifier) && Right.is(tok::l_square)) + return false; + } if (Right.Tok.getIdentifierInfo() && Left.Tok.getIdentifierInfo()) return true; // Never ever merge two identifiers. if (Style.isCpp()) { Index: clang/unittests/Format/FormatTestCSharp.cpp =================================================================== --- clang/unittests/Format/FormatTestCSharp.cpp +++ clang/unittests/Format/FormatTestCSharp.cpp @@ -525,11 +525,11 @@ // Omitted final `,`s will change the formatting. verifyFormat(R"(// -Shape[] shapes = new[] {new Circle {Radius = 2.7281, Colour = Colours.Red}, - new Square { - Side = 101.1, - Colour = Colours.Yellow, - }};)", +Shape[] shapes = new[] { new Circle { Radius = 2.7281, Colour = Colours.Red }, + new Square { + Side = 101.1, + Colour = Colours.Yellow, + }};)", Style); } @@ -575,5 +575,20 @@ Style); } +TEST_F(FormatTestCSharp, CSharpSpaces) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); + + verifyFormat(R"(new Car { "Door", 0.1 })", Style); + verifyFormat(R"(new Car { 0.1, "Door" })", Style); + verifyFormat(R"(new string[] { "A" })", Style); + verifyFormat(R"(new string[] {})", Style); + verifyFormat(R"(new Car { someVariableName })", Style); + verifyFormat(R"(new Car { someVariableName })", Style); + verifyFormat(R"(new Dictionary { ["Key"] = "Value" };)", + Style); + verifyFormat(R"(Apply(x => x.Name, x => () => x.ID);)", Style); + verifyFormat(R"(bool[] xs = { true, true };)", Style); +} + } // namespace format } // end namespace clang