Skip to content

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)