@ -5,14 +5,13 @@ using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers ;
using Avalonia.Utilities ;
using XamlX.Ast ;
using XamlX.Emit ;
using XamlX.IL ;
using XamlX.Transform ;
using XamlX.Transform.Transformers ;
using XamlX.TypeSystem ;
using XamlX.Emit ;
using XamlX.IL ;
using XamlIlEmitContext = XamlX . Emit . XamlEmitContext < XamlX . IL . IXamlILEmitter , XamlX . IL . XamlILNodeEmitResult > ;
using IXamlIlAstEmitableNode = XamlX . Emit . IXamlAstEmitableNode < XamlX . IL . IXamlILEmitter , XamlX . IL . XamlILNodeEmitResult > ;
using XamlIlEmitContext = XamlX . Emit . XamlEmitContext < XamlX . IL . IXamlILEmitter , XamlX . IL . XamlILNodeEmitResult > ;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{
@ -69,6 +68,13 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
if ( parsedPropertyName . owner = = null )
forgedReference = new XamlAstNamePropertyReference ( lineInfo , selectorTypeReference ,
propertyName , selectorTypeReference ) ;
else if ( string . IsNullOrWhiteSpace ( parsedPropertyName . ns )
& & string . Equals ( parsedPropertyName . owner , "Classes" , StringComparison . OrdinalIgnoreCase )
& & ! string . IsNullOrWhiteSpace ( parsedPropertyName . name )
)
{
return new XamlIlAvaloniaClassProperty ( context . GetAvaloniaTypes ( ) , parsedPropertyName . name , lineInfo ) ;
}
else
{
var xmlOwner = parsedPropertyName . ns ;
@ -124,7 +130,13 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
{
IXamlType AvaloniaPropertyType { get ; }
}
// Marker interface, used to identify whether the Avalonia property represents Classes
interface IXamlIlAvaloniaClassPropertyNode : IXamlIlAvaloniaPropertyNode
{
}
class XamlIlAvaloniaPropertyNode : XamlAstNode , IXamlAstValueNode , IXamlIlAstEmitableNode , IXamlIlAvaloniaPropertyNode
{
public XamlIlAvaloniaPropertyNode ( IXamlLineInfo lineInfo , IXamlType type , XamlAstClrProperty property , IXamlType propertyType ) : base ( lineInfo )
@ -433,4 +445,47 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
}
}
}
sealed class XamlIlAvaloniaClassProperty : XamlAstClrProperty ,
IXamlIlAvaloniaClassPropertyNode ,
IXamlAstValueNode ,
IXamlAstLocalsEmitableNode < IXamlILEmitter , XamlILNodeEmitResult >
{
private readonly IXamlMethod _ method ;
private readonly AvaloniaXamlIlWellKnownTypes _ types ;
private readonly string _ className ;
private readonly IXamlAstTypeReference _ type ;
private readonly IXamlType _ returnType ;
public XamlIlAvaloniaClassProperty ( AvaloniaXamlIlWellKnownTypes types ,
string className ,
IXamlLineInfo lineInfo ) : base ( lineInfo , className , types . Classes , null , null , null )
{
Parameters = [ types . XamlIlTypes . String ] ;
_ method = types . GetClassProperty ;
AvaloniaPropertyType = types . XamlIlTypes . Boolean ;
_ types = types ;
_ returnType = _ types . AvaloniaPropertyT . MakeGenericType ( types . XamlIlTypes . Boolean ) ;
_ type = new XamlAstClrTypeReference ( this , _ returnType , false ) ;
_ className = className ;
Setters = [ ] ;
}
public IXamlType AvaloniaPropertyType { get ; }
public IReadOnlyList < IXamlType > Parameters { get ; }
public IXamlAstTypeReference Type = > _ type ;
public PropertySetterBinderParameters BinderParameters { get ; } = new PropertySetterBinderParameters ( ) ;
public XamlILNodeEmitResult Emit ( XamlEmitContextWithLocals < IXamlILEmitter , XamlILNodeEmitResult > context , IXamlILEmitter emitter )
{
using ( var loc = emitter . LocalsPool . GetLocal ( _ types . XamlIlTypes . String ) )
{
emitter
. Ldstr ( _ className ) ;
emitter . EmitCall ( _ method , false ) ;
}
return XamlILNodeEmitResult . Type ( 0 , _ returnType ) ;
}
}
}