Skip to content

Commit 536040e

Browse files
committed
Modify SA1100 code fix to operate on BaseExpressionSyntax
Roslyn 2+ didn't recognize our special rewrite where we replaced the text of the 'base' keyword with 'this'. The new method is slightly slower but ensures we properly apply code fixes.
1 parent 1e3bffc commit 536040e

1 file changed

Lines changed: 10 additions & 13 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1100CodeFixProvider.cs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace StyleCop.Analyzers.ReadabilityRules
1313
using Microsoft.CodeAnalysis.CodeActions;
1414
using Microsoft.CodeAnalysis.CodeFixes;
1515
using Microsoft.CodeAnalysis.CSharp;
16+
using Microsoft.CodeAnalysis.CSharp.Syntax;
1617
using Microsoft.CodeAnalysis.Text;
1718

1819
/// <summary>
@@ -51,26 +52,22 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
5152
return SpecializedTasks.CompletedTask;
5253
}
5354

54-
private static SyntaxToken GetBaseKeywordToken(SyntaxNode root, TextSpan sourceSpan)
55+
private static BaseExpressionSyntax GetBaseExpressionNode(SyntaxNode root, TextSpan sourceSpan)
5556
{
56-
return root.FindToken(sourceSpan.Start);
57+
return (BaseExpressionSyntax)root.FindToken(sourceSpan.Start).Parent;
5758
}
5859

59-
private static SyntaxToken RewriteBaseAsThis(SyntaxToken token)
60+
private static ThisExpressionSyntax RewriteBaseAsThis(BaseExpressionSyntax token)
6061
{
61-
// By creating a `base` token with the literal text `this`, we can replace a token with the code fix instead
62-
// of replacing an entire syntax node. This improves the performance of the code fix, but the resulting tree
63-
// could be considered in a bad state. However, this is not a problem under any interpretation of the result
64-
// because SA1100 is only reported in cases where `base.` and `this.` have the same meaning.
65-
return SyntaxFactory.Token(token.LeadingTrivia, SyntaxKind.BaseKeyword, "this", "this", token.TrailingTrivia);
62+
return SyntaxFactory.ThisExpression(SyntaxFactory.Token(SyntaxKind.ThisKeyword).WithTriviaFrom(token.Token));
6663
}
6764

6865
private static async Task<Document> GetTransformedDocumentAsync(Document document, Diagnostic diagnostic, CancellationToken cancellationToken)
6966
{
7067
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
71-
var token = GetBaseKeywordToken(root, diagnostic.Location.SourceSpan);
68+
var node = GetBaseExpressionNode(root, diagnostic.Location.SourceSpan);
7269

73-
SyntaxNode newSyntaxRoot = root.ReplaceToken(token, RewriteBaseAsThis(token));
70+
SyntaxNode newSyntaxRoot = root.ReplaceNode(node, RewriteBaseAsThis(node));
7471
return document.WithSyntaxRoot(newSyntaxRoot);
7572
}
7673

@@ -91,13 +88,13 @@ protected override async Task<SyntaxNode> FixAllInDocumentAsync(FixAllContext fi
9188

9289
var syntaxRoot = await document.GetSyntaxRootAsync().ConfigureAwait(false);
9390

94-
List<SyntaxToken> tokensToReplace = new List<SyntaxToken>(diagnostics.Length);
91+
List<BaseExpressionSyntax> nodesToReplace = new List<BaseExpressionSyntax>(diagnostics.Length);
9592
foreach (var diagnostic in diagnostics)
9693
{
97-
tokensToReplace.Add(GetBaseKeywordToken(syntaxRoot, diagnostic.Location.SourceSpan));
94+
nodesToReplace.Add(GetBaseExpressionNode(syntaxRoot, diagnostic.Location.SourceSpan));
9895
}
9996

100-
return syntaxRoot.ReplaceTokens(tokensToReplace, (originalToken, rewrittenToken) => RewriteBaseAsThis(rewrittenToken));
97+
return syntaxRoot.ReplaceNodes(nodesToReplace, (originalNode, rewrittenNode) => RewriteBaseAsThis(rewrittenNode));
10198
}
10299
}
103100
}

0 commit comments

Comments
 (0)