14 changed files with 236 additions and 239 deletions
@ -1,114 +0,0 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using XamlIl.Ast; |
|||
using XamlIl.Transform; |
|||
using XamlIl.TypeSystem; |
|||
|
|||
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers |
|||
{ |
|||
public class AvaloniaXamlIlBindingPropertyAssignmentsTransformer : IXamlIlAstTransformer |
|||
{ |
|||
public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node) |
|||
{ |
|||
if (node is XamlIlAstXamlPropertyValueNode pv |
|||
&& pv.Property.GetClrProperty() is IXamlIlAvaloniaProperty ap |
|||
&& pv.Values.Count == 1) |
|||
{ |
|||
var types = context.GetAvaloniaTypes(); |
|||
|
|||
var vn = pv.Values[0]; |
|||
if (vn.Type.GetClrType().Equals(XamlIlPseudoType.Null)) |
|||
return node; |
|||
|
|||
if (pv.Property.GetClrProperty().CustomAttributes |
|||
.Any(a => a.Type.Equals(types.AssignBindingAttribute))) |
|||
return node; |
|||
|
|||
// Special handling for markup extensions
|
|||
if (vn.Type.IsMarkupExtension) |
|||
{ |
|||
if (XamlIlTransformHelpers |
|||
.GetMarkupExtensionProvideValueAlternatives(context, vn.Type.GetClrType()) |
|||
.Any(x => types.IBinding.IsAssignableFrom(x.ReturnType))) |
|||
{ |
|||
if (XamlIlTransformHelpers.TryConvertMarkupExtension(context, pv.Values[0], |
|||
new AssignBindingProperty(types, ap), out var ext)) |
|||
return ext; |
|||
} |
|||
} |
|||
else if (types.IBinding.IsAssignableFrom(vn.Type.GetClrType())) |
|||
{ |
|||
pv.Property = new XamlIlAstClrPropertyReference(pv.Property, new AssignBindingProperty(types, ap)); |
|||
} |
|||
} |
|||
|
|||
return node; |
|||
} |
|||
|
|||
class AssignBindingProperty : IXamlIlAvaloniaProperty |
|||
{ |
|||
public AssignBindingProperty( |
|||
AvaloniaXamlIlWellKnownTypes types, |
|||
IXamlIlAvaloniaProperty property |
|||
) |
|||
{ |
|||
PropertyType = types.IBinding; |
|||
AvaloniaProperty = property.AvaloniaProperty; |
|||
CustomAttributes = property.CustomAttributes; |
|||
Name = property.Name; |
|||
Setter = new SetterMethod(types, (property.Setter ?? property.Getter).DeclaringType, |
|||
AvaloniaProperty); |
|||
} |
|||
|
|||
public bool Equals(IXamlIlProperty other) => |
|||
other is AssignBindingProperty abp && abp.AvaloniaProperty.Equals(AvaloniaProperty); |
|||
|
|||
public string Name { get; } |
|||
public IXamlIlType PropertyType { get; } |
|||
public IXamlIlMethod Setter { get; } |
|||
public IXamlIlMethod Getter { get; } |
|||
public IReadOnlyList<IXamlIlCustomAttribute> CustomAttributes { get; } |
|||
public IXamlIlField AvaloniaProperty { get; } |
|||
|
|||
class SetterMethod : IXamlIlCustomEmitMethod |
|||
{ |
|||
private readonly AvaloniaXamlIlWellKnownTypes _types; |
|||
private readonly IXamlIlField _avaloniaProperty; |
|||
|
|||
public SetterMethod(AvaloniaXamlIlWellKnownTypes types, |
|||
IXamlIlType declaringType, |
|||
IXamlIlField avaloniaProperty) |
|||
{ |
|||
_types = types; |
|||
_avaloniaProperty = avaloniaProperty; |
|||
Parameters = new[] {types.AvaloniaObject, types.IBinding}; |
|||
ReturnType = types.XamlIlTypes.Void; |
|||
DeclaringType = declaringType; |
|||
Name = "Bind_" + avaloniaProperty.Name; |
|||
} |
|||
|
|||
public bool Equals(IXamlIlMethod other) => |
|||
other is SetterMethod sm && sm._avaloniaProperty.Equals(_avaloniaProperty); |
|||
|
|||
public string Name { get; } |
|||
public bool IsPublic => true; |
|||
public bool IsStatic => true; |
|||
public IXamlIlType ReturnType { get; } |
|||
public IReadOnlyList<IXamlIlType> Parameters { get; } |
|||
public IXamlIlType DeclaringType { get; } |
|||
public void EmitCall(IXamlIlEmitter emitter) |
|||
{ |
|||
using (var bloc = emitter.LocalsPool.GetLocal(_types.IBinding)) |
|||
emitter |
|||
.Stloc(bloc.Local) |
|||
.Ldsfld(_avaloniaProperty) |
|||
.Ldloc(bloc.Local) |
|||
// TODO: provide anchor?
|
|||
.Ldnull(); |
|||
emitter.EmitCall(_types.AvaloniaObjectBindMethod, true); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1 +1 @@ |
|||
Subproject commit c0da3c49810316a96b47a00a83ae79d4f28406a1 |
|||
Subproject commit 56c401c48f51979201ad810c96a9644705d4ddd9 |
|||
Loading…
Reference in new issue