Skip to content

Commit c473b64

Browse files
committed
Fix SA1003 handling of colon in format clause
Fixes #3073
1 parent 31030c7 commit c473b64

2 files changed

Lines changed: 140 additions & 0 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1003UnitTests.cs

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,142 @@ public void TestMethod()
976976
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
977977
}
978978

979+
/// <summary>
980+
/// Verifies that colon in a ternary operator triggers SA1003.
981+
/// </summary>
982+
/// <param name="postfixOperator">The postfix operator to verify.</param>
983+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
984+
[Theory]
985+
[InlineData("++")]
986+
[InlineData("--")]
987+
public async Task TestTernaryFollowedByColonAsync(string postfixOperator)
988+
{
989+
var testCode = $@"public class TestClass
990+
{{
991+
public void TestMethod()
992+
{{
993+
int x = 0;
994+
var y1 = x > 0 ? x{postfixOperator}:x{postfixOperator};
995+
var y2 = x > 0 ? x{postfixOperator} :x{postfixOperator};
996+
var y3 = x > 0 ? x{postfixOperator}: x{postfixOperator};
997+
var y4 = x > 0 ? x{postfixOperator} : x{postfixOperator};
998+
}}
999+
}}
1000+
";
1001+
var fixedCode = $@"public class TestClass
1002+
{{
1003+
public void TestMethod()
1004+
{{
1005+
int x = 0;
1006+
var y1 = x > 0 ? x{postfixOperator} : x{postfixOperator};
1007+
var y2 = x > 0 ? x{postfixOperator} : x{postfixOperator};
1008+
var y3 = x > 0 ? x{postfixOperator} : x{postfixOperator};
1009+
var y4 = x > 0 ? x{postfixOperator} : x{postfixOperator};
1010+
}}
1011+
}}
1012+
";
1013+
1014+
DiagnosticResult[] expected =
1015+
{
1016+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(6, 27, 6, 29).WithArguments(postfixOperator),
1017+
Diagnostic(DescriptorPrecededByWhitespace).WithSpan(6, 29, 6, 30).WithArguments(":"),
1018+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(6, 29, 6, 30).WithArguments(":"),
1019+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(7, 30, 7, 31).WithArguments(":"),
1020+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(8, 27, 8, 29).WithArguments(postfixOperator),
1021+
Diagnostic(DescriptorPrecededByWhitespace).WithSpan(8, 29, 8, 30).WithArguments(":"),
1022+
};
1023+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1024+
}
1025+
1026+
/// <summary>
1027+
/// Verifies that colon in a ternary operator triggers SA1003.
1028+
/// </summary>
1029+
/// <param name="prefixOperator">The prefix operator to verify.</param>
1030+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
1031+
[Theory]
1032+
[InlineData("++")]
1033+
[InlineData("--")]
1034+
public async Task TestTernaryPrecededByColonAsync(string prefixOperator)
1035+
{
1036+
var testCode = $@"public class TestClass
1037+
{{
1038+
public void TestMethod()
1039+
{{
1040+
int x = 0;
1041+
var y1 = x > 0 ? {prefixOperator}x:{prefixOperator}x;
1042+
var y2 = x > 0 ? {prefixOperator}x :{prefixOperator}x;
1043+
var y3 = x > 0 ? {prefixOperator}x: {prefixOperator}x;
1044+
var y4 = x > 0 ? {prefixOperator}x : {prefixOperator}x;
1045+
}}
1046+
}}
1047+
";
1048+
var fixedCode = $@"public class TestClass
1049+
{{
1050+
public void TestMethod()
1051+
{{
1052+
int x = 0;
1053+
var y1 = x > 0 ? {prefixOperator}x : {prefixOperator}x;
1054+
var y2 = x > 0 ? {prefixOperator}x : {prefixOperator}x;
1055+
var y3 = x > 0 ? {prefixOperator}x : {prefixOperator}x;
1056+
var y4 = x > 0 ? {prefixOperator}x : {prefixOperator}x;
1057+
}}
1058+
}}
1059+
";
1060+
1061+
DiagnosticResult[] expected =
1062+
{
1063+
Diagnostic(DescriptorPrecededByWhitespace).WithSpan(6, 29, 6, 30).WithArguments(":"),
1064+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(6, 29, 6, 30).WithArguments(":"),
1065+
Diagnostic(DescriptorFollowedByWhitespace).WithSpan(7, 30, 7, 31).WithArguments(":"),
1066+
Diagnostic(DescriptorPrecededByWhitespace).WithSpan(8, 29, 8, 30).WithArguments(":"),
1067+
};
1068+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1069+
}
1070+
1071+
/// <summary>
1072+
/// Verifies that interpolated string format triggers SA1003, and does not require a preceding space.
1073+
/// </summary>
1074+
/// <param name="postfixOperator">The postfix operator to verify.</param>
1075+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
1076+
[Theory]
1077+
[InlineData("++")]
1078+
[InlineData("--")]
1079+
[WorkItem(3073, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3073")]
1080+
public async Task TestInterpolatedStringFormatAsync(string postfixOperator)
1081+
{
1082+
var testCode = $@"public class TestClass
1083+
{{
1084+
public void TestMethod()
1085+
{{
1086+
int x = 0;
1087+
var y1 = $""{{x{postfixOperator}:N}}"";
1088+
var y2 = $""{{x{postfixOperator} :N}}"";
1089+
var y3 = $""{{x{postfixOperator}: N}}"";
1090+
var y4 = $""{{x{postfixOperator} : N}}"";
1091+
}}
1092+
}}
1093+
";
1094+
var fixedCode = $@"public class TestClass
1095+
{{
1096+
public void TestMethod()
1097+
{{
1098+
int x = 0;
1099+
var y1 = $""{{x{postfixOperator}:N}}"";
1100+
var y2 = $""{{x{postfixOperator}:N}}"";
1101+
var y3 = $""{{x{postfixOperator}: N}}"";
1102+
var y4 = $""{{x{postfixOperator}: N}}"";
1103+
}}
1104+
}}
1105+
";
1106+
1107+
DiagnosticResult[] expected =
1108+
{
1109+
Diagnostic(DescriptorNotFollowedByWhitespace).WithSpan(7, 22, 7, 24).WithArguments(postfixOperator),
1110+
Diagnostic(DescriptorNotFollowedByWhitespace).WithSpan(9, 22, 9, 24).WithArguments(postfixOperator),
1111+
};
1112+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
1113+
}
1114+
9791115
/// <summary>
9801116
/// Verifies that spacing errors in conditional directives are fixed correctly. This is a regression test for
9811117
/// DotNetAnalyzers/StyleCopAnalyzers#1831.

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,10 @@ private static void HandlePostfixUnaryExpression(SyntaxNodeAnalysisContext conte
312312
mustHaveTrailingWhitespace = !(followingToken.Parent is InterpolationSyntax);
313313
break;
314314

315+
case SyntaxKind.ColonToken:
316+
mustHaveTrailingWhitespace = !(followingToken.Parent is InterpolationFormatClauseSyntax);
317+
break;
318+
315319
default:
316320
mustHaveTrailingWhitespace = true;
317321
break;

0 commit comments

Comments
 (0)