From 53ec3abbf2f56e246cc2e445639d89dc69bb0db8 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 09:44:38 -0700 Subject: [PATCH 1/8] Merge TagHelperDescriptorProviderContext and DefaultContext --- .../TagHelperDescriptorProviderContext.cs | 46 +++++-------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index d89fde61427..f759c203f04 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -1,49 +1,27 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; namespace Microsoft.AspNetCore.Razor.Language; -public abstract class TagHelperDescriptorProviderContext +public sealed class TagHelperDescriptorProviderContext { - public virtual bool ExcludeHidden { get; set; } - - public virtual bool IncludeDocumentation { get; set; } + public bool ExcludeHidden { get; set; } + public bool IncludeDocumentation { get; set; } - public abstract ItemCollection Items { get; } + public ItemCollection Items { get; } + public ICollection Results { get; } - public abstract ICollection Results { get; } - - public static TagHelperDescriptorProviderContext Create() + private TagHelperDescriptorProviderContext(ICollection results) { - return new DefaultContext(new List()); + Results = results; + Items = []; } - public static TagHelperDescriptorProviderContext Create(ICollection results) - { - if (results == null) - { - throw new ArgumentNullException(nameof(results)); - } - - return new DefaultContext(results); - } - - private class DefaultContext : TagHelperDescriptorProviderContext - { - public DefaultContext(ICollection results) - { - Results = results; - - Items = new ItemCollection(); - } - - public override ItemCollection Items { get; } + public static TagHelperDescriptorProviderContext Create() + => new([]); - public override ICollection Results { get; } - } + public static TagHelperDescriptorProviderContext Create(ICollection results) + => new(results); } From adff92a959b6aee144c98dc9646d0f010ede43a2 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 09:47:38 -0700 Subject: [PATCH 2/8] Make Compilation a TagHelperDescriptorProviderContext property Every single `TagHelperDescriptorProviderContext` created in Razor compiler or tooling code adds a valid compilation. So, adding the compilation to the `ItemsCollection` is pure overhead and no `ITagHelperDescriptorProvider` needs to check it for null. I removed a single test that verified the behavior if a compilation was never set. Now that a compilation is required, this test is no longer needed. --- ...omponentTagHelperDescriptorProviderTest.cs | 4 +- ...omponentTagHelperDescriptorProviderTest.cs | 4 +- ...omponentTagHelperDescriptorProviderTest.cs | 4 +- .../CSharp/BindTagHelperDescriptorProvider.cs | 6 +- .../src/CSharp/CompilationTagHelperFeature.cs | 10 +- .../ComponentTagHelperDescriptorProvider.cs | 9 +- .../DefaultTagHelperDescriptorProvider.cs | 7 +- ...EventHandlerTagHelperDescriptorProvider.cs | 6 +- .../FormNameTagHelperDescriptorProvider.cs | 6 +- .../CSharp/KeyTagHelperDescriptorProvider.cs | 6 +- .../CSharp/RefTagHelperDescriptorProvider.cs | 6 +- .../RenderModeTagHelperDescriptorProvider.cs | 6 +- .../SplatTagHelperDescriptorProvider.cs | 6 +- ...lperDescriptorProviderContextExtensions.cs | 32 ------ .../TagHelperDescriptorProviderContext.cs | 14 ++- ...iewComponentTagHelperDescriptorProvider.cs | 8 +- ...iewComponentTagHelperDescriptorProvider.cs | 8 +- ...iewComponentTagHelperDescriptorProvider.cs | 8 +- .../StaticCompilationTagHelperFeature.cs | 3 +- .../BindTagHelperDescriptorProviderTest.cs | 47 +++----- .../test/CompilationTagHelperFeatureTest.cs | 13 +-- ...omponentTagHelperDescriptorProviderTest.cs | 106 +++++------------- .../DefaultTagHelperDescriptorProviderTest.cs | 26 +---- ...tHandlerTagHelperDescriptorProviderTest.cs | 4 +- .../KeyTagHelperDescriptorProviderTest.cs | 4 +- .../RefTagHelperDescriptorProviderTest.cs | 4 +- .../SplatTagHelperDescriptorProviderTest.cs | 4 +- .../CompilationTagHelperResolver.cs | 16 +-- 28 files changed, 90 insertions(+), 287 deletions(-) delete mode 100644 src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperDescriptorProviderContextExtensions.cs diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs index 6374829f5eb..ab563dda4ce 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -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; @@ -28,8 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs index 228dbee93cb..8192f48af6d 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -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; @@ -28,8 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs index 11de487c208..68961a39485 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -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; @@ -28,8 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs index d806c859e57..ba7f1436257 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs @@ -91,11 +91,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) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs index 09ca7e652ef..af9a69e4160 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs @@ -17,15 +17,15 @@ public sealed class CompilationTagHelperFeature : RazorEngineFeatureBase, ITagHe public IReadOnlyList GetDescriptors() { - var results = new List(); - - 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(); + var context = TagHelperDescriptorProviderContext.Create(compilation, results); + for (var i = 0; i < _providers.Length; i++) { _providers[i].Execute(context); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs index 55c244c0500..15315e2bf0c 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs @@ -10,7 +10,6 @@ using System.Linq; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; -using Microsoft.AspNetCore.Razor.Language.Extensions; using Microsoft.AspNetCore.Razor.PooledObjects; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; @@ -34,13 +33,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - // No compilation, nothing to do. - return; - } - + var compilation = context.Compilation; var targetSymbol = context.Items.GetTargetSymbol(); var collector = new Collector(compilation, targetSymbol); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs index a7f69392c35..b97810e3a92 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs @@ -21,12 +21,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - // No compilation, nothing to do. - return; - } + var compilation = context.Compilation; var tagHelperTypeSymbol = compilation.GetTypeByMetadataName(TagHelperTypes.ITagHelper); if (tagHelperTypeSymbol == null || tagHelperTypeSymbol.TypeKind == TypeKind.Error) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs index 058f6485b3e..e49f629ffe7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs @@ -25,11 +25,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; if (compilation.GetTypeByMetadataName(ComponentsApi.EventHandlerAttribute.FullTypeName) is not INamedTypeSymbol eventHandlerAttribute) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs index 030030882eb..fe834bd4db2 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs @@ -25,11 +25,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; var renderTreeBuilders = compilation.GetTypesByMetadataName(ComponentsApi.RenderTreeBuilder.FullTypeName) .Where(static t => t.DeclaredAccessibility == Accessibility.Public && diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs index 22a999350e1..2a12fbb0087 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs @@ -26,11 +26,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; var renderTreeBuilderType = compilation.GetTypeByMetadataName(ComponentsApi.RenderTreeBuilder.FullTypeName); if (renderTreeBuilderType == null) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs index 7ade45235d5..dc2014716bf 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs @@ -26,11 +26,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; var elementReference = compilation.GetTypeByMetadataName(ComponentsApi.ElementReference.FullTypeName); if (elementReference == null) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs index 81d214463e7..16d38f9df6a 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs @@ -26,11 +26,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; var iComponentRenderMode = compilation.GetTypeByMetadataName(ComponentsApi.IComponentRenderMode.FullTypeName); if (iComponentRenderMode == null) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs index e1d44045aa0..796fc145acb 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs @@ -26,11 +26,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - return; - } + var compilation = context.Compilation; var renderTreeBuilder = compilation.GetTypeByMetadataName(ComponentsApi.RenderTreeBuilder.FullTypeName); if (renderTreeBuilder == null) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperDescriptorProviderContextExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperDescriptorProviderContextExtensions.cs deleted file mode 100644 index 23273e15454..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperDescriptorProviderContextExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#nullable disable - -using System; -using Microsoft.AspNetCore.Razor.Language; - -namespace Microsoft.CodeAnalysis.Razor; - -public static class TagHelperDescriptorProviderContextExtensions -{ - public static Compilation GetCompilation(this TagHelperDescriptorProviderContext context) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - return (Compilation)context.Items[typeof(Compilation)]; - } - - public static void SetCompilation(this TagHelperDescriptorProviderContext context, Compilation compilation) - { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } - - context.Items[typeof(Compilation)] = compilation; - } -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index f759c203f04..5625641a296 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -2,26 +2,30 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Razor.Language; public sealed class TagHelperDescriptorProviderContext { + public Compilation Compilation { get; } + public bool ExcludeHidden { get; set; } public bool IncludeDocumentation { get; set; } public ItemCollection Items { get; } public ICollection Results { get; } - private TagHelperDescriptorProviderContext(ICollection results) + private TagHelperDescriptorProviderContext(Compilation compilation, ICollection results) { + Compilation = compilation; Results = results; Items = []; } - public static TagHelperDescriptorProviderContext Create() - => new([]); + public static TagHelperDescriptorProviderContext Create(Compilation compilation) + => new(compilation, results: []); - public static TagHelperDescriptorProviderContext Create(ICollection results) - => new(results); + public static TagHelperDescriptorProviderContext Create(Compilation compilation, ICollection results) + => new(compilation, results); } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs index f53efafa6e8..70ed5efa619 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X; @@ -23,12 +22,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - // No compilation, nothing to do. - return; - } + var compilation = context.Compilation; var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs index 1b699e6aa40..a3c6c11d5d9 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X; @@ -23,12 +22,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - // No compilation, nothing to do. - return; - } + var compilation = context.Compilation; var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs index ead9211e953..178508686ac 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs @@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions; @@ -23,12 +22,7 @@ public void Execute(TagHelperDescriptorProviderContext context) throw new ArgumentNullException(nameof(context)); } - var compilation = context.GetCompilation(); - if (compilation == null) - { - // No compilation, nothing to do. - return; - } + var compilation = context.Compilation; var vcAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.ViewComponentAttribute); var nonVCAttribute = compilation.GetTypeByMetadataName(ViewComponentTypes.NonViewComponentAttribute); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs index 15f35d54f51..0efcc84523b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs @@ -22,8 +22,7 @@ public void CollectDescriptors(ISymbol? targetSymbol, List return; } - var context = TagHelperDescriptorProviderContext.Create(results); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation, results); if (targetSymbol is not null) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs index 35fc97d894f..718c0128b2c 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs @@ -5,7 +5,6 @@ using System; using System.Linq; -using System.Threading; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using Xunit; @@ -49,8 +48,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -184,8 +182,7 @@ public void Execute_BindTagHelperReturnsValuesWhenProvidedNoTargetSymbol() Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -209,8 +206,7 @@ public void Execute_BindTagHelperReturnsValuesWhenProvidedCorrectAssemblyTargetS Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var bindConverterSymbol = compilation.GetTypeByMetadataName(ComponentsApi.BindConverter.FullTypeName); context.Items.SetTargetSymbol(bindConverterSymbol.ContainingAssembly); @@ -237,8 +233,7 @@ public void Execute_BindTagHelperReturnsEmptyWhenCompilationAssemblyTargetSymbol Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); context.Items.SetTargetSymbol(compilation.Assembly); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -281,8 +276,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -432,8 +426,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -468,9 +461,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -729,9 +720,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -814,9 +803,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -890,9 +877,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -987,9 +972,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -1086,9 +1069,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -1115,9 +1096,7 @@ public void Execute_BindFallback_CreatesDescriptor() var compilation = BaseCompilation; Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/CompilationTagHelperFeatureTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/CompilationTagHelperFeatureTest.cs index 052185a68f6..e93e5617c6e 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/CompilationTagHelperFeatureTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/CompilationTagHelperFeatureTest.cs @@ -70,11 +70,8 @@ public void IsValidCompilation_ReturnsTrueIfWellKnownTypesAreFound() public void GetDescriptors_DoesNotSetCompilation_IfCompilationIsInvalid() { // Arrange - Compilation compilation = null; var provider = new Mock(); - provider.Setup(c => c.Execute(It.IsAny())) - .Callback(c => compilation = c.GetCompilation()) - .Verifiable(); + provider.Setup(c => c.Execute(It.IsAny())); var engine = RazorProjectEngine.Create( configure => @@ -91,8 +88,7 @@ public void GetDescriptors_DoesNotSetCompilation_IfCompilationIsInvalid() // Assert Assert.Empty(result); - provider.Verify(); - Assert.Null(compilation); + provider.Verify(c => c.Execute(It.IsAny()), Times.Never); } [Fact] @@ -101,8 +97,9 @@ public void GetDescriptors_SetsCompilation_IfCompilationIsValid() // Arrange Compilation compilation = null; var provider = new Mock(); - provider.Setup(c => c.Execute(It.IsAny())) - .Callback(c => compilation = c.GetCompilation()) + provider + .Setup(c => c.Execute(It.IsAny())) + .Callback(c => compilation = c.Compilation) .Verifiable(); var references = new[] diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs index 2786fd31756..13205705dc7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs @@ -41,9 +41,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -166,9 +164,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -230,9 +226,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -272,9 +266,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -312,9 +304,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -352,9 +342,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -405,9 +393,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -453,9 +439,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -501,9 +485,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -565,9 +547,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -640,9 +620,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -690,9 +668,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -752,9 +728,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -803,9 +777,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -858,9 +830,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -921,9 +891,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -978,9 +946,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1053,9 +1019,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1125,9 +1089,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1207,9 +1169,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1289,9 +1249,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1375,9 +1333,7 @@ public class Context Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1461,9 +1417,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1553,9 +1507,7 @@ public string this[int i] Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1609,9 +1561,7 @@ public class MyDerivedComponent2 : MyDerivedComponent1 Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1669,8 +1619,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); context.Items.SetTargetSymbol((IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(compilation.References.First(r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll")))); var provider = new ComponentTagHelperDescriptorProvider(); @@ -1715,8 +1664,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs index eec507e0ae8..2c3f5a3593a 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs @@ -3,10 +3,8 @@ #nullable disable -using System.Diagnostics; using System.Linq; using System.Reflection; -using System.Threading; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis.CSharp; using Xunit; @@ -25,8 +23,7 @@ public void Execute_DoesNotAddEditorBrowsableNeverDescriptorsAtDesignTime() var compilation = TestCompilation.Create(_assembly); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); context.ExcludeHidden = true; // Act @@ -40,21 +37,6 @@ public void Execute_DoesNotAddEditorBrowsableNeverDescriptorsAtDesignTime() Assert.Empty(editorBrowsableDescriptor); } - [Fact] - public void Execute_NoOpsIfCompilationIsNotSet() - { - // Arrange - var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - - var context = TagHelperDescriptorProviderContext.Create(); - - // Act - descriptorProvider.Execute(context); - - // Assert - Assert.Empty(context.Results); - } - [Fact] public void Execute_WithDefaultDiscoversTagHelpersFromAssemblyAndReference() { @@ -73,8 +55,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) { var compilation = TestCompilation.Create(_assembly, CSharpSyntaxTree.ParseText(csharp)); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); // Act descriptorProvider.Execute(context); @@ -104,8 +85,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) { var compilation = TestCompilation.Create(_assembly, CSharpSyntaxTree.ParseText(csharp)); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); + var context = TagHelperDescriptorProviderContext.Create(compilation); context.Items.SetTargetSymbol((IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(compilation.References.First(r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll")))); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs index b5d097adc6d..5f49881ab64 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs @@ -33,9 +33,7 @@ public class EventHandlers Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(compilation); - + var context = TagHelperDescriptorProviderContext.Create(compilation); var provider = new EventHandlerTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs index 8d3fbc8a7a7..d24a0959ece 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs @@ -16,9 +16,7 @@ public class KeyTagHelperDescriptorProviderTest : TagHelperDescriptorProviderTes public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(BaseCompilation); - + var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); var provider = new KeyTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs index 82246df560e..3f0ec75f345 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs @@ -16,9 +16,7 @@ public class RefTagHelperDescriptorProviderTest : TagHelperDescriptorProviderTes public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(BaseCompilation); - + var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); var provider = new RefTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs index 66e5380a54c..b0563a10af2 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs @@ -16,9 +16,7 @@ public class SplatTagHelperDescriptorProviderTest : TagHelperDescriptorProviderT public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(); - context.SetCompilation(BaseCompilation); - + var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); var provider = new SplatTagHelperDescriptorProvider(); // Act diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs index adf4da162be..4db479a3d89 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs @@ -37,20 +37,20 @@ public async ValueTask> GetTagHelpersAsync( var providers = projectEngine.Engine.Features.OfType().OrderBy(f => f.Order).ToArray(); if (providers.Length == 0) { - return ImmutableArray.Empty; + return []; } - using var _ = HashSetPool.GetPooledObject(out var results); - var context = TagHelperDescriptorProviderContext.Create(results); - context.ExcludeHidden = true; - context.IncludeDocumentation = true; - var compilation = await workspaceProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - if (CompilationTagHelperFeature.IsValidCompilation(compilation)) + if (compilation is null || !CompilationTagHelperFeature.IsValidCompilation(compilation)) { - context.SetCompilation(compilation); + return []; } + using var _ = HashSetPool.GetPooledObject(out var results); + var context = TagHelperDescriptorProviderContext.Create(compilation, results); + context.ExcludeHidden = true; + context.IncludeDocumentation = true; + ExecuteProviders(providers, context, _telemetryReporter); return results.ToImmutableArray(); From ec5cd16335327bd38cc52f9ed6ba2d34e747101c Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 10:07:39 -0700 Subject: [PATCH 3/8] Make TargetSymbol a TagHelperDescriptorProviderContext property --- .../CSharp/BindTagHelperDescriptorProvider.cs | 3 +-- .../ComponentTagHelperDescriptorProvider.cs | 2 +- .../DefaultTagHelperDescriptorProvider.cs | 2 +- ...EventHandlerTagHelperDescriptorProvider.cs | 2 +- .../FormNameTagHelperDescriptorProvider.cs | 3 +-- .../CSharp/KeyTagHelperDescriptorProvider.cs | 3 +-- .../CSharp/RefTagHelperDescriptorProvider.cs | 3 +-- .../RenderModeTagHelperDescriptorProvider.cs | 3 +-- .../SplatTagHelperDescriptorProvider.cs | 3 +-- .../CSharp/TagHelperTargetSymbolExtensions.cs | 26 ------------------- .../TagHelperDescriptorProviderContext.cs | 13 +++++++--- .../StaticCompilationTagHelperFeature.cs | 8 +----- .../BindTagHelperDescriptorProviderTest.cs | 7 ++--- ...omponentTagHelperDescriptorProviderTest.cs | 6 +++-- .../DefaultTagHelperDescriptorProviderTest.cs | 6 +++-- 15 files changed, 29 insertions(+), 61 deletions(-) delete mode 100644 src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperTargetSymbolExtensions.cs diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs index ba7f1436257..b1999846c33 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs @@ -101,8 +101,7 @@ 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; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs index 15315e2bf0c..afd68b5eac0 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs @@ -34,7 +34,7 @@ public void Execute(TagHelperDescriptorProviderContext context) } var compilation = context.Compilation; - var targetSymbol = context.Items.GetTargetSymbol(); + var targetSymbol = context.TargetSymbol; var collector = new Collector(compilation, targetSymbol); collector.Collect(context); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs index b97810e3a92..4a7d1c98cc2 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs @@ -30,7 +30,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); + var targetSymbol = context.TargetSymbol; var factory = new DefaultTagHelperDescriptorFactory(compilation, context.IncludeDocumentation, context.ExcludeHidden); var collector = new Collector(compilation, targetSymbol, factory, tagHelperTypeSymbol); collector.Collect(context); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs index e49f629ffe7..7817c7fafa5 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs @@ -33,7 +33,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); + var targetSymbol = context.TargetSymbol; var collector = new Collector(compilation, targetSymbol, eventHandlerAttribute); collector.Collect(context); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs index fe834bd4db2..208e1ecc038 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs @@ -36,8 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); - if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilder.ContainingAssembly)) + if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilder.ContainingAssembly)) { return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs index 2a12fbb0087..359071fbc3e 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs @@ -36,8 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); - if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilderType.ContainingAssembly)) + if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilderType.ContainingAssembly)) { return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs index dc2014716bf..40f50698d20 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs @@ -36,8 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); - if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, elementReference.ContainingAssembly)) + if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, elementReference.ContainingAssembly)) { return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs index 16d38f9df6a..8feb1499e26 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs @@ -36,8 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); - if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, iComponentRenderMode.ContainingAssembly)) + if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, iComponentRenderMode.ContainingAssembly)) { return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs index 796fc145acb..5ec98d1eaa5 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs @@ -36,8 +36,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - var targetSymbol = context.Items.GetTargetSymbol(); - if (targetSymbol is not null && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilder.ContainingAssembly)) + if (context.TargetSymbol is { } targetSymbol && !SymbolEqualityComparer.Default.Equals(targetSymbol, renderTreeBuilder.ContainingAssembly)) { return; } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperTargetSymbolExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperTargetSymbolExtensions.cs deleted file mode 100644 index 6e9b1609e7f..00000000000 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/TagHelperTargetSymbolExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using Microsoft.AspNetCore.Razor.Language; - -namespace Microsoft.CodeAnalysis.Razor; - -internal static class TagHelperTargetSymbolExtensions -{ - private static readonly object TargetSymbolKey = new object(); - - public static ISymbol? GetTargetSymbol(this ItemCollection items) - { - if (items.Count == 0 || items[TargetSymbolKey] is not ISymbol symbol) - { - return null; - } - - return symbol; - } - - public static void SetTargetSymbol(this ItemCollection items, ISymbol symbol) - { - items[TargetSymbolKey] = symbol; - } -} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index 5625641a296..af2f09c4d28 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -9,6 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Language; public sealed class TagHelperDescriptorProviderContext { public Compilation Compilation { get; } + public ISymbol? TargetSymbol { get; } public bool ExcludeHidden { get; set; } public bool IncludeDocumentation { get; set; } @@ -16,16 +17,20 @@ public sealed class TagHelperDescriptorProviderContext public ItemCollection Items { get; } public ICollection Results { get; } - private TagHelperDescriptorProviderContext(Compilation compilation, ICollection results) + private TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol, ICollection results) { Compilation = compilation; + TargetSymbol = targetSymbol; Results = results; Items = []; } - public static TagHelperDescriptorProviderContext Create(Compilation compilation) - => new(compilation, results: []); + public static TagHelperDescriptorProviderContext Create(Compilation compilation, ISymbol? targetSymbol = null) + => new(compilation, targetSymbol, results: []); public static TagHelperDescriptorProviderContext Create(Compilation compilation, ICollection results) - => new(compilation, results); + => new(compilation, targetSymbol: null, results); + + public static TagHelperDescriptorProviderContext Create(Compilation compilation, ISymbol? targetSymbol, ICollection results) + => new(compilation, targetSymbol, results); } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs index 0efcc84523b..8da3ba40778 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs @@ -6,7 +6,6 @@ using System.Linq; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Razor; namespace Microsoft.NET.Sdk.Razor.SourceGenerators { @@ -22,12 +21,7 @@ public void CollectDescriptors(ISymbol? targetSymbol, List return; } - var context = TagHelperDescriptorProviderContext.Create(compilation, results); - - if (targetSymbol is not null) - { - context.Items.SetTargetSymbol(targetSymbol); - } + var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol, results); foreach (var provider in _providers) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs index 718c0128b2c..1c3f5c37019 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs @@ -206,10 +206,8 @@ public void Execute_BindTagHelperReturnsValuesWhenProvidedCorrectAssemblyTargetS Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); - var bindConverterSymbol = compilation.GetTypeByMetadataName(ComponentsApi.BindConverter.FullTypeName); - context.Items.SetTargetSymbol(bindConverterSymbol.ContainingAssembly); + var context = TagHelperDescriptorProviderContext.Create(compilation, bindConverterSymbol.ContainingAssembly); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -233,8 +231,7 @@ public void Execute_BindTagHelperReturnsEmptyWhenCompilationAssemblyTargetSymbol Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); - context.Items.SetTargetSymbol(compilation.Assembly); + var context = TagHelperDescriptorProviderContext.Create(compilation, compilation.Assembly); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs index 13205705dc7..54ae8aef5cb 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs @@ -1619,8 +1619,10 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); - context.Items.SetTargetSymbol((IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(compilation.References.First(r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll")))); + var targetSymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol( + compilation.References.First(static r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll"))); + + var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol); var provider = new ComponentTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs index 2c3f5a3593a..a38a1fc025f 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs @@ -85,8 +85,10 @@ public override void Process(TagHelperContext context, TagHelperOutput output) { var compilation = TestCompilation.Create(_assembly, CSharpSyntaxTree.ParseText(csharp)); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(compilation); - context.Items.SetTargetSymbol((IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol(compilation.References.First(r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll")))); + var targetSymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol( + compilation.References.First(static r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll"))); + + var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol); // Act descriptorProvider.Execute(context); From 45625bc1a23337594aa93814e98638d6b964b2c1 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 10:09:29 -0700 Subject: [PATCH 4/8] Remove TagHelperDescriptorProviderContext.Items property This can be safely removed now that there are no more references. --- .../src/Language/TagHelperDescriptorProviderContext.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index af2f09c4d28..5d7c950c16b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -14,7 +14,6 @@ public sealed class TagHelperDescriptorProviderContext public bool ExcludeHidden { get; set; } public bool IncludeDocumentation { get; set; } - public ItemCollection Items { get; } public ICollection Results { get; } private TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol, ICollection results) @@ -22,7 +21,6 @@ private TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? tar Compilation = compilation; TargetSymbol = targetSymbol; Results = results; - Items = []; } public static TagHelperDescriptorProviderContext Create(Compilation compilation, ISymbol? targetSymbol = null) From 9476634170ea39c92663ad2da01ce95a2325b090 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 10:14:05 -0700 Subject: [PATCH 5/8] Swap TagHelperDescriptorProviderContext.Create methods for constructors --- ...omponentTagHelperDescriptorProviderTest.cs | 2 +- ...omponentTagHelperDescriptorProviderTest.cs | 2 +- ...omponentTagHelperDescriptorProviderTest.cs | 2 +- .../src/CSharp/CompilationTagHelperFeature.cs | 2 +- .../TagHelperDescriptorProviderContext.cs | 26 ++++----- .../StaticCompilationTagHelperFeature.cs | 2 +- .../BindTagHelperDescriptorProviderTest.cs | 26 ++++----- ...omponentTagHelperDescriptorProviderTest.cs | 54 +++++++++---------- .../DefaultTagHelperDescriptorProviderTest.cs | 6 +-- ...tHandlerTagHelperDescriptorProviderTest.cs | 2 +- .../KeyTagHelperDescriptorProviderTest.cs | 2 +- .../RefTagHelperDescriptorProviderTest.cs | 2 +- .../SplatTagHelperDescriptorProviderTest.cs | 2 +- .../CompilationTagHelperResolver.cs | 2 +- 14 files changed, 63 insertions(+), 69 deletions(-) diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs index ab563dda4ce..b79da5d4bf9 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -27,7 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs index 8192f48af6d..8776cd20f16 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -27,7 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs index 68961a39485..e4712707c84 100644 --- a/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.AspNetCore.Mvc.Razor.Extensions/test/ViewComponentTagHelperDescriptorProviderTest.cs @@ -27,7 +27,7 @@ public class StringParameterViewComponent var compilation = MvcShim.BaseCompilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(code)); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ViewComponentTagHelperDescriptorProvider() { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs index af9a69e4160..cfa7f57f20b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/CompilationTagHelperFeature.cs @@ -24,7 +24,7 @@ public IReadOnlyList GetDescriptors() } var results = new List(); - var context = TagHelperDescriptorProviderContext.Create(compilation, results); + var context = new TagHelperDescriptorProviderContext(compilation, results); for (var i = 0; i < _providers.Length; i++) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index 5d7c950c16b..cee1a15c3b4 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -6,29 +6,23 @@ namespace Microsoft.AspNetCore.Razor.Language; -public sealed class TagHelperDescriptorProviderContext +public sealed class TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol, ICollection results) { - public Compilation Compilation { get; } - public ISymbol? TargetSymbol { get; } + public Compilation Compilation { get; } = compilation; + public ISymbol? TargetSymbol { get; } = targetSymbol; public bool ExcludeHidden { get; set; } public bool IncludeDocumentation { get; set; } - public ICollection Results { get; } + public ICollection Results { get; } = results; - private TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol, ICollection results) + public TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol = null) + : this(compilation, targetSymbol, results: []) { - Compilation = compilation; - TargetSymbol = targetSymbol; - Results = results; } - public static TagHelperDescriptorProviderContext Create(Compilation compilation, ISymbol? targetSymbol = null) - => new(compilation, targetSymbol, results: []); - - public static TagHelperDescriptorProviderContext Create(Compilation compilation, ICollection results) - => new(compilation, targetSymbol: null, results); - - public static TagHelperDescriptorProviderContext Create(Compilation compilation, ISymbol? targetSymbol, ICollection results) - => new(compilation, targetSymbol, results); + public TagHelperDescriptorProviderContext(Compilation compilation, ICollection results) + : this(compilation, targetSymbol: null, results) + { + } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs index 8da3ba40778..812c7bb3381 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/StaticCompilationTagHelperFeature.cs @@ -21,7 +21,7 @@ public void CollectDescriptors(ISymbol? targetSymbol, List return; } - var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol, results); + var context = new TagHelperDescriptorProviderContext(compilation, targetSymbol, results); foreach (var provider in _providers) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs index 1c3f5c37019..6b568a1b353 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/BindTagHelperDescriptorProviderTest.cs @@ -48,7 +48,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -182,7 +182,7 @@ public void Execute_BindTagHelperReturnsValuesWhenProvidedNoTargetSymbol() Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -207,7 +207,7 @@ public void Execute_BindTagHelperReturnsValuesWhenProvidedCorrectAssemblyTargetS Assert.Empty(compilation.GetDiagnostics()); var bindConverterSymbol = compilation.GetTypeByMetadataName(ComponentsApi.BindConverter.FullTypeName); - var context = TagHelperDescriptorProviderContext.Create(compilation, bindConverterSymbol.ContainingAssembly); + var context = new TagHelperDescriptorProviderContext(compilation, bindConverterSymbol.ContainingAssembly); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -231,7 +231,7 @@ public void Execute_BindTagHelperReturnsEmptyWhenCompilationAssemblyTargetSymbol Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation, compilation.Assembly); + var context = new TagHelperDescriptorProviderContext(compilation, compilation.Assembly); var bindTagHelperProvider = new BindTagHelperDescriptorProvider(); @@ -273,7 +273,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -423,7 +423,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); // We run after component discovery and depend on the results. var componentProvider = new ComponentTagHelperDescriptorProvider(); @@ -458,7 +458,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -717,7 +717,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -800,7 +800,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -874,7 +874,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -969,7 +969,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -1066,7 +1066,7 @@ public class BindAttributes Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act @@ -1093,7 +1093,7 @@ public void Execute_BindFallback_CreatesDescriptor() var compilation = BaseCompilation; Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new BindTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs index 54ae8aef5cb..3a37a47cd1b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/ComponentTagHelperDescriptorProviderTest.cs @@ -41,7 +41,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -164,7 +164,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -226,7 +226,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -266,7 +266,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -304,7 +304,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -342,7 +342,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -393,7 +393,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -439,7 +439,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -485,7 +485,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -547,7 +547,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -620,7 +620,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -668,7 +668,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -728,7 +728,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -777,7 +777,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -830,7 +830,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -891,7 +891,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -946,7 +946,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1019,7 +1019,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1089,7 +1089,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1169,7 +1169,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1249,7 +1249,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1333,7 +1333,7 @@ public class Context Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1417,7 +1417,7 @@ public class MyComponent : ComponentBase Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1507,7 +1507,7 @@ public string this[int i] Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1561,7 +1561,7 @@ public class MyDerivedComponent2 : MyDerivedComponent1 Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1622,7 +1622,7 @@ public Task SetParametersAsync(ParameterView parameters) var targetSymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol( compilation.References.First(static r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll"))); - var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol); + var context = new TagHelperDescriptorProviderContext(compilation, targetSymbol); var provider = new ComponentTagHelperDescriptorProvider(); // Act @@ -1666,7 +1666,7 @@ public Task SetParametersAsync(ParameterView parameters) Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new ComponentTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs index a38a1fc025f..83702d37e3f 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs @@ -23,7 +23,7 @@ public void Execute_DoesNotAddEditorBrowsableNeverDescriptorsAtDesignTime() var compilation = TestCompilation.Create(_assembly); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); context.ExcludeHidden = true; // Act @@ -55,7 +55,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) { var compilation = TestCompilation.Create(_assembly, CSharpSyntaxTree.ParseText(csharp)); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); // Act descriptorProvider.Execute(context); @@ -88,7 +88,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) { var targetSymbol = (IAssemblySymbol)compilation.GetAssemblyOrModuleSymbol( compilation.References.First(static r => r.Display.Contains("Microsoft.CodeAnalysis.Razor.Test.dll"))); - var context = TagHelperDescriptorProviderContext.Create(compilation, targetSymbol); + var context = new TagHelperDescriptorProviderContext(compilation, targetSymbol); // Act descriptorProvider.Execute(context); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs index 5f49881ab64..101927ad544 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/EventHandlerTagHelperDescriptorProviderTest.cs @@ -33,7 +33,7 @@ public class EventHandlers Assert.Empty(compilation.GetDiagnostics()); - var context = TagHelperDescriptorProviderContext.Create(compilation); + var context = new TagHelperDescriptorProviderContext(compilation); var provider = new EventHandlerTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs index d24a0959ece..a9238bd8afe 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/KeyTagHelperDescriptorProviderTest.cs @@ -16,7 +16,7 @@ public class KeyTagHelperDescriptorProviderTest : TagHelperDescriptorProviderTes public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); + var context = new TagHelperDescriptorProviderContext(BaseCompilation); var provider = new KeyTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs index 3f0ec75f345..5109439c9cf 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/RefTagHelperDescriptorProviderTest.cs @@ -16,7 +16,7 @@ public class RefTagHelperDescriptorProviderTest : TagHelperDescriptorProviderTes public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); + var context = new TagHelperDescriptorProviderContext(BaseCompilation); var provider = new RefTagHelperDescriptorProvider(); // Act diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs index b0563a10af2..19e2c970bfd 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/SplatTagHelperDescriptorProviderTest.cs @@ -16,7 +16,7 @@ public class SplatTagHelperDescriptorProviderTest : TagHelperDescriptorProviderT public void Execute_CreatesDescriptor() { // Arrange - var context = TagHelperDescriptorProviderContext.Create(BaseCompilation); + var context = new TagHelperDescriptorProviderContext(BaseCompilation); var provider = new SplatTagHelperDescriptorProvider(); // Act diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs index 4db479a3d89..63cda097147 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs @@ -47,7 +47,7 @@ public async ValueTask> GetTagHelpersAsync( } using var _ = HashSetPool.GetPooledObject(out var results); - var context = TagHelperDescriptorProviderContext.Create(compilation, results); + var context = new TagHelperDescriptorProviderContext(compilation, results); context.ExcludeHidden = true; context.IncludeDocumentation = true; From eae0d53793687727c7399a8babe5c0b145dc8a14 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 10:19:35 -0700 Subject: [PATCH 6/8] Make ExcludeHidden and IncludeDocumentation init-only properties --- .../src/Language/TagHelperDescriptorProviderContext.cs | 7 +++---- .../test/DefaultTagHelperDescriptorProviderTest.cs | 6 ++++-- .../CompilationTagHelperResolver.cs | 8 +++++--- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs index cee1a15c3b4..1305d7888af 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderContext.cs @@ -10,12 +10,11 @@ public sealed class TagHelperDescriptorProviderContext(Compilation compilation, { public Compilation Compilation { get; } = compilation; public ISymbol? TargetSymbol { get; } = targetSymbol; - - public bool ExcludeHidden { get; set; } - public bool IncludeDocumentation { get; set; } - public ICollection Results { get; } = results; + public bool ExcludeHidden { get; init; } + public bool IncludeDocumentation { get; init; } + public TagHelperDescriptorProviderContext(Compilation compilation, ISymbol? targetSymbol = null) : this(compilation, targetSymbol, results: []) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs index 83702d37e3f..f5d46a59aec 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor/test/DefaultTagHelperDescriptorProviderTest.cs @@ -23,8 +23,10 @@ public void Execute_DoesNotAddEditorBrowsableNeverDescriptorsAtDesignTime() var compilation = TestCompilation.Create(_assembly); var descriptorProvider = new DefaultTagHelperDescriptorProvider(); - var context = new TagHelperDescriptorProviderContext(compilation); - context.ExcludeHidden = true; + var context = new TagHelperDescriptorProviderContext(compilation) + { + ExcludeHidden = true + }; // Act descriptorProvider.Execute(context); diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs index 63cda097147..73e1d766d06 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs @@ -47,9 +47,11 @@ public async ValueTask> GetTagHelpersAsync( } using var _ = HashSetPool.GetPooledObject(out var results); - var context = new TagHelperDescriptorProviderContext(compilation, results); - context.ExcludeHidden = true; - context.IncludeDocumentation = true; + var context = new TagHelperDescriptorProviderContext(compilation, results) + { + ExcludeHidden = true, + IncludeDocumentation = true + }; ExecuteProviders(providers, context, _telemetryReporter); From 5fbfc0d454eba158ee903f877a6bc67141c93f88 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 12:28:46 -0700 Subject: [PATCH 7/8] Clean up all ITagHelperDescriptorProviders a bit (and found a bug!) - Enable nullability - Mark all as sealed - Use `Lazy` for singleton `ITagHelperDescriptorProviders` - Introduce `TagHelperDescriptorProviderBase` - Inherit from `TagHelperDescriptorProviderBase` - Remove unnecessary properties - Remove unnecessary property setters In addition, I spotted a bug in `EventHandlerTagDescriptorProvider` while addressing nullability warnings. The buggy code is right here: https://github.com/dotnet/razor/blob/fb84ae5d9bb8132972c2c23cf209721161f81deb/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs#L70-L76 When reading the constructor arguments of an `EventHandlerAttribute` it appears that we swap the last two arguments of the 4-argument variant. The constructor is defined like so: ```C# EventHandlerAttribute(string attributeName, Type eventArgsType, bool enableStopPropagation, bool enablePreventDefault); ``` Unfortunately, the compiler reads the third parameter as `enablePreventDefaeult` and the fourth parameter as `enableStopPropagation`. This has been broken since support for the 4-argument constructor variant was added in https://github.com/dotnet/razor/commit/7635bba6ef2d3e6798d0846ceb96da6d5908e1b0. Fixing this bug is tracked by https://github.com/dotnet/razor/issues/10497. --- .../CSharp/BindTagHelperDescriptorProvider.cs | 183 ++++++++---------- .../ComponentTagHelperDescriptorProvider.cs | 170 ++++++++-------- .../DefaultTagHelperDescriptorProvider.cs | 17 +- ...EventHandlerTagHelperDescriptorProvider.cs | 89 +++++---- .../FormNameTagHelperDescriptorProvider.cs | 16 +- .../CSharp/KeyTagHelperDescriptorProvider.cs | 83 ++++---- .../CSharp/RefTagHelperDescriptorProvider.cs | 83 ++++---- .../RenderModeTagHelperDescriptorProvider.cs | 22 +-- .../SplatTagHelperDescriptorProvider.cs | 82 ++++---- .../src/CSharp/SymbolExtensions.cs | 3 + .../TagHelperDescriptorProviderBase.cs | 11 ++ ...iewComponentTagHelperDescriptorProvider.cs | 19 +- .../ViewComponentTypeVisitor.cs | 10 +- ...iewComponentTagHelperDescriptorProvider.cs | 19 +- .../ViewComponentTypeVisitor.cs | 10 +- ...iewComponentTagHelperDescriptorProvider.cs | 19 +- .../src/Mvc/ViewComponentTypeVisitor.cs | 8 +- 17 files changed, 386 insertions(+), 458 deletions(-) create mode 100644 src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderBase.cs diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs index b1999846c33..e2c3d9f77c5 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs @@ -5,6 +5,7 @@ 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; @@ -12,21 +13,14 @@ 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 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 @@ -107,7 +101,7 @@ public void Execute(TagHelperDescriptorProviderContext context) } // 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); @@ -124,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"; + attribute.TypeName = "System.Collections.Generic.Dictionary"; - 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( diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs index afd68b5eac0..99c6e5e6943 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/ComponentTagHelperDescriptorProvider.cs @@ -1,13 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using Microsoft.AspNetCore.Razor.PooledObjects; @@ -15,23 +14,16 @@ namespace Microsoft.CodeAnalysis.Razor; -internal partial class ComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider +internal sealed class ComponentTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { private static readonly SymbolDisplayFormat GloballyQualifiedFullNameTypeDisplayFormat = SymbolDisplayFormat.FullyQualifiedFormat .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Included) .WithMiscellaneousOptions(SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions & (~SymbolDisplayMiscellaneousOptions.UseSpecialTypes)); - public bool IncludeDocumentation { get; set; } - - public int Order { get; set; } - - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; var targetSymbol = context.TargetSymbol; @@ -40,7 +32,7 @@ public void Execute(TagHelperDescriptorProviderContext context) collector.Collect(context); } - private sealed class Collector(Compilation compilation, ISymbol targetSymbol) + private sealed class Collector(Compilation compilation, ISymbol? targetSymbol) : TagHelperCollector(compilation, targetSymbol) { protected override void Collect(ISymbol symbol, ICollection results) @@ -136,7 +128,7 @@ private static TagHelperDescriptor CreateNameMatchingDescriptor( foreach (var attribute in type.GetAttributes()) { - if (attribute.AttributeClass.HasFullName(ComponentsApi.CascadingTypeParameterAttribute.MetadataName) && + if (attribute.HasFullName(ComponentsApi.CascadingTypeParameterAttribute.MetadataName) && attribute.ConstructorArguments.FirstOrDefault() is { Value: string value }) { cascadeGenericTypeAttributes.Add(value); @@ -198,7 +190,7 @@ private static void CreateProperty(TagHelperDescriptorBuilder builder, INamedTyp pb.ContainingType = containingSymbol.ToDisplayString(SymbolExtensions.FullNameTypeDisplayFormat); pb.TypeName = property.Type.ToDisplayString(SymbolExtensions.FullNameTypeDisplayFormat); pb.IsEditorRequired = property.GetAttributes().Any( - static a => a.AttributeClass.HasFullName("Microsoft.AspNetCore.Components.EditorRequiredAttribute")); + static a => a.HasFullName("Microsoft.AspNetCore.Components.EditorRequiredAttribute")); pb.CaseSensitive = false; @@ -231,7 +223,7 @@ private static void CreateProperty(TagHelperDescriptorBuilder builder, INamedTyp metadata.Add(MakeTrue(ComponentMetadata.Component.GenericTypedKey)); } - if (property.SetMethod.IsInitOnly) + if (property.SetMethod.AssumeNotNull().IsInitOnly) { metadata.Add(MakeTrue(ComponentMetadata.Component.InitOnlyProperty)); } @@ -293,101 +285,98 @@ static bool HasTypeParameter(ITypeSymbol type) private static string IsAwaitable(IPropertySymbol prop) { - var methodSymbol = ((INamedTypeSymbol)prop.Type).DelegateInvokeMethod; + var methodSymbol = ((INamedTypeSymbol)prop.Type).DelegateInvokeMethod.AssumeNotNull(); if (methodSymbol.ReturnsVoid) { return bool.FalseString; } - else + + var members = methodSymbol.ReturnType.GetMembers(); + foreach (var candidate in members) { - var members = methodSymbol.ReturnType.GetMembers(); - foreach (var candidate in members) + if (candidate is not IMethodSymbol method || !string.Equals(candidate.Name, "GetAwaiter", StringComparison.Ordinal)) { - if (candidate is not IMethodSymbol method || !string.Equals(candidate.Name, "GetAwaiter", StringComparison.Ordinal)) - { - continue; - } + continue; + } - if (!VerifyGetAwaiter(method)) - { - continue; - } + if (!VerifyGetAwaiter(method)) + { + continue; + } + + return bool.TrueString; + } - return bool.TrueString; + return methodSymbol.IsAsync ? bool.TrueString : bool.FalseString; + + static bool VerifyGetAwaiter(IMethodSymbol getAwaiter) + { + var returnType = getAwaiter.ReturnType; + if (returnType == null) + { + return false; } - return methodSymbol.IsAsync ? bool.TrueString : bool.FalseString; + var foundIsCompleted = false; + var foundOnCompleted = false; + var foundGetResult = false; - static bool VerifyGetAwaiter(IMethodSymbol getAwaiter) + foreach (var member in returnType.GetMembers()) { - var returnType = getAwaiter.ReturnType; - if (returnType == null) + if (!foundIsCompleted && + member is IPropertySymbol property && + IsProperty_IsCompleted(property)) { - return false; + foundIsCompleted = true; } - - var foundIsCompleted = false; - var foundOnCompleted = false; - var foundGetResult = false; - - foreach (var member in returnType.GetMembers()) + if (!(foundOnCompleted && foundGetResult) && member is IMethodSymbol method) { - if (!foundIsCompleted && - member is IPropertySymbol property && - IsProperty_IsCompleted(property)) + if (IsMethod_OnCompleted(method)) { - foundIsCompleted = true; + foundOnCompleted = true; } - - if (!(foundOnCompleted && foundGetResult) && member is IMethodSymbol method) + else if (IsMethod_GetResult(method)) { - if (IsMethod_OnCompleted(method)) - { - foundOnCompleted = true; - } - else if (IsMethod_GetResult(method)) - { - foundGetResult = true; - } + foundGetResult = true; } + } - if (foundIsCompleted && foundOnCompleted && foundGetResult) - { - return true; - } + if (foundIsCompleted && foundOnCompleted && foundGetResult) + { + return true; } + } - return false; + return false; - static bool IsProperty_IsCompleted(IPropertySymbol property) + static bool IsProperty_IsCompleted(IPropertySymbol property) + { + return property is { - return property is - { - Name: WellKnownMemberNames.IsCompleted, - Type.SpecialType: SpecialType.System_Boolean, - GetMethod: not null - }; - } + Name: WellKnownMemberNames.IsCompleted, + Type.SpecialType: SpecialType.System_Boolean, + GetMethod: not null + }; + } - static bool IsMethod_OnCompleted(IMethodSymbol method) + static bool IsMethod_OnCompleted(IMethodSymbol method) + { + return method is { - return method is - { - Name: WellKnownMemberNames.OnCompleted, - ReturnsVoid: true, - Parameters: [{ Type.TypeKind: TypeKind.Delegate }] - }; - } + Name: WellKnownMemberNames.OnCompleted, + ReturnsVoid: true, + Parameters: [{ Type.TypeKind: TypeKind.Delegate }] + }; + } - static bool IsMethod_GetResult(IMethodSymbol method) + static bool IsMethod_GetResult(IMethodSymbol method) + { + return method is { - return method is - { - Name: WellKnownMemberNames.GetResult, - Parameters: [] - }; - } + Name: WellKnownMemberNames.GetResult, + Parameters: [] + }; } } } @@ -400,7 +389,7 @@ private static void CreateTypeParameterProperty(TagHelperDescriptorBuilder build pb.Name = typeParameter.Name; pb.TypeName = typeof(Type).FullName; - using var _ = ListPool>.GetPooledObject(out var metadataPairs); + using var _ = ListPool>.GetPooledObject(out var metadataPairs); metadataPairs.Add(PropertyName(typeParameter.Name)); metadataPairs.Add(MakeTrue(ComponentMetadata.Component.TypeParameterKey)); metadataPairs.Add(new(ComponentMetadata.Component.TypeParameterIsCascadingKey, cascade.ToString())); @@ -458,7 +447,7 @@ private static void CreateTypeParameterProperty(TagHelperDescriptorBuilder build builder.Name)); }); - static bool TryGetWhereClauseText(ITypeParameterSymbol typeParameter, PooledList constraints, [NotNullWhen(true)] out string constraintsText) + static bool TryGetWhereClauseText(ITypeParameterSymbol typeParameter, PooledList constraints, [NotNullWhen(true)] out string? constraintsText) { if (constraints.Count == 0) { @@ -547,7 +536,7 @@ private static TagHelperDescriptor CreateChildContentDescriptor(TagHelperDescrip return descriptor; } - private static void CreateContextParameter(TagHelperDescriptorBuilder builder, string childContentName) + private static void CreateContextParameter(TagHelperDescriptorBuilder builder, string? childContentName) { builder.BindAttribute(b => { @@ -579,9 +568,10 @@ private static void CreateContextParameter(TagHelperDescriptorBuilder builder, s using var names = new PooledHashSet(StringHashSetPool.Ordinal); using var results = new PooledArrayBuilder<(IPropertySymbol, PropertyKind)>(); + var currentType = type; do { - if (type.HasFullName(ComponentsApi.ComponentBase.MetadataName)) + if (currentType.HasFullName(ComponentsApi.ComponentBase.MetadataName)) { // The ComponentBase base class doesn't have any [Parameter]. // Bail out now to avoid walking through its many members, plus the members @@ -589,7 +579,7 @@ private static void CreateContextParameter(TagHelperDescriptorBuilder builder, s break; } - foreach (var member in type.GetMembers()) + foreach (var member in currentType.GetMembers()) { if (member is not IPropertySymbol property) { @@ -632,7 +622,7 @@ private static void CreateContextParameter(TagHelperDescriptorBuilder builder, s kind = PropertyKind.Ignored; } - if (!property.GetAttributes().Any(static a => a.AttributeClass.HasFullName(ComponentsApi.ParameterAttribute.MetadataName))) + if (!property.GetAttributes().Any(static a => a.HasFullName(ComponentsApi.ParameterAttribute.MetadataName))) { if (property.IsOverride) { @@ -661,9 +651,9 @@ var p when IsDelegate(p) => PropertyKind.Delegate, results.Add((property, kind)); } - type = type.BaseType; + currentType = currentType.BaseType; } - while (type != null); + while (currentType != null); return results.DrainToImmutable(); diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs index 4a7d1c98cc2..3953596d2f9 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/DefaultTagHelperDescriptorProvider.cs @@ -1,25 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; namespace Microsoft.CodeAnalysis.Razor; -public sealed class DefaultTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider +public sealed class DefaultTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - public int Order { get; set; } - - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; @@ -37,7 +30,7 @@ public void Execute(TagHelperDescriptorProviderContext context) } private class Collector( - Compilation compilation, ISymbol targetSymbol, DefaultTagHelperDescriptorFactory factory, INamedTypeSymbol tagHelperTypeSymbol) + Compilation compilation, ISymbol? targetSymbol, DefaultTagHelperDescriptorFactory factory, INamedTypeSymbol tagHelperTypeSymbol) : TagHelperCollector(compilation, targetSymbol) { private readonly DefaultTagHelperDescriptorFactory _factory = factory; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs index 7817c7fafa5..f89840fde8b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs @@ -1,10 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using Microsoft.AspNetCore.Razor.PooledObjects; @@ -12,18 +10,11 @@ namespace Microsoft.CodeAnalysis.Razor; -internal class EventHandlerTagHelperDescriptorProvider : ITagHelperDescriptorProvider +internal sealed class EventHandlerTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - public int Order { get; set; } - - 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); var compilation = context.Compilation; @@ -39,7 +30,7 @@ public void Execute(TagHelperDescriptorProviderContext context) collector.Collect(context); } - private class Collector(Compilation compilation, ISymbol targetSymbol, INamedTypeSymbol eventHandlerAttribute) + private class Collector(Compilation compilation, ISymbol? targetSymbol, INamedTypeSymbol eventHandlerAttribute) : TagHelperCollector(compilation, targetSymbol) { private readonly INamedTypeSymbol _eventHandlerAttribute = eventHandlerAttribute; @@ -63,30 +54,63 @@ protected override void Collect(ISymbol symbol, ICollection { if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, _eventHandlerAttribute)) { - var enablePreventDefault = false; - var enableStopPropagation = false; - if (attribute.ConstructorArguments.Length == 4) + if (!AttributeArgs.TryGet(attribute, out var values)) { - enablePreventDefault = (bool)attribute.ConstructorArguments[2].Value; - enableStopPropagation = (bool)attribute.ConstructorArguments[3].Value; + // If this occurs, the EventHandlerAttribute type has been broken. + Assumed.Unreachable(); } var (typeName, namespaceName) = displayNames.GetNames(); - var constructorArguments = attribute.ConstructorArguments; - - results.Add(CreateTagHelper( - typeName, - namespaceName, - type.Name, - (string)constructorArguments[0].Value, - (INamedTypeSymbol)constructorArguments[1].Value, - enablePreventDefault, - enableStopPropagation)); + results.Add(CreateTagHelper(typeName, namespaceName, type.Name, values)); } } } } + private readonly record struct AttributeArgs( + string Attribute, + INamedTypeSymbol EventArgsType, + bool EnableStopPropagation, + bool EnablePreventDefault) + { + public static bool TryGet(AttributeData attribute, out AttributeArgs args) + { + // EventHandlerAttribute has two constructors: + // + // - EventHandlerAttribute(string attributeName, Type eventArgsType); + // - EventHandlerAttribute(string attributeName, Type eventArgsType, bool enableStopPropagation, bool enablePreventDefault); + + args = default; + + var arguments = attribute.ConstructorArguments; + + if (arguments.Length is not (2 or 4)) + { + return false; + } + + if (arguments[0] is not { Value: string attributeName } || + arguments[1] is not { Value: INamedTypeSymbol eventArgsType }) + { + return false; + } + + // TODO: The enablePreventDefault and enableStopPropagation arguments are incorrectly swapped! + // However, they have been that way since the 4-argument constructor variant was introduced + // in https://github.com/dotnet/razor/commit/7635bba6ef2d3e6798d0846ceb96da6d5908e1b0. + // Fixing this is tracked be https://github.com/dotnet/razor/issues/10497 + + if (arguments is not [.., { Value: bool enablePreventDefault }, { Value: bool enableStopPropagation }]) + { + enableStopPropagation = false; + enablePreventDefault = false; + } + + args = new(attributeName, eventArgsType, enableStopPropagation, enablePreventDefault); + return true; + } + } + /// /// Helper to avoid computing various type-based names until necessary. /// @@ -108,11 +132,10 @@ private static TagHelperDescriptor CreateTagHelper( string typeName, string typeNamespace, string typeNameIdentifier, - string attribute, - INamedTypeSymbol eventArgsType, - bool enablePreventDefault, - bool enableStopPropagation) + AttributeArgs args) { + var (attribute, eventArgsType, enableStopPropagation, enablePreventDefault) = args; + var attributeName = "@" + attribute; var eventArgType = eventArgsType.ToDisplayString(); _ = TagHelperDescriptorBuilder.GetPooledInstance( diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs index 208e1ecc038..c04ecadf5fc 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/FormNameTagHelperDescriptorProvider.cs @@ -3,27 +3,21 @@ using System; using System.Linq; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; namespace Microsoft.CodeAnalysis.Razor; -internal sealed class FormNameTagHelperDescriptorProvider : ITagHelperDescriptorProvider +// Run after the component tag helper provider +internal sealed class FormNameTagHelperDescriptorProvider() : TagHelperDescriptorProviderBase(order: 1000) { private static readonly Lazy s_formNameTagHelper = new(CreateFormNameTagHelper); - // Run after the component tag helper provider - 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); var compilation = context.Compilation; diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs index 359071fbc3e..0bafbe36bf6 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/KeyTagHelperDescriptorProvider.cs @@ -1,30 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; namespace Microsoft.CodeAnalysis.Razor; -internal class KeyTagHelperDescriptorProvider : ITagHelperDescriptorProvider +// Run after the component tag helper provider +internal sealed class KeyTagHelperDescriptorProvider() : TagHelperDescriptorProviderBase(order: 1000) { - private static TagHelperDescriptor s_keyTagHelper; - - // Run after the component tag helper provider - public int Order { get; set; } = 1000; + private static readonly Lazy s_keyTagHelper = new(CreateKeyTagHelper); - 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); var compilation = context.Compilation; @@ -41,50 +33,45 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - context.Results.Add(GetOrCreateKeyTagHelper()); + context.Results.Add(s_keyTagHelper.Value); } - private static TagHelperDescriptor GetOrCreateKeyTagHelper() + private static TagHelperDescriptor CreateKeyTagHelper() { - return s_keyTagHelper ??= CreateKeyTagHelper(); - - static TagHelperDescriptor CreateKeyTagHelper() - { - using var _ = TagHelperDescriptorBuilder.GetPooledInstance( - ComponentMetadata.Key.TagHelperKind, "Key", ComponentsApi.AssemblyName, - out var builder); + using var _ = TagHelperDescriptorBuilder.GetPooledInstance( + ComponentMetadata.Key.TagHelperKind, "Key", ComponentsApi.AssemblyName, + out var builder); - builder.CaseSensitive = true; - builder.SetDocumentation(DocumentationDescriptor.KeyTagHelper); + builder.CaseSensitive = true; + builder.SetDocumentation(DocumentationDescriptor.KeyTagHelper); - builder.SetMetadata( - SpecialKind(ComponentMetadata.Key.TagHelperKind), - MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), - RuntimeName(ComponentMetadata.Key.RuntimeName), - TypeName("Microsoft.AspNetCore.Components.Key")); + builder.SetMetadata( + SpecialKind(ComponentMetadata.Key.TagHelperKind), + MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), + RuntimeName(ComponentMetadata.Key.RuntimeName), + TypeName("Microsoft.AspNetCore.Components.Key")); - builder.TagMatchingRule(rule => + builder.TagMatchingRule(rule => + { + rule.TagName = "*"; + rule.Attribute(attribute => { - rule.TagName = "*"; - rule.Attribute(attribute => - { - attribute.Name = "@key"; - attribute.SetMetadata(Attributes.IsDirectiveAttribute); - }); + attribute.Name = "@key"; + attribute.SetMetadata(Attributes.IsDirectiveAttribute); }); + }); - builder.BindAttribute(attribute => - { - attribute.SetDocumentation(DocumentationDescriptor.KeyTagHelper); - attribute.Name = "@key"; + builder.BindAttribute(attribute => + { + attribute.SetDocumentation(DocumentationDescriptor.KeyTagHelper); + attribute.Name = "@key"; - attribute.TypeName = typeof(object).FullName; - attribute.SetMetadata( - PropertyName("Key"), - IsDirectiveAttribute); - }); + attribute.TypeName = typeof(object).FullName; + attribute.SetMetadata( + PropertyName("Key"), + IsDirectiveAttribute); + }); - return builder.Build(); - } + return builder.Build(); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs index 40f50698d20..e6cb16f5489 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RefTagHelperDescriptorProvider.cs @@ -1,30 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; namespace Microsoft.CodeAnalysis.Razor; -internal class RefTagHelperDescriptorProvider : ITagHelperDescriptorProvider +// Run after the component tag helper provider, because later we may want component-type-specific variants of this +internal sealed class RefTagHelperDescriptorProvider() : TagHelperDescriptorProviderBase(order: 1000) { - private static TagHelperDescriptor s_refTagHelper; - - // Run after the component tag helper provider, because later we may want component-type-specific variants of this - public int Order { get; set; } = 1000; + private static readonly Lazy s_refTagHelper = new(CreateRefTagHelper); - 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); var compilation = context.Compilation; @@ -41,50 +33,45 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - context.Results.Add(GetOrCreateRefTagHelper()); + context.Results.Add(s_refTagHelper.Value); } - private static TagHelperDescriptor GetOrCreateRefTagHelper() + private static TagHelperDescriptor CreateRefTagHelper() { - return s_refTagHelper ??= CreateRefTagHelper(); - - static TagHelperDescriptor CreateRefTagHelper() - { - using var _ = TagHelperDescriptorBuilder.GetPooledInstance( - ComponentMetadata.Ref.TagHelperKind, "Ref", ComponentsApi.AssemblyName, - out var builder); + using var _ = TagHelperDescriptorBuilder.GetPooledInstance( + ComponentMetadata.Ref.TagHelperKind, "Ref", ComponentsApi.AssemblyName, + out var builder); - builder.CaseSensitive = true; - builder.SetDocumentation(DocumentationDescriptor.RefTagHelper); + builder.CaseSensitive = true; + builder.SetDocumentation(DocumentationDescriptor.RefTagHelper); - builder.SetMetadata( - SpecialKind(ComponentMetadata.Ref.TagHelperKind), - MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), - RuntimeName(ComponentMetadata.Ref.RuntimeName), - TypeName("Microsoft.AspNetCore.Components.Ref")); + builder.SetMetadata( + SpecialKind(ComponentMetadata.Ref.TagHelperKind), + MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), + RuntimeName(ComponentMetadata.Ref.RuntimeName), + TypeName("Microsoft.AspNetCore.Components.Ref")); - builder.TagMatchingRule(rule => + builder.TagMatchingRule(rule => + { + rule.TagName = "*"; + rule.Attribute(attribute => { - rule.TagName = "*"; - rule.Attribute(attribute => - { - attribute.Name = "@ref"; - attribute.SetMetadata(Attributes.IsDirectiveAttribute); - }); + attribute.Name = "@ref"; + attribute.SetMetadata(Attributes.IsDirectiveAttribute); }); + }); - builder.BindAttribute(attribute => - { - attribute.SetDocumentation(DocumentationDescriptor.RefTagHelper); - attribute.Name = "@ref"; + builder.BindAttribute(attribute => + { + attribute.SetDocumentation(DocumentationDescriptor.RefTagHelper); + attribute.Name = "@ref"; - attribute.TypeName = typeof(object).FullName; - attribute.SetMetadata( - PropertyName("Ref"), - IsDirectiveAttribute); - }); + attribute.TypeName = typeof(object).FullName; + attribute.SetMetadata( + PropertyName("Ref"), + IsDirectiveAttribute); + }); - return builder.Build(); - } + return builder.Build(); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs index 8feb1499e26..a18227a82dd 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/RenderModeTagHelperDescriptorProvider.cs @@ -1,30 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable enable - using System; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; namespace Microsoft.CodeAnalysis.Razor; -internal sealed class RenderModeTagHelperDescriptorProvider : ITagHelperDescriptorProvider +// Run after the component tag helper provider +internal sealed class RenderModeTagHelperDescriptorProvider() : TagHelperDescriptorProviderBase(order: 1000) { - private static readonly Lazy s_refTagHelper = new(CreateRenderModeTagHelper); - - // Run after the component tag helper provider - public int Order { get; set; } = 1000; - - public RazorEngine? Engine { get; set; } + private static readonly Lazy s_renderModeTagHelper = new(CreateRenderModeTagHelper); - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; @@ -41,7 +33,7 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - context.Results.Add(s_refTagHelper.Value); + context.Results.Add(s_renderModeTagHelper.Value); } private static TagHelperDescriptor CreateRenderModeTagHelper() diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs index 5ec98d1eaa5..2db0111c0b7 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SplatTagHelperDescriptorProvider.cs @@ -1,30 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.Language.Components; using static Microsoft.AspNetCore.Razor.Language.CommonMetadata; namespace Microsoft.CodeAnalysis.Razor; -internal class SplatTagHelperDescriptorProvider : ITagHelperDescriptorProvider +internal sealed class SplatTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - private static TagHelperDescriptor s_splatTagHelper; - - // Order doesn't matter - public int Order { get; set; } + private static readonly Lazy s_splatTagHelper = new(CreateSplatTagHelper); - 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); var compilation = context.Compilation; @@ -41,50 +32,45 @@ public void Execute(TagHelperDescriptorProviderContext context) return; } - context.Results.Add(GetOrCreateSplatTagHelper()); + context.Results.Add(s_splatTagHelper.Value); } - private static TagHelperDescriptor GetOrCreateSplatTagHelper() + private static TagHelperDescriptor CreateSplatTagHelper() { - return s_splatTagHelper ??= CreateSplatTagHelper(); - - static TagHelperDescriptor CreateSplatTagHelper() - { - using var _ = TagHelperDescriptorBuilder.GetPooledInstance( - ComponentMetadata.Splat.TagHelperKind, "Attributes", ComponentsApi.AssemblyName, - out var builder); + using var _ = TagHelperDescriptorBuilder.GetPooledInstance( + ComponentMetadata.Splat.TagHelperKind, "Attributes", ComponentsApi.AssemblyName, + out var builder); - builder.CaseSensitive = true; - builder.SetDocumentation(DocumentationDescriptor.SplatTagHelper); + builder.CaseSensitive = true; + builder.SetDocumentation(DocumentationDescriptor.SplatTagHelper); - builder.SetMetadata( - SpecialKind(ComponentMetadata.Splat.TagHelperKind), - MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), - RuntimeName(ComponentMetadata.Splat.RuntimeName), - TypeName("Microsoft.AspNetCore.Components.Attributes")); + builder.SetMetadata( + SpecialKind(ComponentMetadata.Splat.TagHelperKind), + MakeTrue(TagHelperMetadata.Common.ClassifyAttributesOnly), + RuntimeName(ComponentMetadata.Splat.RuntimeName), + TypeName("Microsoft.AspNetCore.Components.Attributes")); - builder.TagMatchingRule(rule => + builder.TagMatchingRule(rule => + { + rule.TagName = "*"; + rule.Attribute(attribute => { - rule.TagName = "*"; - rule.Attribute(attribute => - { - attribute.Name = "@attributes"; - attribute.SetMetadata(Attributes.IsDirectiveAttribute); - }); + attribute.Name = "@attributes"; + attribute.SetMetadata(Attributes.IsDirectiveAttribute); }); + }); - builder.BindAttribute(attribute => - { - attribute.SetDocumentation(DocumentationDescriptor.SplatTagHelper); - attribute.Name = "@attributes"; + builder.BindAttribute(attribute => + { + attribute.SetDocumentation(DocumentationDescriptor.SplatTagHelper); + attribute.Name = "@attributes"; - attribute.TypeName = typeof(object).FullName; - attribute.SetMetadata( - PropertyName("Attributes"), - IsDirectiveAttribute); - }); + attribute.TypeName = typeof(object).FullName; + attribute.SetMetadata( + PropertyName("Attributes"), + IsDirectiveAttribute); + }); - return builder.Build(); - } + return builder.Build(); } } diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SymbolExtensions.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SymbolExtensions.cs index e9bc59e3480..a280e8db8a4 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SymbolExtensions.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/SymbolExtensions.cs @@ -13,6 +13,9 @@ internal static class SymbolExtensions .WithGlobalNamespaceStyle(SymbolDisplayGlobalNamespaceStyle.Omitted) .RemoveMiscellaneousOptions(SymbolDisplayMiscellaneousOptions.UseSpecialTypes); + internal static bool HasFullName(this AttributeData attribute, string fullName) + => attribute.AttributeClass is { } attributeClass && attributeClass.HasFullName(fullName); + /// /// Checks if has the same fully qualified name as . /// diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderBase.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderBase.cs new file mode 100644 index 00000000000..0ab7a8355cb --- /dev/null +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/TagHelperDescriptorProviderBase.cs @@ -0,0 +1,11 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.AspNetCore.Razor.Language; + +public abstract class TagHelperDescriptorProviderBase(int order = 0) : RazorEngineFeatureBase, ITagHelperDescriptorProvider +{ + public int Order { get; } = order; + + public abstract void Execute(TagHelperDescriptorProviderContext context); +} diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs index 70ed5efa619..abddce93827 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTagHelperDescriptorProvider.cs @@ -1,26 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X; -public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider +public sealed class ViewComponentTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - public int Order { get; set; } - - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; @@ -42,12 +35,12 @@ private class Collector( Compilation compilation, ViewComponentTagHelperDescriptorFactory factory, INamedTypeSymbol vcAttribute, - INamedTypeSymbol nonVCAttribute) + INamedTypeSymbol? nonVCAttribute) : TagHelperCollector(compilation, targetSymbol: null) { private readonly ViewComponentTagHelperDescriptorFactory _factory = factory; private readonly INamedTypeSymbol _vcAttribute = vcAttribute; - private readonly INamedTypeSymbol _nonVCAttribute = nonVCAttribute; + private readonly INamedTypeSymbol? _nonVCAttribute = nonVCAttribute; protected override void Collect(ISymbol symbol, ICollection results) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTypeVisitor.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTypeVisitor.cs index 2baa96bc20e..610fa47c60b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTypeVisitor.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version1_X/ViewComponentTypeVisitor.cs @@ -1,23 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Collections.Generic; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X; -internal class ViewComponentTypeVisitor : SymbolVisitor +internal sealed class ViewComponentTypeVisitor : SymbolVisitor { private readonly INamedTypeSymbol _viewComponentAttribute; - private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly INamedTypeSymbol? _nonViewComponentAttribute; private readonly List _results; public ViewComponentTypeVisitor( INamedTypeSymbol viewComponentAttribute, - INamedTypeSymbol nonViewComponentAttribute, + INamedTypeSymbol? nonViewComponentAttribute, List results) { _viewComponentAttribute = viewComponentAttribute; @@ -65,7 +63,7 @@ internal bool IsViewComponent(INamedTypeSymbol symbol) AttributeIsDefined(symbol, _viewComponentAttribute); } - private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + private static bool AttributeIsDefined(INamedTypeSymbol? type, INamedTypeSymbol? queryAttribute) { if (type == null || queryAttribute == null) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs index a3c6c11d5d9..6058ae7ae52 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTagHelperDescriptorProvider.cs @@ -1,26 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X; -public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider +public sealed class ViewComponentTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - public int Order { get; set; } - - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; @@ -42,12 +35,12 @@ private class Collector( Compilation compilation, ViewComponentTagHelperDescriptorFactory factory, INamedTypeSymbol vcAttribute, - INamedTypeSymbol nonVCAttribute) + INamedTypeSymbol? nonVCAttribute) : TagHelperCollector(compilation, targetSymbol: null) { private readonly ViewComponentTagHelperDescriptorFactory _factory = factory; private readonly INamedTypeSymbol _vcAttribute = vcAttribute; - private readonly INamedTypeSymbol _nonVCAttribute = nonVCAttribute; + private readonly INamedTypeSymbol? _nonVCAttribute = nonVCAttribute; protected override void Collect(ISymbol symbol, ICollection results) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTypeVisitor.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTypeVisitor.cs index cb1ff06f5ca..7e2b8240fb5 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTypeVisitor.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc.Version2_X/ViewComponentTypeVisitor.cs @@ -1,23 +1,21 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Collections.Generic; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X; -internal class ViewComponentTypeVisitor : SymbolVisitor +internal sealed class ViewComponentTypeVisitor : SymbolVisitor { private readonly INamedTypeSymbol _viewComponentAttribute; - private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly INamedTypeSymbol? _nonViewComponentAttribute; private readonly List _results; public ViewComponentTypeVisitor( INamedTypeSymbol viewComponentAttribute, - INamedTypeSymbol nonViewComponentAttribute, + INamedTypeSymbol? nonViewComponentAttribute, List results) { _viewComponentAttribute = viewComponentAttribute; @@ -70,7 +68,7 @@ internal bool IsViewComponent(INamedTypeSymbol symbol) AttributeIsDefined(symbol, _viewComponentAttribute); } - private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + private static bool AttributeIsDefined(INamedTypeSymbol? type, INamedTypeSymbol? queryAttribute) { if (type == null || queryAttribute == null) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs index 178508686ac..2159ce7a07b 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTagHelperDescriptorProvider.cs @@ -1,26 +1,19 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - -using System; using System.Collections.Generic; +using Microsoft.AspNetCore.Razor; using Microsoft.AspNetCore.Razor.Language; using Microsoft.AspNetCore.Razor.PooledObjects; using Microsoft.CodeAnalysis; namespace Microsoft.AspNetCore.Mvc.Razor.Extensions; -public sealed class ViewComponentTagHelperDescriptorProvider : RazorEngineFeatureBase, ITagHelperDescriptorProvider +public sealed class ViewComponentTagHelperDescriptorProvider : TagHelperDescriptorProviderBase { - public int Order { get; set; } - - public void Execute(TagHelperDescriptorProviderContext context) + public override void Execute(TagHelperDescriptorProviderContext context) { - if (context == null) - { - throw new ArgumentNullException(nameof(context)); - } + ArgHelper.ThrowIfNull(context); var compilation = context.Compilation; @@ -42,12 +35,12 @@ private class Collector( Compilation compilation, ViewComponentTagHelperDescriptorFactory factory, INamedTypeSymbol vcAttribute, - INamedTypeSymbol nonVCAttribute) + INamedTypeSymbol? nonVCAttribute) : TagHelperCollector(compilation, targetSymbol: null) { private readonly ViewComponentTagHelperDescriptorFactory _factory = factory; private readonly INamedTypeSymbol _vcAttribute = vcAttribute; - private readonly INamedTypeSymbol _nonVCAttribute = nonVCAttribute; + private readonly INamedTypeSymbol? _nonVCAttribute = nonVCAttribute; protected override void Collect(ISymbol symbol, ICollection results) { diff --git a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTypeVisitor.cs b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTypeVisitor.cs index d7a48e6494f..96f3982c579 100644 --- a/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTypeVisitor.cs +++ b/src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Mvc/ViewComponentTypeVisitor.cs @@ -1,8 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#nullable disable - using System; using System.Collections.Generic; using Microsoft.CodeAnalysis; @@ -12,12 +10,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Extensions; internal class ViewComponentTypeVisitor : SymbolVisitor { private readonly INamedTypeSymbol _viewComponentAttribute; - private readonly INamedTypeSymbol _nonViewComponentAttribute; + private readonly INamedTypeSymbol? _nonViewComponentAttribute; private readonly List _results; public ViewComponentTypeVisitor( INamedTypeSymbol viewComponentAttribute, - INamedTypeSymbol nonViewComponentAttribute, + INamedTypeSymbol? nonViewComponentAttribute, List results) { _viewComponentAttribute = viewComponentAttribute; @@ -75,7 +73,7 @@ internal bool IsViewComponent(INamedTypeSymbol symbol) AttributeIsDefined(symbol, _viewComponentAttribute); } - private static bool AttributeIsDefined(INamedTypeSymbol type, INamedTypeSymbol queryAttribute) + private static bool AttributeIsDefined(INamedTypeSymbol? type, INamedTypeSymbol? queryAttribute) { if (type == null || queryAttribute == null) { From 9f6c7b6186f9a30f785ac9c8531bdcfcffde08ac Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 8 Aug 2024 13:16:01 -0700 Subject: [PATCH 8/8] Clean up CompilationTagHelperResolver --- .../CompilationTagHelperResolver.cs | 63 +++++++------------ .../Telemetry/ITelemetryReporter.cs | 2 +- .../Telemetry/NoOpTelemetryReporter.cs | 2 +- .../Telemetry/TelemetryReporter.cs | 2 +- 4 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs index 73e1d766d06..05b2edf83cd 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/CompilationTagHelperResolver.cs @@ -1,8 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the MIT license. See License.txt in the project root for license information. -using System; -using System.Collections.Generic; +using System.Buffers; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -15,70 +14,54 @@ namespace Microsoft.AspNetCore.Razor; -internal class CompilationTagHelperResolver(ITelemetryReporter? telemetryReporter) +internal sealed class CompilationTagHelperResolver(ITelemetryReporter telemetryReporter) { - private readonly ITelemetryReporter? _telemetryReporter = telemetryReporter; + private readonly ITelemetryReporter _telemetryReporter = telemetryReporter; public async ValueTask> GetTagHelpersAsync( - Project workspaceProject, + Project project, RazorProjectEngine projectEngine, CancellationToken cancellationToken) { - if (workspaceProject is null) - { - throw new ArgumentNullException(nameof(workspaceProject)); - } - - if (projectEngine is null) - { - throw new ArgumentNullException(nameof(projectEngine)); - } + var providers = projectEngine.Engine.Features + .OfType() + .OrderBy(static f => f.Order) + .ToImmutableArray(); - var providers = projectEngine.Engine.Features.OfType().OrderBy(f => f.Order).ToArray(); - if (providers.Length == 0) + if (providers is []) { return []; } - var compilation = await workspaceProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); if (compilation is null || !CompilationTagHelperFeature.IsValidCompilation(compilation)) { return []; } - using var _ = HashSetPool.GetPooledObject(out var results); + using var pooledHashSet = HashSetPool.GetPooledObject(out var results); + using var pooledWatch = StopwatchPool.GetPooledObject(out var watch); + using var pooledSpan = ArrayPool.Shared.GetPooledArraySpan(minimumLength: providers.Length, out var properties); + var context = new TagHelperDescriptorProviderContext(compilation, results) { ExcludeHidden = true, IncludeDocumentation = true }; - ExecuteProviders(providers, context, _telemetryReporter); - - return results.ToImmutableArray(); - - static void ExecuteProviders(ITagHelperDescriptorProvider[] providers, TagHelperDescriptorProviderContext context, ITelemetryReporter? telemetryReporter) + for (var i = 0; i < providers.Length; i++) { - using var _ = StopwatchPool.GetPooledObject(out var watch); + var provider = providers[i]; - Property[]? properties = null; + watch.Restart(); + provider.Execute(context); + watch.Stop(); - for (var i = 0; i < providers.Length; i++) - { - var provider = providers[i]; - watch.Restart(); - provider.Execute(context); - watch.Stop(); + properties[i] = new($"{provider.GetType().Name}.elapsedtimems", watch.ElapsedMilliseconds); + } - if (telemetryReporter is not null) - { - properties ??= new Property[providers.Length]; - var propertyName = $"{provider.GetType().Name}.elapsedtimems"; - properties[i] = new(propertyName, watch.ElapsedMilliseconds); - } - } + _telemetryReporter.ReportEvent("taghelperresolver/gettaghelpers", Severity.Normal, properties); - telemetryReporter?.ReportEvent("taghelperresolver/gettaghelpers", Severity.Normal, properties.AssumeNotNull()); - } + return [.. results]; } } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs index 0530e181e21..7f0814a98b6 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/ITelemetryReporter.cs @@ -19,7 +19,7 @@ internal interface ITelemetryReporter void ReportEvent(string name, Severity severity, Property property); void ReportEvent(string name, Severity severity, Property property1, Property property2); void ReportEvent(string name, Severity severity, Property property1, Property property2, Property property3); - void ReportEvent(string name, Severity severity, params Property[] properties); + void ReportEvent(string name, Severity severity, params ReadOnlySpan properties); void ReportFault(Exception exception, string? message, params object?[] @params); } diff --git a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs index 29dcb3101a7..28a937da055 100644 --- a/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs +++ b/src/Razor/src/Microsoft.AspNetCore.Razor.ProjectEngineHost/Telemetry/NoOpTelemetryReporter.cs @@ -44,7 +44,7 @@ public void ReportEvent(string name, Severity severity, Property property1, Prop { } - public void ReportEvent(string name, Severity severity, params Property[] properties) + public void ReportEvent(string name, Severity severity, params ReadOnlySpan properties) { } diff --git a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs index 7542ae4a7b6..f6de565c009 100644 --- a/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs +++ b/src/Razor/src/Microsoft.VisualStudio.LanguageServices.Razor/Telemetry/TelemetryReporter.cs @@ -72,7 +72,7 @@ public void ReportEvent(string name, Severity severity, Property property1, Prop Report(telemetryEvent); } - public void ReportEvent(string name, Severity severity, params Property[] properties) + public void ReportEvent(string name, Severity severity, params ReadOnlySpan properties) { var telemetryEvent = new TelemetryEvent(GetEventName(name), ConvertSeverity(severity));