Skip to content

Commit a8dcf4a

Browse files
Improves tag helper span computation performance
Utilizes a pooled array builder when computing tag helper spans, reducing memory allocations. Avoids calling into the legacy `GetTagHelperSpans` method, further improving performance by avoiding allocations of `TagHelperSpanVisitor`. In addition, returns `SourceSpans` rather than `TagHelperSpanInternal` since tooling doesn't use the tag helper binding info.
1 parent d51064b commit a8dcf4a

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.CachedData.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Runtime.CompilerServices;
88
using System.Threading;
99
using Microsoft.AspNetCore.Razor.Language.Legacy;
10+
using Microsoft.AspNetCore.Razor.Language.Syntax;
11+
using Microsoft.AspNetCore.Razor.PooledObjects;
1012
using Microsoft.CodeAnalysis;
1113
using Microsoft.CodeAnalysis.CSharp;
1214
using Microsoft.CodeAnalysis.Razor.Threading;
@@ -40,7 +42,7 @@ private sealed class CachedData(RazorCodeDocument codeDocument)
4042
private readonly SemaphoreSlim _stateLock = new(initialCount: 1);
4143
private SyntaxTree? _syntaxTree;
4244
private ImmutableArray<ClassifiedSpanInternal>? _classifiedSpans;
43-
private ImmutableArray<TagHelperSpanInternal>? _tagHelperSpans;
45+
private ImmutableArray<SourceSpan>? _tagHelperSpans;
4446

4547
public SyntaxTree GetOrParseCSharpSyntaxTree(CancellationToken cancellationToken)
4648
{
@@ -74,7 +76,7 @@ public ImmutableArray<ClassifiedSpanInternal> GetOrComputeClassifiedSpans(Cancel
7476
}
7577
}
7678

77-
public ImmutableArray<TagHelperSpanInternal> GetOrComputeTagHelperSpans(CancellationToken cancellationToken)
79+
public ImmutableArray<SourceSpan> GetOrComputeTagHelperSpans(CancellationToken cancellationToken)
7880
{
7981
if (_tagHelperSpans is { } tagHelperSpans)
8082
{
@@ -83,7 +85,25 @@ public ImmutableArray<TagHelperSpanInternal> GetOrComputeTagHelperSpans(Cancella
8385

8486
using (_stateLock.DisposableWait(cancellationToken))
8587
{
86-
return _tagHelperSpans ??= _codeDocument.GetRequiredSyntaxTree().GetTagHelperSpans();
88+
return _tagHelperSpans ??= ComputeTagHelperSpans(_codeDocument.GetRequiredSyntaxTree());
89+
}
90+
91+
static ImmutableArray<SourceSpan> ComputeTagHelperSpans(RazorSyntaxTree syntaxTree)
92+
{
93+
using var builder = new PooledArrayBuilder<SourceSpan>();
94+
95+
foreach (var node in syntaxTree.Root.DescendantNodes())
96+
{
97+
if (node is not MarkupTagHelperElementSyntax tagHelperElement ||
98+
tagHelperElement.TagHelperInfo is null)
99+
{
100+
continue;
101+
}
102+
103+
builder.Add(tagHelperElement.GetSourceSpan(syntaxTree.Source));
104+
}
105+
106+
return builder.ToImmutableAndClear();
87107
}
88108
}
89109

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/RazorCodeDocumentExtensions.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,12 @@ public static RazorLanguageKind GetLanguageKind(this RazorCodeDocument codeDocum
153153
private static ImmutableArray<ClassifiedSpanInternal> GetClassifiedSpans(RazorCodeDocument document)
154154
=> GetCachedData(document).GetOrComputeClassifiedSpans(CancellationToken.None);
155155

156-
private static ImmutableArray<TagHelperSpanInternal> GetTagHelperSpans(RazorCodeDocument document)
156+
private static ImmutableArray<SourceSpan> GetTagHelperSpans(RazorCodeDocument document)
157157
=> GetCachedData(document).GetOrComputeTagHelperSpans(CancellationToken.None);
158158

159159
private static RazorLanguageKind GetLanguageKindCore(
160160
ImmutableArray<ClassifiedSpanInternal> classifiedSpans,
161-
ImmutableArray<TagHelperSpanInternal> tagHelperSpans,
161+
ImmutableArray<SourceSpan> tagHelperSpans,
162162
int hostDocumentIndex,
163163
int hostDocumentLength,
164164
bool rightAssociative)
@@ -206,10 +206,8 @@ private static RazorLanguageKind GetLanguageKindCore(
206206
}
207207
}
208208

209-
foreach (var tagHelperSpan in tagHelperSpans)
209+
foreach (var span in tagHelperSpans)
210210
{
211-
var span = tagHelperSpan.Span;
212-
213211
if (span.AbsoluteIndex <= hostDocumentIndex)
214212
{
215213
var end = span.AbsoluteIndex + span.Length;

0 commit comments

Comments
 (0)