Skip to content
This repository was archived by the owner on Jul 12, 2022. It is now read-only.

Commit 4dd9b7f

Browse files
committed
Delay retrieving the SemanticModel element
Getting the SemanticModel instance is potentially an expensive operation. For example in the Roslyn.sln project it takes on average 3-5 seconds if it requires creating a new Compilation. This is true even when processing a single project because MSBuild will load the entire solution for such a request and hence the Compilation encompasses the entire solution. Delaying access in this manner significantly speeds up the formatting speed of documents that need no changes.
1 parent d9b2c30 commit 4dd9b7f

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

src/Microsoft.DotNet.CodeFormatting/Rules/ExplicitThisRule.cs

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,19 @@ public sealed class ExplicitThisRule : IFormattingRule
1616
{
1717
private sealed class ExplicitThisRewriter : CSharpSyntaxRewriter
1818
{
19-
private readonly SemanticModel _semanticModel;
19+
private readonly Document _document;
2020
private readonly CancellationToken _cancellationToken;
21+
private SemanticModel _semanticModel;
2122
private bool _addedAnnotations;
2223

2324
internal bool AddedAnnotations
2425
{
2526
get { return _addedAnnotations; }
2627
}
2728

28-
internal ExplicitThisRewriter(SemanticModel semanticModel, CancellationToken cancellationToken)
29+
internal ExplicitThisRewriter(Document document, CancellationToken cancellationToken)
2930
{
30-
_semanticModel = semanticModel;
31+
_document = document;
3132
_cancellationToken = cancellationToken;
3233
}
3334

@@ -37,22 +38,32 @@ public override SyntaxNode VisitMemberAccessExpression(MemberAccessExpressionSyn
3738
var name = node.Name.Identifier.ValueText;
3839
if (node.Expression != null &&
3940
node.Expression.CSharpKind() == SyntaxKind.ThisExpression &&
40-
name.StartsWith("_", StringComparison.Ordinal))
41+
name.StartsWith("_", StringComparison.Ordinal) &&
42+
IsPrivateField(node))
4143
{
42-
var symbolInfo = _semanticModel.GetSymbolInfo(node, _cancellationToken);
43-
if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Field)
44-
{
45-
var field = (IFieldSymbol)symbolInfo.Symbol;
46-
if (field.DeclaredAccessibility == Accessibility.Private)
47-
{
48-
_addedAnnotations = true;
49-
return node.WithAdditionalAnnotations(Simplifier.Annotation);
50-
}
51-
}
44+
_addedAnnotations = true;
45+
return node.WithAdditionalAnnotations(Simplifier.Annotation);
5246
}
5347

5448
return node;
5549
}
50+
51+
private bool IsPrivateField(MemberAccessExpressionSyntax memberSyntax)
52+
{
53+
if (_semanticModel == null)
54+
{
55+
_semanticModel = _document.GetSemanticModelAsync(_cancellationToken).Result;
56+
}
57+
58+
var symbolInfo = _semanticModel.GetSymbolInfo(memberSyntax, _cancellationToken);
59+
if (symbolInfo.Symbol != null && symbolInfo.Symbol.Kind == SymbolKind.Field)
60+
{
61+
var field = (IFieldSymbol)symbolInfo.Symbol;
62+
return field.DeclaredAccessibility == Accessibility.Private;
63+
}
64+
65+
return false;
66+
}
5667
}
5768

5869
public async Task<Document> ProcessAsync(Document document, CancellationToken cancellationToken)
@@ -63,8 +74,7 @@ public async Task<Document> ProcessAsync(Document document, CancellationToken ca
6374
return document;
6475
}
6576

66-
var semanticModel = await document.GetSemanticModelAsync(cancellationToken);
67-
var rewriter = new ExplicitThisRewriter(semanticModel, cancellationToken);
77+
var rewriter = new ExplicitThisRewriter(document, cancellationToken);
6878
var newNode = rewriter.Visit(syntaxNode);
6979
if (!rewriter.AddedAnnotations)
7080
{

0 commit comments

Comments
 (0)