diff options
author | Mackinnon Buck <mackinnon.buck@gmail.com> | 2021-09-03 03:53:09 +0300 |
---|---|---|
committer | Mackinnon Buck <mackinnon.buck@gmail.com> | 2021-09-03 03:53:09 +0300 |
commit | 506322c5726000fc543e1786868a38044cd385a3 (patch) | |
tree | 747ad306f5759acf0aed346174b6f0df507f60a2 | |
parent | 848cdb37a63285462d10890255ae3034f3db461c (diff) |
Improved design for inherited parameterst-mbuck/code-gen-component-parameters
10 files changed, 165 insertions, 120 deletions
diff --git a/src/Components/Components/src/ComponentBase.cs b/src/Components/Components/src/ComponentBase.cs index d9dd102bf8..65db35c444 100644 --- a/src/Components/Components/src/ComponentBase.cs +++ b/src/Components/Components/src/ComponentBase.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Components.Rendering; namespace Microsoft.AspNetCore.Components @@ -19,7 +20,7 @@ namespace Microsoft.AspNetCore.Components /// Optional base class for components. Alternatively, components may /// implement <see cref="IComponent"/> directly. /// </summary> - public abstract class ComponentBase : IComponent, IHandleEvent, IHandleAfterRender + public abstract class ComponentBase : IComponent, IHandleEvent, IHandleAfterRender, IPropertySetterProvider { private readonly RenderFragment _renderFragment; private RenderHandle _renderHandle; @@ -28,6 +29,9 @@ namespace Microsoft.AspNetCore.Components private bool _hasPendingQueuedRender; private bool _hasCalledOnAfterRender; + /// <inheritdoc/> + public virtual IUnmatchedValuesPropertySetter? UnmatchedValuesPropertySetter => default; + /// <summary> /// Constructs an instance of <see cref="ComponentBase"/>. /// </summary> @@ -221,6 +225,13 @@ namespace Microsoft.AspNetCore.Components } } + /// <inheritdoc/> + public virtual bool TryGetSetter(string propertyName, [NotNullWhen(true)] out IPropertySetter? propertySetter) + { + propertySetter = default; + return false; + } + private async Task RunInitAndSetParametersAsync() { OnInitialized(); diff --git a/src/Components/Components/src/ParameterView.cs b/src/Components/Components/src/ParameterView.cs index ae3fe17fcf..6eb97f0685 100644 --- a/src/Components/Components/src/ParameterView.cs +++ b/src/Components/Components/src/ParameterView.cs @@ -260,6 +260,21 @@ namespace Microsoft.AspNetCore.Components } /// <summary> + /// For each parameter property on <paramref name="target"/>, updates its value to + /// match the corresponding entry in the <see cref="ParameterView"/>. + /// </summary> + /// <param name="target">An object that has a public writable property matching each parameter's name and type.</param> + public void SetParameterProperties(IPropertySetterProvider target) + { + if (target is null) + { + throw new ArgumentNullException(nameof(target)); + } + + ComponentProperties.SetProperties(this, target); + } + + /// <summary> /// An enumerator that iterates through a <see cref="ParameterView"/>. /// </summary> diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index aa95835c55..7ccbe039f2 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -40,6 +40,7 @@ Microsoft.AspNetCore.Components.NavigationOptions.ForceLoad.init -> void Microsoft.AspNetCore.Components.NavigationOptions.NavigationOptions() -> void Microsoft.AspNetCore.Components.NavigationOptions.ReplaceHistoryEntry.get -> bool Microsoft.AspNetCore.Components.NavigationOptions.ReplaceHistoryEntry.init -> void +Microsoft.AspNetCore.Components.ParameterView.SetParameterProperties(Microsoft.AspNetCore.Components.IPropertySetterProvider! target) -> void Microsoft.AspNetCore.Components.RenderHandle.IsRenderingOnMetadataUpdate.get -> bool Microsoft.AspNetCore.Components.RenderTree.Renderer.RemoveRootComponent(int componentId) -> void Microsoft.AspNetCore.Components.IPersistentComponentStateStore @@ -127,6 +128,8 @@ static Microsoft.AspNetCore.Components.NavigationManagerExtensions.GetUriWithQue static Microsoft.AspNetCore.Components.NavigationManagerExtensions.GetUriWithQueryParameters(this Microsoft.AspNetCore.Components.NavigationManager! navigationManager, System.Collections.Generic.IReadOnlyDictionary<string!, object?>! parameters) -> string! static Microsoft.AspNetCore.Components.NavigationManagerExtensions.GetUriWithQueryParameters(this Microsoft.AspNetCore.Components.NavigationManager! navigationManager, string! uri, System.Collections.Generic.IReadOnlyDictionary<string!, object?>! parameters) -> string! static Microsoft.AspNetCore.Components.ParameterView.FromDictionary(System.Collections.Generic.IDictionary<string!, object?>! parameters) -> Microsoft.AspNetCore.Components.ParameterView +virtual Microsoft.AspNetCore.Components.ComponentBase.TryGetSetter(string! propertyName, out Microsoft.AspNetCore.Components.IPropertySetter? propertySetter) -> bool +virtual Microsoft.AspNetCore.Components.ComponentBase.UnmatchedValuesPropertySetter.get -> Microsoft.AspNetCore.Components.IUnmatchedValuesPropertySetter? virtual Microsoft.AspNetCore.Components.NavigationManager.NavigateToCore(string! uri, Microsoft.AspNetCore.Components.NavigationOptions options) -> void virtual Microsoft.AspNetCore.Components.NavigationManager.NavigateToCore(string! uri, bool forceLoad) -> void virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo? fieldInfo, System.EventArgs! eventArgs) -> System.Threading.Tasks.Task! diff --git a/src/Components/Components/src/Reflection/ComponentProperties.cs b/src/Components/Components/src/Reflection/ComponentProperties.cs index 1fcc915ab2..7ac15057b2 100644 --- a/src/Components/Components/src/Reflection/ComponentProperties.cs +++ b/src/Components/Components/src/Reflection/ComponentProperties.cs @@ -26,19 +26,27 @@ namespace Microsoft.AspNetCore.Components.Reflection throw new ArgumentNullException(nameof(target)); } - var targetType = target.GetType(); + var writers = GetWritersForType(target.GetType()); + SetProperties(parameters, writers, target); + } - if (target is not IPropertySetterProvider propertySetterProvider) + public static void SetProperties(in ParameterView parameters, IPropertySetterProvider target) + { + if (target == null) { - if (!_cachedWritersByType.TryGetValue(targetType, out var writers)) - { - writers = new WritersForType(targetType); - _cachedWritersByType[targetType] = writers; - } - - propertySetterProvider = writers; + throw new ArgumentNullException(nameof(target)); } + var provider = new FallbackPropertySetterProvider(target); + SetProperties(parameters, provider, target); + } + + private static void SetProperties<TProvider>( + in ParameterView parameters, + in TProvider propertySetterProvider, + object target) where TProvider : IPropertySetterProvider + { + var targetType = target.GetType(); var unmatchedValuesSetter = propertySetterProvider.UnmatchedValuesPropertySetter; // The logic is split up for simplicity now that we have CaptureUnmatchedValues parameters. @@ -48,13 +56,13 @@ namespace Microsoft.AspNetCore.Components.Reflection foreach (var parameter in parameters) { var parameterName = parameter.Name; - if (!propertySetterProvider.TryGetSetter(parameterName, out var writer)) + if (!propertySetterProvider.TryGetSetter(parameterName, out var setter)) { // Case 1: There is nowhere to put this value. ThrowForUnknownIncomingParameterName(targetType, parameterName); throw null; // Unreachable } - else if (writer.Cascading && !parameter.Cascading) + else if (setter.Cascading && !parameter.Cascading) { // We don't allow you to set a cascading parameter with a non-cascading value. Put another way: // cascading parameters are not part of the public API of a component, so it's not reasonable @@ -65,7 +73,7 @@ namespace Microsoft.AspNetCore.Components.Reflection ThrowForSettingCascadingParameterWithNonCascadingValue(targetType, parameterName); throw null; // Unreachable } - else if (!writer.Cascading && parameter.Cascading) + else if (!setter.Cascading && parameter.Cascading) { // We're giving a more specific error here because trying to set a non-cascading parameter // with a cascading value is likely deliberate (but not supported), or is a bug in our code. @@ -73,7 +81,7 @@ namespace Microsoft.AspNetCore.Components.Reflection throw null; // Unreachable } - SetProperty(target, writer, parameterName, parameter.Value); + SetProperty(target, setter, parameterName, parameter.Value); } } else @@ -89,9 +97,9 @@ namespace Microsoft.AspNetCore.Components.Reflection isCaptureUnmatchedValuesParameterSetExplicitly = true; } - if (propertySetterProvider.TryGetSetter(parameterName, out var writer)) + if (propertySetterProvider.TryGetSetter(parameterName, out var setter)) { - if (!writer.Cascading && parameter.Cascading) + if (!setter.Cascading && parameter.Cascading) { // Don't allow an "extra" cascading value to be collected - or don't allow a non-cascading // parameter to be set with a cascading value. @@ -100,7 +108,7 @@ namespace Microsoft.AspNetCore.Components.Reflection ThrowForSettingParameterWithCascadingValue(targetType, parameterName); throw null; // Unreachable } - else if (writer.Cascading && !parameter.Cascading) + else if (setter.Cascading && !parameter.Cascading) { // Allow unmatched parameters to collide with the names of cascading parameters. This is // valid because cascading parameter names are not part of the public API. There's no @@ -111,7 +119,7 @@ namespace Microsoft.AspNetCore.Components.Reflection } else { - SetProperty(target, writer, parameterName, parameter.Value); + SetProperty(target, setter, parameterName, parameter.Value); } } else @@ -166,6 +174,42 @@ namespace Microsoft.AspNetCore.Components.Reflection } } + // This struct wraps the provided IPropertySetterProvider, using a fallback, reflection-based + // IPropertySetterProvider when the target cannot provide a property. + private struct FallbackPropertySetterProvider : IPropertySetterProvider + { + private readonly IPropertySetterProvider _target; + private IPropertySetterProvider? _fallback; + + private IPropertySetterProvider Fallback + => _fallback ??= GetWritersForType(_target.GetType()); + + public FallbackPropertySetterProvider(IPropertySetterProvider target) + { + _target = target; + _fallback = default; + } + + public IUnmatchedValuesPropertySetter? UnmatchedValuesPropertySetter + => _target.UnmatchedValuesPropertySetter + ?? Fallback.UnmatchedValuesPropertySetter; + + public bool TryGetSetter(string propertyName, [NotNullWhen(true)] out IPropertySetter? propertySetter) + => _target.TryGetSetter(propertyName, out propertySetter) + || Fallback.TryGetSetter(propertyName, out propertySetter); + } + + private static WritersForType GetWritersForType(Type targetType) + { + if (!_cachedWritersByType.TryGetValue(targetType, out var writers)) + { + writers = new WritersForType(targetType); + _cachedWritersByType[targetType] = writers; + } + + return writers; + } + internal static IEnumerable<PropertyInfo> GetCandidateBindableProperties([DynamicallyAccessedMembers(Component)] Type targetType) => MemberAssignment.GetPropertiesIncludingInherited(targetType, BindablePropertyFlags); @@ -319,7 +363,7 @@ namespace Microsoft.AspNetCore.Components.Reflection } } - public bool TryGetSetter(string parameterName, [MaybeNullWhen(false)] out IPropertySetter writer) + public bool TryGetSetter(string parameterName, [MaybeNullWhen(false)] out IPropertySetter setter) { // In intensive parameter-passing scenarios, one of the most expensive things we do is the // lookup from parameterName to writer. Pre-5.0 that was because of the string hashing. @@ -328,9 +372,9 @@ namespace Microsoft.AspNetCore.Components.Reflection // having to hash the string. We only fall back on hashing the string if the cache gets full, // which would only be in very unusual situations because components don't typically have many // parameters, and the parameterName strings usually come from compile-time constants. - if (!_referenceEqualityWritersCache.TryGetValue(parameterName, out writer)) + if (!_referenceEqualityWritersCache.TryGetValue(parameterName, out setter)) { - _underlyingWriters.TryGetValue(parameterName, out writer); + _underlyingWriters.TryGetValue(parameterName, out setter); // Note that because we're not locking around this, it's possible we might // actually write more than MaxCachedWriterLookups entries due to concurrent @@ -341,11 +385,11 @@ namespace Microsoft.AspNetCore.Components.Reflection // being passed as catch-all parameter values. if (_referenceEqualityWritersCache.Count < MaxCachedWriterLookups) { - _referenceEqualityWritersCache.TryAdd(parameterName, writer); + _referenceEqualityWritersCache.TryAdd(parameterName, setter); } } - return writer != null; + return setter != null; } } } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs index 5215d3b35b..0da1c22cc3 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentDesignTimeNodeWriter.cs @@ -804,13 +804,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components } } - public override void WriteComponentParameterData(CodeRenderingContext context, ComponentParameterDataIntermediateNode node) - { - WriteUnmatchedValuesPropertySetterProperty(context); - WriteTryGetSetterSignature(context); - WriteTryGetSetterDefaultBody(context); - } - public override void WriteTemplate(CodeRenderingContext context, TemplateIntermediateNode node) { if (context == null) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs index d3ca5fa4f4..e5f4dd340e 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentNodeWriter.cs @@ -273,43 +273,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Components } } - protected static void WriteUnmatchedValuesPropertySetterProperty(CodeRenderingContext context) - { - context.CodeWriter.Write(ComponentsApi.IUnmatchedValuesPropertySetter.FullTypeName); - context.CodeWriter.Write(" "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.FullTypeName); - context.CodeWriter.Write("."); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.UnmatchedValuesPropertySetter); - context.CodeWriter.WriteLine(" { get; }"); - } - - protected static void WriteTryGetSetterSignature(CodeRenderingContext context) - { - context.CodeWriter.Write("bool "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.FullTypeName); - context.CodeWriter.Write("."); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.TryGetSetter); - context.CodeWriter.Write("("); - context.CodeWriter.Write("string "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertyNameParameter); - context.CodeWriter.Write(", "); - context.CodeWriter.Write("out "); - context.CodeWriter.Write(ComponentsApi.IPropertySetter.FullTypeName); - context.CodeWriter.Write(" "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); - context.CodeWriter.WriteLine(")"); - } - - protected static void WriteTryGetSetterDefaultBody(CodeRenderingContext context) - { - using (context.CodeWriter.BuildScope()) - { - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); - context.CodeWriter.WriteLine(" = default;"); - context.CodeWriter.WriteLine("return false;"); - } - } - protected List<TypeInferenceMethodParameter> GetTypeInferenceMethodParameters(ComponentTypeInferenceMethodIntermediateNode node) { var p = new List<TypeInferenceMethodParameter>(); diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentPropertySetterProviderPass.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentPropertySetterProviderPass.cs index 8e96aa960d..48afd4ce1c 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentPropertySetterProviderPass.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentPropertySetterProviderPass.cs @@ -26,8 +26,6 @@ internal class ComponentPropertySetterProviderPass : ComponentIntermediateNodePa BuildComponentParameterData(codeDocument.GetTagHelperContext(), componentParameterDataNode); - primaryClass.Interfaces.Add(ComponentsApi.IPropertySetterProvider.FullTypeName); - var nodeParameterDataBuilder = IntermediateNodeBuilder.Create(primaryClass); nodeParameterDataBuilder.Add(componentParameterDataNode); } diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs index 2d52b00052..941dd97b56 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/src/Components/ComponentRuntimeNodeWriter.cs @@ -742,62 +742,78 @@ namespace Microsoft.AspNetCore.Razor.Language.Components // 2. Handle properties capturing unmatched values. // 3. Utilize existing CodeWriter extensions where possible. - var hasParameters = node.ParameterData.Count > 0; - - if (hasParameters) + if (node.ParameterData.Count == 0) { - // Writes something like: - // private static readonly Lazy<Dictionary<string, DelegatePropertySetter<MyComponent>>> __propertyWriters = new(static () => new() - // { - // [nameof(Param1)] = new(static (c, v) => c.Param1 = (bool)value), - // ... - // }); - context.CodeWriter.Write("private static readonly Lazy<Dictionary<string, "); + return; + } + + // Writes something like: + // + // private static readonly Lazy<Dictionary<string, IPropertySetter>> __propertyWriters = new(static () => new() + // { + // [nameof(Param1)] = new DelegatePropertySetter<MyComponent>(static (c, v) => c.Param1 = (bool)value), + // ... + // }); + context.CodeWriter.Write("private static readonly Lazy<Dictionary<string, "); + context.CodeWriter.Write(ComponentsApi.IPropertySetter.FullTypeName); + context.CodeWriter.Write(">> "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySettersField); + context.CodeWriter.WriteLine("= new(static () => new()"); + context.CodeWriter.WriteLine("{"); + context.CodeWriter.CurrentIndent += context.CodeWriter.TabSize; + + foreach (var parameterData in node.ParameterData) + { + context.CodeWriter.Write("[nameof("); + context.CodeWriter.Write(parameterData.Name); + context.CodeWriter.Write(")] = new "); context.CodeWriter.Write(ComponentsApi.DelegatePropertySetter.FullTypeName); context.CodeWriter.Write("<"); context.CodeWriter.Write(node.ComponentFullTypeName); - context.CodeWriter.Write(">>> "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySettersField); - context.CodeWriter.WriteLine("= new(static () => new()"); - context.CodeWriter.WriteLine("{"); - context.CodeWriter.CurrentIndent += context.CodeWriter.TabSize; - - foreach (var parameterData in node.ParameterData) - { - context.CodeWriter.Write("[nameof("); - context.CodeWriter.Write(parameterData.Name); - context.CodeWriter.Write(")] = new(static (c, value) => c."); - context.CodeWriter.Write(parameterData.Name); - context.CodeWriter.Write(" = ("); - context.CodeWriter.Write(parameterData.TypeName); - context.CodeWriter.WriteLine(")value),"); - } - - context.CodeWriter.CurrentIndent -= context.CodeWriter.TabSize; - context.CodeWriter.WriteLine("});"); + context.CodeWriter.Write(">"); + context.CodeWriter.Write("(static (c, v) => c."); + context.CodeWriter.Write(parameterData.Name); + context.CodeWriter.Write(" = ("); + context.CodeWriter.Write(parameterData.TypeName); + context.CodeWriter.WriteLine(")v),"); } - WriteUnmatchedValuesPropertySetterProperty(context); - WriteTryGetSetterSignature(context); + context.CodeWriter.CurrentIndent -= context.CodeWriter.TabSize; + context.CodeWriter.WriteLine("});"); - using (context.CodeWriter.BuildScope()) - { - if (hasParameters) - { - context.CodeWriter.Write("var success = "); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySettersField); - context.CodeWriter.Write(".Value.TryGetValue("); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertyNameParameter); - context.CodeWriter.WriteLine(", out var result);"); - context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); - context.CodeWriter.WriteLine(" = result;"); - context.CodeWriter.WriteLine("return success;"); - } - else - { - WriteTryGetSetterDefaultBody(context); - } - } + // Writes something like: + // + // public override bool TryGetSetter(string propertyName, out IPropertySetter propertySetter) + // => __propertySetters.Value.TryGetValue(propertyName, out propertySetter) + // || base.TryGetSetter(propertyName, out propertySetter); + context.CodeWriter.Write("public override bool "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.TryGetSetter); + context.CodeWriter.Write("("); + context.CodeWriter.Write("string "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertyNameParameter); + context.CodeWriter.Write(", "); + context.CodeWriter.Write("out "); + context.CodeWriter.Write(ComponentsApi.IPropertySetter.FullTypeName); + context.CodeWriter.Write(" "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); + context.CodeWriter.WriteLine(")"); + + context.CodeWriter.CurrentIndent += context.CodeWriter.TabSize; + context.CodeWriter.Write("=> "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySettersField); + context.CodeWriter.Write(".Value.TryGetValue("); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertyNameParameter); + context.CodeWriter.Write(", out "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); + context.CodeWriter.WriteLine(")"); + context.CodeWriter.Write("|| base."); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.TryGetSetter); + context.CodeWriter.Write("("); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertyNameParameter); + context.CodeWriter.Write(", out "); + context.CodeWriter.Write(ComponentsApi.IPropertySetterProvider.PropertySetterParameter); + context.CodeWriter.WriteLine(");"); + context.CodeWriter.CurrentIndent -= context.CodeWriter.TabSize; } public override void WriteTemplate(CodeRenderingContext context, TemplateIntermediateNode node) diff --git a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithConstrainedTypeParameters/TestComponent.mappings.txt b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithConstrainedTypeParameters/TestComponent.mappings.txt index 76387ba727..896f8df0cc 100644 --- a/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithConstrainedTypeParameters/TestComponent.mappings.txt +++ b/src/Razor/Microsoft.AspNetCore.Razor.Language/test/TestFiles/IntegrationTests/ComponentRuntimeCodeGenerationTest/ComponentWithConstrainedTypeParameters/TestComponent.mappings.txt @@ -21,7 +21,7 @@ Source Location: (294:15,7 [236] x:\dir\subdir\Test\TestComponent.cshtml) [Parameter] public TItem3 Item3 { get; set; } [Parameter] public RenderFragment<TItem2> ChildContent { get; set; } | -Generated Location: (1589:57,7 [236] ) +Generated Location: (2838:67,7 [236] ) | [Parameter] public TItem1 Item1 { get; set; } [Parameter] public List<TItem2> Items2 { get; set; } diff --git a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs index ce0218b941..e9f88e8fbe 100644 --- a/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs +++ b/src/Razor/test/Microsoft.AspNetCore.Razor.Test.ComponentShim/Microsoft.AspNetCore.Components.netstandard2.0.cs @@ -92,9 +92,11 @@ namespace Microsoft.AspNetCore.Components public ChangeEventArgs() { } public object Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } } } - public abstract partial class ComponentBase : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, Microsoft.AspNetCore.Components.IHandleEvent + public abstract partial class ComponentBase : Microsoft.AspNetCore.Components.IComponent, Microsoft.AspNetCore.Components.IHandleAfterRender, Microsoft.AspNetCore.Components.IHandleEvent, Microsoft.AspNetCore.Components.IPropertySetterProvider { public ComponentBase() { } + public virtual IUnmatchedValuesPropertySetter UnmatchedValuesPropertySetter { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } } + public virtual bool TryGetSetter(string propertyName, out Microsoft.AspNetCore.Components.IPropertySetter propertySetter) { throw null; } protected virtual void BuildRenderTree(Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder builder) { } protected System.Threading.Tasks.Task InvokeAsync(System.Action workItem) { throw null; } protected System.Threading.Tasks.Task InvokeAsync(System.Func<System.Threading.Tasks.Task> workItem) { throw null; } |