Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ItemCollection from TagHelperDescriptorProviderContext #10720

Merged
merged 8 commits into from
Aug 12, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;
using Xunit;
using static Microsoft.AspNetCore.Razor.Language.CommonMetadata;

Expand All @@ -28,8 +27,7 @@ public class StringParameterViewComponent

var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
var context = new TagHelperDescriptorProviderContext(compilation);

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;
using Xunit;
using static Microsoft.AspNetCore.Razor.Language.CommonMetadata;

Expand All @@ -28,8 +27,7 @@ public class StringParameterViewComponent

var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
var context = new TagHelperDescriptorProviderContext(compilation);

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Razor;
using Xunit;
using static Microsoft.AspNetCore.Razor.Language.CommonMetadata;

Expand All @@ -28,8 +27,7 @@ public class StringParameterViewComponent

var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code));

var context = TagHelperDescriptorProviderContext.Create();
context.SetCompilation(compilation);
var context = new TagHelperDescriptorProviderContext(compilation);

var provider = new ViewComponentTagHelperDescriptorProvider()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,22 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Razor;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.AspNetCore.Razor.Language.Components;
using Microsoft.AspNetCore.Razor.PooledObjects;
using static Microsoft.AspNetCore.Razor.Language.CommonMetadata;

namespace Microsoft.CodeAnalysis.Razor;

internal class BindTagHelperDescriptorProvider : ITagHelperDescriptorProvider
// Run after the component tag helper provider, because we need to see the results.
internal sealed class BindTagHelperDescriptorProvider() : TagHelperDescriptorProviderBase(order: 1000)
{
private static TagHelperDescriptor? s_fallbackBindTagHelper;
private static readonly Lazy<TagHelperDescriptor> s_fallbackBindTagHelper = new(CreateFallbackBindTagHelper);

// Run after the component tag helper provider, because we need to see the results.
public int Order { get; set; } = 1000;

public RazorEngine? Engine { get; set; }

public void Execute(TagHelperDescriptorProviderContext context)
public override void Execute(TagHelperDescriptorProviderContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
ArgHelper.ThrowIfNull(context);

// This provider returns tag helper information for 'bind' which doesn't necessarily
// map to any real component. Bind behaviors more like a macro, which can map a single LValue to
Expand Down Expand Up @@ -91,11 +85,7 @@ public void Execute(TagHelperDescriptorProviderContext context)
// we have. Case #4 is data-driven based on component definitions.
//
// We provide a good set of attributes that map to the HTML dom. This set is user extensible.
var compilation = context.GetCompilation();
if (compilation == null)
{
return;
}
var compilation = context.Compilation;

var bindMethods = compilation.GetTypeByMetadataName(ComponentsApi.BindConverter.FullTypeName);
if (bindMethods == null)
Expand All @@ -105,14 +95,13 @@ public void Execute(TagHelperDescriptorProviderContext context)
return;
}

var targetSymbol = context.Items.GetTargetSymbol();
if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, bindMethods.ContainingAssembly))
if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, bindMethods.ContainingAssembly))
{
return;
}

// Tag Helper definition for case #1. This is the most general case.
context.Results.Add(GetOrCreateFallbackBindTagHelper());
context.Results.Add(s_fallbackBindTagHelper.Value);

var bindElementAttribute = compilation.GetTypeByMetadataName(ComponentsApi.BindElementAttribute.FullTypeName);
var bindInputElementAttribute = compilation.GetTypeByMetadataName(ComponentsApi.BindInputElementAttribute.FullTypeName);
Expand All @@ -129,112 +118,107 @@ public void Execute(TagHelperDescriptorProviderContext context)
collector.Collect(context);
}

private static TagHelperDescriptor GetOrCreateFallbackBindTagHelper()
private static TagHelperDescriptor CreateFallbackBindTagHelper()
{
return s_fallbackBindTagHelper ??= CreateFallbackBindTagHelper();

static TagHelperDescriptor CreateFallbackBindTagHelper()
using var _ = TagHelperDescriptorBuilder.GetPooledInstance(
ComponentMetadata.Bind.TagHelperKind, "Bind", ComponentsApi.AssemblyName,
out var builder);

builder.CaseSensitive = true;
builder.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback);

builder.SetMetadata(
SpecialKind(ComponentMetadata.Bind.TagHelperKind),
MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly),
RuntimeName(ComponentMetadata.Bind.RuntimeName),
MakeTrue(ComponentMetadata.Bind.FallbackKey),
TypeName("Microsoft.AspNetCore.Components.Bind"),
TypeNamespace("Microsoft.AspNetCore.Components"),
TypeNameIdentifier("Bind"));

builder.TagMatchingRule(rule =>
{
using var _ = TagHelperDescriptorBuilder.GetPooledInstance(
ComponentMetadata.Bind.TagHelperKind, "Bind", ComponentsApi.AssemblyName,
out var builder);

builder.CaseSensitive = true;
builder.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback);

builder.SetMetadata(
SpecialKind(ComponentMetadata.Bind.TagHelperKind),
MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly),
RuntimeName(ComponentMetadata.Bind.RuntimeName),
MakeTrue(ComponentMetadata.Bind.FallbackKey),
TypeName("Microsoft.AspNetCore.Components.Bind"),
TypeNamespace("Microsoft.AspNetCore.Components"),
TypeNameIdentifier("Bind"));

builder.TagMatchingRule(rule =>
rule.TagName = "*";
rule.Attribute(attribute =>
{
rule.TagName = "*";
rule.Attribute(attribute =>
{
attribute.Name = "@bind-";
attribute.NameComparisonMode = RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch;
attribute.SetMetadata(Attributes.IsDirectiveAttribute);
});
attribute.Name = "@bind-";
attribute.NameComparisonMode = RequiredAttributeDescriptor.NameComparisonMode.PrefixMatch;
attribute.SetMetadata(Attributes.IsDirectiveAttribute);
});
});

builder.BindAttribute(attribute =>
{
attribute.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback);
builder.BindAttribute(attribute =>
{
attribute.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback);

var attributeName = "@bind-...";
attribute.Name = attributeName;
attribute.AsDictionary("@bind-", typeof(object).FullName);
var attributeName = "@bind-...";
attribute.Name = attributeName;
attribute.AsDictionary("@bind-", typeof(object).FullName);

attribute.SetMetadata(
PropertyName("Bind"),
IsDirectiveAttribute);
attribute.SetMetadata(
PropertyName("Bind"),
IsDirectiveAttribute);

attribute.TypeName = "System.Collections.Generic.Dictionary<string, object>";
attribute.TypeName = "System.Collections.Generic.Dictionary<string, object>";

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "format";
parameter.TypeName = typeof(string).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback_Format);
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "format";
parameter.TypeName = typeof(string).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback_Format);

parameter.SetMetadata(Parameters.Format);
});
parameter.SetMetadata(Parameters.Format);
});

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "event";
parameter.TypeName = typeof(string).FullName;
parameter.SetDocumentation(
DocumentationDescriptor.From(
DocumentationId.BindTagHelper_Fallback_Event, attributeName));
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "event";
parameter.TypeName = typeof(string).FullName;
parameter.SetDocumentation(
DocumentationDescriptor.From(
DocumentationId.BindTagHelper_Fallback_Event, attributeName));

parameter.SetMetadata(Parameters.Event);
});
parameter.SetMetadata(Parameters.Event);
});

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "culture";
parameter.TypeName = typeof(CultureInfo).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture);
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "culture";
parameter.TypeName = typeof(CultureInfo).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture);

parameter.SetMetadata(Parameters.Culture);
});
parameter.SetMetadata(Parameters.Culture);
});

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "get";
parameter.TypeName = typeof(object).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get);
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "get";
parameter.TypeName = typeof(object).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get);

parameter.SetMetadata(Parameters.Get);
});
parameter.SetMetadata(Parameters.Get);
});

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "set";
parameter.TypeName = typeof(Delegate).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set);
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "set";
parameter.TypeName = typeof(Delegate).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set);

parameter.SetMetadata(Parameters.Set);
});
parameter.SetMetadata(Parameters.Set);
});

attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "after";
parameter.TypeName = typeof(Delegate).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After);
attribute.BindAttributeParameter(parameter =>
{
parameter.Name = "after";
parameter.TypeName = typeof(Delegate).FullName;
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After);

parameter.SetMetadata(Parameters.After);
});
parameter.SetMetadata(Parameters.After);
});
});

return builder.Build();
}
return builder.Build();
}

private class Collector(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public sealed class CompilationTagHelperFeature : RazorEngineFeatureBase, ITagHe

public IReadOnlyList<TagHelperDescriptor> GetDescriptors()
{
var results = new List<TagHelperDescriptor>();

var context = TagHelperDescriptorProviderContext.Create(results);
var compilation = CSharpCompilation.Create("__TagHelpers", references: _referenceFeature.References);
if (IsValidCompilation(compilation))
if (!IsValidCompilation(compilation))
{
context.SetCompilation(compilation);
return [];
}

var results = new List<TagHelperDescriptor>();
var context = new TagHelperDescriptorProviderContext(compilation, results);

for (var i = 0; i < _providers.Length; i++)
{
_providers[i].Execute(context);
Expand Down
Loading
Loading