Skip to content

Commit 081e2d0

Browse files
authored
Merge pull request #3737 from bjornhellander/feature/sa1119-ref-conditional
Update SA1119 to allow parenthesis around a ref ternary conditional expression when it is the left-hand side of an assigment
2 parents c0246ab + 380924c commit 081e2d0

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/MaintainabilityRules/SA1119CSharp7UnitTests.cs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,12 @@
55

66
namespace StyleCop.Analyzers.Test.CSharp7.MaintainabilityRules
77
{
8+
using System.Collections.Generic;
89
using System.Threading;
910
using System.Threading.Tasks;
1011
using Microsoft.CodeAnalysis.Testing;
12+
using StyleCop.Analyzers.Lightup;
13+
using StyleCop.Analyzers.Test.Helpers;
1114
using StyleCop.Analyzers.Test.MaintainabilityRules;
1215
using Xunit;
1316
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
@@ -16,6 +19,31 @@ namespace StyleCop.Analyzers.Test.CSharp7.MaintainabilityRules
1619

1720
public partial class SA1119CSharp7UnitTests : SA1119UnitTests
1821
{
22+
public static IEnumerable<object[]> Assignments
23+
{
24+
get
25+
{
26+
yield return new object[] { "= 1" };
27+
yield return new object[] { "+= 1" };
28+
yield return new object[] { "-= 1" };
29+
yield return new object[] { "*= 1" };
30+
yield return new object[] { "/= 1" };
31+
yield return new object[] { "%= 1" };
32+
yield return new object[] { "&= 1" };
33+
yield return new object[] { "|= 1" };
34+
yield return new object[] { "^= 1" };
35+
yield return new object[] { "<<= 1" };
36+
yield return new object[] { ">>= 1" };
37+
yield return new object[] { "++" };
38+
yield return new object[] { "--" };
39+
40+
if (LightupHelpers.SupportsCSharp11)
41+
{
42+
yield return new object[] { ">>>= 1" };
43+
}
44+
}
45+
}
46+
1947
/// <summary>
2048
/// Verifies that extra parentheses in pattern matching is not reported.
2149
/// </summary>
@@ -85,5 +113,21 @@ public void Bar()
85113

86114
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
87115
}
116+
117+
[Theory]
118+
[MemberData(nameof(Assignments))]
119+
[WorkItem(3712, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3712")]
120+
public async Task TestConditionalRefAssignmentAsync(string assignment)
121+
{
122+
var testCode = $@"public class Foo
123+
{{
124+
public void Bar(bool b, ref int x, ref int y)
125+
{{
126+
(b ? ref x : ref y) {assignment};
127+
}}
128+
}}";
129+
130+
await VerifyCSharpDiagnosticAsync(LanguageVersionEx.CSharp7_2.OrLaterDefault(), testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
131+
}
88132
}
89133
}

StyleCop.Analyzers/StyleCop.Analyzers/MaintainabilityRules/SA1119StatementMustNotUseUnnecessaryParenthesis.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ private static void HandleParenthesizedExpression(SyntaxNodeAnalysisContext cont
153153
return;
154154
}
155155

156+
if (node.Parent is AssignmentExpressionSyntax assignmentExpression
157+
&& node.Expression.IsKind(SyntaxKind.ConditionalExpression)
158+
&& assignmentExpression.Left == node)
159+
{
160+
// NOTE: This is only valid syntax if the conditional expression is a ref expression
161+
// Parenthesis can't be removed here
162+
return;
163+
}
164+
156165
if (!(node.Parent is ExpressionSyntax)
157166
|| node.Parent is CheckedExpressionSyntax
158167
|| node.Parent is MemberAccessExpressionSyntax)

0 commit comments

Comments
 (0)