Browse Source

Provide helper type instead of manually emitting closure type into assembly.

pull/3001/head
Jeremy Koritzinsky 7 years ago
parent
commit
2832462a85
  1. 15
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs
  2. 2
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  3. 53
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs

15
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs

@ -22,6 +22,21 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings
=> new IndexerAccessor(target, property, argument); => 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 internal class AvaloniaPropertyAccessor : PropertyAccessorBase
{ {
private readonly WeakReference<AvaloniaObject> _reference; private readonly WeakReference<AvaloniaObject> _reference;

2
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 PropertyPathBuilder { get; }
public IXamlIlType IPropertyAccessor { get; } public IXamlIlType IPropertyAccessor { get; }
public IXamlIlType PropertyInfoAccessorFactory { get; } public IXamlIlType PropertyInfoAccessorFactory { get; }
public IXamlIlType IndexerPropertyAccessorHelper { get; }
public IXamlIlType CompiledBindingPathBuilder { get; } public IXamlIlType CompiledBindingPathBuilder { get; }
public IXamlIlType CompiledBindingPath { get; } public IXamlIlType CompiledBindingPath { get; }
public IXamlIlType CompiledBindingExtension { get; } public IXamlIlType CompiledBindingExtension { get; }
@ -82,6 +83,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
PropertyPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.Core.PropertyPathBuilder"); PropertyPathBuilder = cfg.TypeSystem.GetType("Avalonia.Data.Core.PropertyPathBuilder");
IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor"); IPropertyAccessor = cfg.TypeSystem.GetType("Avalonia.Data.Core.Plugins.IPropertyAccessor");
PropertyInfoAccessorFactory = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.PropertyInfoAccessorFactory"); 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"); CompiledBindingPathBuilder = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPathBuilder");
CompiledBindingPath = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPath"); CompiledBindingPath = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings.CompiledBindingPath");
CompiledBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension"); CompiledBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindingExtension");

53
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/XamlIlPropertyInfoAccessorFactoryEmitter.cs

@ -11,12 +11,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{ {
class XamlIlPropertyInfoAccessorFactoryEmitter class XamlIlPropertyInfoAccessorFactoryEmitter
{ {
private const string IndexerClosureFactoryMethodName = "CreateAccessor";
private readonly IXamlIlTypeBuilder _indexerClosureTypeBuilder;
private IXamlIlType _indexerClosureType;
public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType) public XamlIlPropertyInfoAccessorFactoryEmitter(IXamlIlTypeBuilder indexerClosureType)
{ {
_indexerClosureTypeBuilder = indexerClosureType;
} }
public IXamlIlType EmitLoadInpcPropertyAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen) 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) public IXamlIlType EmitLoadIndexerAccessorFactory(XamlIlEmitContext context, IXamlIlEmitter codeGen, IXamlIlAstValueNode value)
{ {
const string IndexerClosureFactoryMethodName = "CreateAccessor";
var intType = context.Configuration.TypeSystem.GetType("System.Int32"); var intType = context.Configuration.TypeSystem.GetType("System.Int32");
if (_indexerClosureType is null) var indexerClosureType = context.GetAvaloniaTypes().IndexerPropertyAccessorHelper;
{
_indexerClosureType = InitializeClosureType(context);
}
context.Emit(value, codeGen, intType); context.Emit(value, codeGen, intType);
codeGen.Newobj(_indexerClosureType.FindConstructor(new List<IXamlIlType> { intType })); codeGen.Newobj(indexerClosureType.FindConstructor(new List<IXamlIlType> { intType }));
EmitLoadPropertyAccessorFactory(context, codeGen, _indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false); EmitLoadPropertyAccessorFactory(context, codeGen, indexerClosureType, IndexerClosureFactoryMethodName, isStatic: false);
return EmitCreateAccessorFactoryDelegate(context, codeGen); 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) private IXamlIlType EmitCreateAccessorFactoryDelegate(XamlIlEmitContext context, IXamlIlEmitter codeGen)
{ {
var types = context.GetAvaloniaTypes(); var types = context.GetAvaloniaTypes();

Loading…
Cancel
Save