Skip to content

Commit 7919bb6

Browse files
committed
Merge pull request #2139 from vweijsters/fix-2069
Fixed SA1119CodeFix for preprocessor directives
2 parents b638f62 + 8a764ca commit 7919bb6

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/MaintainabilityRules/SA1119CodeFixProvider.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,18 @@ private static SyntaxNode GetReplacement(ParenthesizedExpressionSyntax oldNode)
6767
var leadingTrivia = SyntaxFactory.TriviaList(oldNode.OpenParenToken.GetAllTrivia().Concat(oldNode.Expression.GetLeadingTrivia()));
6868
var trailingTrivia = oldNode.Expression.GetTrailingTrivia().AddRange(oldNode.CloseParenToken.GetAllTrivia());
6969

70+
// Workaround for Roslyn not handling elastic markers for directive trivia correctly.
71+
if (!leadingTrivia.Any())
72+
{
73+
var previousToken = oldNode.OpenParenToken.GetPreviousToken();
74+
if (TriviaHelper.IndexOfTrailingWhitespace(previousToken.TrailingTrivia) == -1)
75+
{
76+
leadingTrivia = SyntaxFactory.TriviaList(SyntaxFactory.Space);
77+
}
78+
}
79+
7080
return oldNode.Expression
71-
.WithLeadingTrivia(leadingTrivia.Any() ? leadingTrivia : SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker))
81+
.WithLeadingTrivia(leadingTrivia)
7282
.WithTrailingTrivia(trailingTrivia.Any() ? trailingTrivia : SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker));
7383
}
7484

StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/SA1119UnitTests.cs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,60 @@ public void Bar()
14011401
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
14021402
}
14031403

1404+
/// <summary>
1405+
/// Verifies that a preprocessor statement with unnecessary parenthesis is handled correctly.
1406+
/// Regression test for #2069
1407+
/// </summary>
1408+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
1409+
[Fact]
1410+
public async Task VerifyThatPreprocessorStatementIsHandledCorrectlyAsync()
1411+
{
1412+
string testCode = @"
1413+
public class Program
1414+
{
1415+
public static void Main(string[] args)
1416+
{
1417+
#if(DEBUG)
1418+
1419+
#endif
1420+
1421+
#if (DEBUG)
1422+
1423+
#endif
1424+
}
1425+
}
1426+
";
1427+
1428+
string fixedCode = @"
1429+
public class Program
1430+
{
1431+
public static void Main(string[] args)
1432+
{
1433+
#if DEBUG
1434+
1435+
#endif
1436+
1437+
#if DEBUG
1438+
1439+
#endif
1440+
}
1441+
}
1442+
";
1443+
DiagnosticResult[] expected =
1444+
{
1445+
this.CSharpDiagnostic(DiagnosticId).WithLocation(6, 4),
1446+
this.CSharpDiagnostic(ParenthesesDiagnosticId).WithLocation(6, 4),
1447+
this.CSharpDiagnostic(ParenthesesDiagnosticId).WithLocation(6, 10),
1448+
this.CSharpDiagnostic(DiagnosticId).WithLocation(10, 5),
1449+
this.CSharpDiagnostic(ParenthesesDiagnosticId).WithLocation(10, 5),
1450+
this.CSharpDiagnostic(ParenthesesDiagnosticId).WithLocation(10, 11),
1451+
};
1452+
1453+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
1454+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
1455+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
1456+
}
1457+
14041458
/// <inheritdoc/>
14051459
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
14061460
{

0 commit comments

Comments
 (0)