diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs index a4534a7396..ed0bc1fdba 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs @@ -22,6 +22,21 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings => new IndexerAccessor(target, property, argument); } + public class IndexerPropertyAccessorHelper + { + private readonly int _index; + + public IndexerPropertyAccessorHelper(int index) + { + _index = index; + } + + public IPropertyAccessor CreateAccessor(WeakReference target, IPropertyInfo property) + { + return PropertyInfoAccessorFactory.CreateIndexerPropertyAccessor(target, property, _index); + } + } + internal class AvaloniaPropertyAccessor : PropertyAccessorBase { private readonly WeakReference _reference; diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index d29e99f2c3..d136563774 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -32,6 +32,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers public IXamlIlType PropertyPathBuilder { get; } public IXamlIlType IPropertyAccessor { get; } public IXamlIlType PropertyInfoAccessorFactory { get; } + public IXamlIlType IndexerPropertyAccessorHelper { get; } public IXamlIlType CompiledBindingPathBuilder { get; } public IXamlIlType CompiledBindingPath { get; } public IXamlIlType CompiledBindingExtension { get; } @@ -82,6 +83,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers PropertyPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.Core.PropertyPathBuilder"); IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor"); PropertyInfoAccessorFactory = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory"); + IndexerPropertyAccessorHelper = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.IndexerPropertyAccessorHelper"); CompiledBindingPathBuilder = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPathBuilder"); CompiledBindingPath = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPath"); CompiledBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension"); diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs index 970c52a2f0..c842254cf0 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs @@ -11,12 +11,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions { class XamlIlPropertyInfoAccessorFactoryEmitter { - private const string IndexerClosureFactoryMethodName = "CreateAccessor"; - private readonly IXamlIlTypeBuilder _indexerClosureTypeBuilder; - private IXamlIlType _indexerClosureType; public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType) { - _indexerClosureTypeBuilder = indexerClosureType; } public IXamlIlType EmitLoadInpcPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen) @@ -46,57 +42,16 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions public IXamlIlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlAstValueNode value) { + const string IndexerClosureFactoryMethodName = "CreateAccessor"; var intType = context.Configuration.TypeSystem.GetType("System.Int32"); - if (_indexerClosureType is null) - { - _indexerClosureType = InitializeClosureType(context); - } + var indexerClosureType = context.GetAvaloniaTypes().IndexerPropertyAccessorHelper; context.Emit(value, codeGen, intType); - codeGen.Newobj(_indexerClosureType.FindConstructor(new List { intType })); - EmitLoadPropertyAccessorFactory(context, codeGen, _indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false); + codeGen.Newobj(indexerClosureType.FindConstructor(new List { intType })); + EmitLoadPropertyAccessorFactory(context, codeGen, indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false); return EmitCreateAccessorFactoryDelegate(context, codeGen); } - private IXamlIlType InitializeClosureType(XamlIlEmitContext context) - { - var types = context.GetAvaloniaTypes(); - var intType = context.Configuration.TypeSystem.GetType("System.Int32"); - var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference"); - var indexAccessorFactoryMethod = context.GetAvaloniaTypes().PropertyInfoAccessorFactory.GetMethod( - new FindMethodMethodSignature( - "CreateIndexerPropertyAccessor", - types.IPropertyAccessor, - weakReferenceType, - types.IPropertyInfo, - intType) - { - IsStatic = true - }); - var indexField = _indexerClosureTypeBuilder.DefineField(intType, "_index", false, false); - var ctor = _indexerClosureTypeBuilder.DefineConstructor(false, intType); - ctor.Generator - .Ldarg_0() - .Ldarg(1) - .Stfld(indexField) - .Ret(); - _indexerClosureTypeBuilder.DefineMethod( - types.IPropertyAccessor, - new[] { weakReferenceType, types.IPropertyInfo }, - IndexerClosureFactoryMethodName, - isPublic: true, - isStatic: false, - isInterfaceImpl: false) - .Generator - .Ldarg(1) - .Ldarg(2) - .LdThisFld(indexField) - .EmitCall(indexAccessorFactoryMethod) - .Ret(); - - return _indexerClosureTypeBuilder.CreateType(); - } - private IXamlIlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlIlEmitter codeGen) { var types = context.GetAvaloniaTypes();