Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis;

namespace Microsoft.AspNetCore.Razor.Language;

public abstract partial class TagHelperCollector<T>
where T : TagHelperCollector<T>
{
private class Cache
private sealed class Cache(IAssemblySymbol assembly)
{
private const int IncludeDocumentation = 1 << 0;
private const int ExcludeHidden = 1 << 1;
Expand All @@ -19,6 +23,8 @@ private class Cache

private readonly TagHelperDescriptor[]?[] _tagHelpers = new TagHelperDescriptor[CacheSize][];

public bool MightContainTagHelpers { get; } = CalculateMightContainTagHelpers(assembly);

public bool TryGet(bool includeDocumentation, bool excludeHidden, [NotNullWhen(true)] out TagHelperDescriptor[]? tagHelpers)
{
var index = CalculateIndex(includeDocumentation, excludeHidden);
Expand Down Expand Up @@ -50,5 +56,15 @@ private static int CalculateIndex(bool includeDocumentation, bool excludeHidden)

return index;
}

private static bool CalculateMightContainTagHelpers(IAssemblySymbol assembly)
{
// In order to contain tag helpers, components, or anything else we might want to find,
// the assembly must start with "Microsoft.AspNetCore." or reference an assembly that
// starts with "Microsoft.AspNetCore."
return assembly.Name.StartsWith("Microsoft.AspNetCore.", StringComparison.Ordinal) ||
assembly.Modules.First().ReferencedAssemblies.Any(
a => a.Name.StartsWith("Microsoft.AspNetCore.", StringComparison.Ordinal));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Razor.PooledObjects;
using Microsoft.CodeAnalysis;
Expand All @@ -25,17 +23,6 @@ protected TagHelperCollector(Compilation compilation, ISymbol? targetSymbol)
_targetSymbol = targetSymbol;
}

private static bool MightContainTagHelpers(IAssemblySymbol assembly)
{
// In order to contain tag helpers, components, or anything else we might want to find,
// the assembly must start with "Microsoft.AspNetCore." or reference an assembly that
// starts with "Microsoft.AspNetCore."

return assembly.Name.StartsWith("Microsoft.AspNetCore.", StringComparison.Ordinal) ||
assembly.Modules.First().ReferencedAssemblies.Any(
a => a.Name.StartsWith("Microsoft.AspNetCore.", StringComparison.Ordinal));
}

protected abstract void Collect(ISymbol symbol, ICollection<TagHelperDescriptor> results);

public void Collect(TagHelperDescriptorProviderContext context)
Expand All @@ -52,17 +39,17 @@ public void Collect(TagHelperDescriptorProviderContext context)
{
if (_compilation.GetAssemblyOrModuleSymbol(reference) is IAssemblySymbol assembly)
{
if (!MightContainTagHelpers(assembly))
{
continue;
}

// Check to see if we already have tag helpers cached for this assembly
// and use the cached versions if we do. Roslyn shares PE assembly symbols
// across compilations, so this ensures that we don't produce new tag helpers
// for the same assemblies over and over again.

var cache = s_perAssemblyCaches.GetOrCreateValue(assembly);
var cache = s_perAssemblyCaches.GetValue(assembly, static assembly => new Cache(assembly));

if (!cache.MightContainTagHelpers)
{
continue;
}

var includeDocumentation = context.IncludeDocumentation;
var excludeHidden = context.ExcludeHidden;
Expand Down