Author: Jonathan Coe Date: 2020-02-28T11:09:55Z New Revision: 5f52a93b698bab3f7083a6d97d3e3a2e303866e0
URL: https://github.com/llvm/llvm-project/commit/5f52a93b698bab3f7083a6d97d3e3a2e303866e0 DIFF: https://github.com/llvm/llvm-project/commit/5f52a93b698bab3f7083a6d97d3e3a2e303866e0.diff LOG: [clang-format] Recognize C# nullable types Summary: Do not confuse C# nullable types with conditional expressions. Do not put a space before the `?` in `[access-modifier] Type? variableName;` Reviewers: krasimir, MyDeveloperDay Reviewed By: krasimir, MyDeveloperDay Subscribers: cfe-commits, MyDeveloperDay Tags: #clang-format, #clang Differential Revision: https://reviews.llvm.org/D75261 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/TokenAnnotator.cpp clang/unittests/Format/FormatTestCSharp.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index bab513a03a33..61c3cda89cdc 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -104,6 +104,7 @@ namespace format { TYPE(CSharpStringLiteral) \ TYPE(CSharpNullCoalescing) \ TYPE(CSharpNamedArgumentColon) \ + TYPE(CSharpNullableTypeQuestionMark) \ TYPE(Unknown) enum TokenType { diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index fb60b8fb7b58..0185dadb15af 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -987,6 +987,10 @@ class AnnotatingParser { if (Line.MustBeDeclaration && !Contexts.back().IsExpression && Style.Language == FormatStyle::LK_JavaScript) break; + if (Style.isCSharp() && Line.MustBeDeclaration) { + Tok->Type = TT_CSharpNullableTypeQuestionMark; + break; + } parseConditional(); break; case tok::kw_template: @@ -2902,6 +2906,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line, if (Left.is(tok::comma) && Right.is(tok::r_square)) return Style.SpacesInSquareBrackets; + // No space before ? in nullable types. + if (Right.is(TT_CSharpNullableTypeQuestionMark)) + return false; + // space between keywords and paren e.g. "using (" if (Right.is(tok::l_paren)) if (Left.isOneOf(tok::kw_using, Keywords.kw_async, Keywords.kw_when)) diff --git a/clang/unittests/Format/FormatTestCSharp.cpp b/clang/unittests/Format/FormatTestCSharp.cpp index ec8dfff94a2b..b91a380456c9 100644 --- a/clang/unittests/Format/FormatTestCSharp.cpp +++ b/clang/unittests/Format/FormatTestCSharp.cpp @@ -175,7 +175,7 @@ TEST_F(FormatTestCSharp, CSharpNullConditional) { Style.SpaceBeforeParens = FormatStyle::SBPO_Always; verifyFormat( - "public Person(string firstName, string lastName, int? age=null)"); + "public Person(string firstName, string lastName, int? age = null)"); verifyFormat("foo () {\n" " switch (args?.Length) {}\n" @@ -603,5 +603,18 @@ TEST_F(FormatTestCSharp, CSharpSpaces) { verifyFormat(R"(private float[, ] Values;)", Style); } +TEST_F(FormatTestCSharp, CSharpNullableTypes) { + FormatStyle Style = getGoogleStyle(FormatStyle::LK_CSharp); + Style.SpacesInSquareBrackets = false; + + verifyFormat(R"(public float? Value;)", Style); // no space before `?`. + + // Erroneous spaces in square brackets here will be tackled in a follow-up + // patch and are not addressed by setting + // `Style.SpacesInSquareBrackets = false;` + verifyFormat(R"(int?[] arr = new int?[ 10 ];)", + Style); // An array of a nullable type. +} + } // namespace format } // end namespace clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits