Skip to content

Commit f1bf53b

Browse files
committed
Merge pull request #1835 from sharwell/fix-1831
Fix SA1003 code fix's handling of trivia
2 parents 573b29f + 362bb79 commit f1bf53b

2 files changed

Lines changed: 62 additions & 1 deletion

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/SpacingRules/SA1003CodeFixProvider.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,37 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
5959
var syntaxRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
6060
var replacements = new Dictionary<SyntaxToken, SyntaxToken>();
6161

62-
var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start);
62+
var token = syntaxRoot.FindToken(diagnostic.Location.SourceSpan.Start, findInsideTrivia: true);
6363
SyntaxToken followingToken;
6464

6565
switch (diagnostic.Properties[SA1003SymbolsMustBeSpacedCorrectly.CodeFixAction])
6666
{
6767
case SA1003SymbolsMustBeSpacedCorrectly.InsertBeforeTag:
6868
replacements[token] = token.WithLeadingTrivia(token.LeadingTrivia.Add(SyntaxFactory.Space));
6969
break;
70+
7071
case SA1003SymbolsMustBeSpacedCorrectly.InsertAfterTag:
7172
replacements[token] = token.WithTrailingTrivia(token.TrailingTrivia.Insert(0, SyntaxFactory.Space));
7273
break;
74+
7375
case SA1003SymbolsMustBeSpacedCorrectly.RemoveBeforeTag:
7476
var precedingToken = token.GetPreviousToken();
7577
replacements[precedingToken] = precedingToken.WithTrailingTrivia(precedingToken.TrailingTrivia.WithoutTrailingWhitespace());
7678
replacements[token] = token.WithLeadingTrivia(token.LeadingTrivia.WithoutLeadingWhitespace());
7779
break;
80+
7881
case SA1003SymbolsMustBeSpacedCorrectly.RemoveAfterTag:
7982
followingToken = token.GetNextToken();
8083
replacements[token] = token.WithTrailingTrivia(token.TrailingTrivia.WithoutLeadingWhitespace());
8184
replacements[followingToken] = followingToken.WithLeadingTrivia(followingToken.LeadingTrivia.WithoutLeadingWhitespace());
8285
break;
86+
8387
case SA1003SymbolsMustBeSpacedCorrectly.RemoveEndOfLineTag:
8488
followingToken = token.GetNextToken();
8589
replacements[token] = token.WithTrailingTrivia(token.TrailingTrivia.WithoutTrailingWhitespace());
8690
replacements[followingToken] = followingToken.WithLeadingTrivia(followingToken.LeadingTrivia.WithoutLeadingWhitespace());
8791
break;
92+
8893
case SA1003SymbolsMustBeSpacedCorrectly.RemoveEndOfLineWithTrailingSpaceTag:
8994
followingToken = token.GetNextToken();
9095
replacements[token] = token.WithTrailingTrivia(token.TrailingTrivia.WithoutTrailingWhitespace().Add(SyntaxFactory.Space));

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,62 @@ public void TestMethod()
877877
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
878878
}
879879

880+
/// <summary>
881+
/// Verifies that spacing errors in conditional directives are fixed correctly. This is a regression test for
882+
/// DotNetAnalyzers/StyleCopAnalyzers#1831.
883+
/// </summary>
884+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
885+
[Fact]
886+
public async Task TestConditionalDirectivesCorrectlyFixedAsync()
887+
{
888+
var testCode = @"class Program
889+
{
890+
static int Main(string[] args)
891+
{
892+
#if! NOT
893+
return 1;
894+
#endif
895+
896+
#if! NOT&&! Y
897+
return 1;
898+
#endif
899+
}
900+
}
901+
";
902+
var fixedCode = @"class Program
903+
{
904+
static int Main(string[] args)
905+
{
906+
#if !NOT
907+
return 1;
908+
#endif
909+
910+
#if !NOT && !Y
911+
return 1;
912+
#endif
913+
}
914+
}
915+
";
916+
917+
DiagnosticResult[] expected =
918+
{
919+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(5, 4).WithArguments("!"),
920+
this.CSharpDiagnostic(DescriptorNotFollowedByWhitespace).WithLocation(5, 4).WithArguments("!"),
921+
922+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(9, 4).WithArguments("!"),
923+
this.CSharpDiagnostic(DescriptorNotFollowedByWhitespace).WithLocation(9, 4).WithArguments("!"),
924+
925+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(9, 9).WithArguments("&&"),
926+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(9, 9).WithArguments("&&"),
927+
928+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(9, 11).WithArguments("!"),
929+
this.CSharpDiagnostic(DescriptorNotFollowedByWhitespace).WithLocation(9, 11).WithArguments("!"),
930+
};
931+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
932+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
933+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
934+
}
935+
880936
/// <inheritdoc/>
881937
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
882938
{

0 commit comments

Comments
 (0)