diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorTagHelperContextDiscoveryPhase.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorTagHelperContextDiscoveryPhase.cs index 7d458653948..7957b1a66dc 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorTagHelperContextDiscoveryPhase.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/DefaultRazorTagHelperContextDiscoveryPhase.cs @@ -53,22 +53,25 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument) visitor = new TagHelperDirectiveVisitor(descriptors, matches); } - if (codeDocument.GetImportSyntaxTrees() is { IsDefault: false } imports) + using (visitor) { - foreach (var import in imports) + if (codeDocument.GetImportSyntaxTrees() is { IsDefault: false } imports) { - visitor.Visit(import); + foreach (var import in imports) + { + visitor.Visit(import); + } } - } - visitor.Visit(syntaxTree); + visitor.Visit(syntaxTree); - // This will always be null for a component document. - var tagHelperPrefix = visitor.TagHelperPrefix; + // This will always be null for a component document. + var tagHelperPrefix = visitor.TagHelperPrefix; - var context = TagHelperDocumentContext.Create(tagHelperPrefix, matches.ToImmutableArray()); - codeDocument.SetTagHelperContext(context); - codeDocument.SetPreTagHelperSyntaxTree(syntaxTree); + var context = TagHelperDocumentContext.Create(tagHelperPrefix, matches.ToImmutableArray()); + codeDocument.SetTagHelperContext(context); + codeDocument.SetPreTagHelperSyntaxTree(syntaxTree); + } } private static bool MatchesDirective(TagHelperDescriptor descriptor, string typePattern, string assemblyName) @@ -106,25 +109,27 @@ private static ReadOnlySpan RemoveGlobalPrefix(in ReadOnlySpan span) return span; } - internal abstract class DirectiveVisitor(HashSet matches) : SyntaxWalker + internal abstract class DirectiveVisitor(HashSet matches) : SyntaxWalker, IDisposable { protected readonly HashSet Matches = matches; public abstract string TagHelperPrefix { get; } public abstract void Visit(RazorSyntaxTree tree); + + public abstract void Dispose(); } internal sealed class TagHelperDirectiveVisitor : DirectiveVisitor { - private readonly List _tagHelpers; + private List _tagHelpers; private string _tagHelperPrefix; public TagHelperDirectiveVisitor(IReadOnlyList tagHelpers, HashSet matches) : base(matches) { // We don't want to consider components in a view document. - _tagHelpers = new(); + _tagHelpers = ListPool.Default.Get(); for (var i = 0; i < tagHelpers.Count; i++) { @@ -229,11 +234,20 @@ private static bool AssemblyContainsTagHelpers(string assemblyName, List.Default.Return(_tagHelpers); + _tagHelpers = null; + } + } } internal sealed class ComponentDirectiveVisitor : DirectiveVisitor { - private readonly ImmutableArray _notFullyQualifiedComponents; + private List _notFullyQualifiedComponents; private readonly string _filePath; private RazorSourceDocument _source; @@ -242,7 +256,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList(capacity: tagHelpers.Count); + _notFullyQualifiedComponents = ListPool.Default.Get(); for (var i = 0; i < tagHelpers.Count; i++) { @@ -260,7 +274,7 @@ public ComponentDirectiveVisitor(string filePath, IReadOnlyList.Default.Return(_notFullyQualifiedComponents); + _notFullyQualifiedComponents = null; + } + } } }