Skip to content

Commit 8a3a031

Browse files
committed
Exclude null-forgiving operator for SA1013
1 parent 9c9bc1c commit 8a3a031

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1013CSharp8UnitTests.cs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,22 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp8.SpacingRules
55
{
6+
using System;
7+
using System.Collections.Generic;
68
using System.Threading;
79
using System.Threading.Tasks;
10+
11+
using Microsoft.CodeAnalysis;
12+
using Microsoft.CodeAnalysis.CodeFixes;
13+
using Microsoft.CodeAnalysis.CSharp;
14+
using Microsoft.CodeAnalysis.Diagnostics;
15+
using Microsoft.CodeAnalysis.Testing;
16+
using Microsoft.CodeAnalysis.Testing.Verifiers;
17+
818
using StyleCop.Analyzers.Test.CSharp7.SpacingRules;
19+
920
using Xunit;
21+
1022
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
1123
StyleCop.Analyzers.SpacingRules.SA1013ClosingBracesMustBeSpacedCorrectly,
1224
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;
@@ -62,5 +74,54 @@ public void TestMethod(object value)
6274
var expected = Diagnostic().WithSpan(14, 37, 14, 38).WithArguments(string.Empty, "followed");
6375
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
6476
}
77+
78+
/// <summary>
79+
/// Validates that a closing brace followed by a null-forgiving operator does not require a space.
80+
/// </summary>
81+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
82+
[Fact]
83+
[WorkItem(3172, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3172")]
84+
public async Task TestCloseBraceWithNullForgivingOperatorAsync()
85+
{
86+
const string testCode = @"
87+
public class Foo
88+
{
89+
public void TestMethod()
90+
{
91+
var test = new[]
92+
{
93+
new { Value = default(string) },
94+
new { Value = ""a"" }!,
95+
new { Value = ""b"" } !,
96+
};
97+
}
98+
}
99+
";
100+
101+
var test = new NullableCSharpAnalyzerTest
102+
{
103+
TestCode = testCode,
104+
};
105+
106+
await test.RunAsync(CancellationToken.None).ConfigureAwait(false);
107+
}
108+
109+
private class NullableCSharpAnalyzerTest : AnalyzerTest<XUnitVerifier>
110+
{
111+
public override string Language => LanguageNames.CSharp;
112+
113+
protected override string DefaultFileExt => "cs";
114+
115+
protected override CompilationOptions CreateCompilationOptions()
116+
=> new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true, nullableContextOptions: NullableContextOptions.Enable);
117+
118+
protected override ParseOptions CreateParseOptions()
119+
=> new CSharpParseOptions(LanguageVersion.CSharp8);
120+
121+
protected override IEnumerable<DiagnosticAnalyzer> GetDiagnosticAnalyzers()
122+
{
123+
yield return new StyleCop.Analyzers.SpacingRules.SA1013ClosingBracesMustBeSpacedCorrectly();
124+
}
125+
}
65126
}
66127
}

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1013ClosingBracesMustBeSpacedCorrectly.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ private static void HandleCloseBraceToken(SyntaxTreeAnalysisContext context, Syn
102102
|| nextToken.IsKind(SyntaxKind.DotToken)
103103
|| (nextToken.IsKind(SyntaxKind.QuestionToken) && nextToken.GetNextToken(includeZeroWidth: true).IsKind(SyntaxKind.DotToken))
104104
|| nextToken.IsKind(SyntaxKind.CloseBracketToken)
105-
|| (nextToken.IsKind(SyntaxKind.ColonToken) && nextToken.Parent.IsKind(SyntaxKindEx.CasePatternSwitchLabel));
105+
|| (nextToken.IsKind(SyntaxKind.ColonToken) && nextToken.Parent.IsKind(SyntaxKindEx.CasePatternSwitchLabel))
106+
|| (nextToken.IsKind(SyntaxKind.ExclamationToken) && nextToken.Parent.IsKind(SyntaxKindEx.SuppressNullableWarningExpression));
106107
}
107108
else
108109
{

0 commit comments

Comments
 (0)