|
|
@@ -3,41 +3,45 @@ using System.Collections.Generic;
|
|
|
using System.Globalization;
|
|
|
using System.Linq;
|
|
|
using Avalonia.Markup.Parsers;
|
|
|
-using XamlIl;
|
|
|
-using XamlIl.Ast;
|
|
|
-using XamlIl.Transform;
|
|
|
-using XamlIl.Transform.Transformers;
|
|
|
-using XamlIl.TypeSystem;
|
|
|
+using XamlX;
|
|
|
+using XamlX.Ast;
|
|
|
+using XamlX.Emit;
|
|
|
+using XamlX.IL;
|
|
|
+using XamlX.Transform;
|
|
|
+using XamlX.Transform.Transformers;
|
|
|
+using XamlX.TypeSystem;
|
|
|
|
|
|
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
{
|
|
|
- class AvaloniaXamlIlSelectorTransformer : IXamlIlAstTransformer
|
|
|
+ using XamlParseException = XamlX.XamlParseException;
|
|
|
+ using XamlLoadException = XamlX.XamlLoadException;
|
|
|
+ class AvaloniaXamlIlSelectorTransformer : IXamlAstTransformer
|
|
|
{
|
|
|
- public IXamlIlAstNode Transform(XamlIlAstTransformationContext context, IXamlIlAstNode node)
|
|
|
+ public IXamlAstNode Transform(AstTransformationContext context, IXamlAstNode node)
|
|
|
{
|
|
|
- if (!(node is XamlIlAstObjectNode on && on.Type.GetClrType().FullName == "Avalonia.Styling.Style"))
|
|
|
+ if (!(node is XamlAstObjectNode on && on.Type.GetClrType().FullName == "Avalonia.Styling.Style"))
|
|
|
return node;
|
|
|
|
|
|
- var pn = on.Children.OfType<XamlIlAstXamlPropertyValueNode>()
|
|
|
+ var pn = on.Children.OfType<XamlAstXamlPropertyValueNode>()
|
|
|
.FirstOrDefault(p => p.Property.GetClrProperty().Name == "Selector");
|
|
|
|
|
|
if (pn == null)
|
|
|
return node;
|
|
|
|
|
|
if (pn.Values.Count != 1)
|
|
|
- throw new XamlIlParseException("Selector property should should have exactly one value", node);
|
|
|
+ throw new XamlParseException("Selector property should should have exactly one value", node);
|
|
|
|
|
|
if (pn.Values[0] is XamlIlSelectorNode)
|
|
|
//Deja vu. I've just been in this place before
|
|
|
return node;
|
|
|
|
|
|
- if (!(pn.Values[0] is XamlIlAstTextNode tn))
|
|
|
- throw new XamlIlParseException("Selector property should be a text node", node);
|
|
|
+ if (!(pn.Values[0] is XamlAstTextNode tn))
|
|
|
+ throw new XamlParseException("Selector property should be a text node", node);
|
|
|
|
|
|
var selectorType = pn.Property.GetClrProperty().Getter.ReturnType;
|
|
|
var initialNode = new XamlIlSelectorInitialNode(node, selectorType);
|
|
|
XamlIlSelectorNode Create(IEnumerable<SelectorGrammar.ISyntax> syntax,
|
|
|
- Func<string, string, XamlIlAstClrTypeReference> typeResolver)
|
|
|
+ Func<string, string, XamlAstClrTypeReference> typeResolver)
|
|
|
{
|
|
|
XamlIlSelectorNode result = initialNode;
|
|
|
XamlIlOrSelectorNode results = null;
|
|
|
@@ -63,18 +67,18 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
var type = result?.TargetType;
|
|
|
|
|
|
if (type == null)
|
|
|
- throw new XamlIlParseException("Property selectors must be applied to a type.", node);
|
|
|
+ throw new XamlParseException("Property selectors must be applied to a type.", node);
|
|
|
|
|
|
var targetProperty =
|
|
|
type.GetAllProperties().FirstOrDefault(p => p.Name == property.Property);
|
|
|
|
|
|
if (targetProperty == null)
|
|
|
- throw new XamlIlParseException($"Cannot find '{property.Property}' on '{type}", node);
|
|
|
+ throw new XamlParseException($"Cannot find '{property.Property}' on '{type}", node);
|
|
|
|
|
|
- if (!XamlIlTransformHelpers.TryGetCorrectlyTypedValue(context,
|
|
|
- new XamlIlAstTextNode(node, property.Value, context.Configuration.WellKnownTypes.String),
|
|
|
+ if (!XamlTransformHelpers.TryGetCorrectlyTypedValue(context,
|
|
|
+ new XamlAstTextNode(node, property.Value, context.Configuration.WellKnownTypes.String),
|
|
|
targetProperty.PropertyType, out var typedValue))
|
|
|
- throw new XamlIlParseException(
|
|
|
+ throw new XamlParseException(
|
|
|
$"Cannot convert '{property.Value}' to '{targetProperty.PropertyType.GetFqn()}",
|
|
|
node);
|
|
|
|
|
|
@@ -100,7 +104,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
result = initialNode;
|
|
|
break;
|
|
|
default:
|
|
|
- throw new XamlIlParseException($"Unsupported selector grammar '{i.GetType()}'.", node);
|
|
|
+ throw new XamlParseException($"Unsupported selector grammar '{i.GetType()}'.", node);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -119,15 +123,15 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
}
|
|
|
catch (Exception e)
|
|
|
{
|
|
|
- throw new XamlIlParseException("Unable to parse selector: " + e.Message, node);
|
|
|
+ throw new XamlParseException("Unable to parse selector: " + e.Message, node);
|
|
|
}
|
|
|
|
|
|
var selector = Create(parsed, (p, n)
|
|
|
- => XamlIlTypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true));
|
|
|
+ => TypeReferenceResolver.ResolveType(context, $"{p}:{n}", true, node, true));
|
|
|
pn.Values[0] = selector;
|
|
|
|
|
|
return new AvaloniaXamlIlTargetTypeMetadataNode(on,
|
|
|
- new XamlIlAstClrTypeReference(selector, selector.TargetType, false),
|
|
|
+ new XamlAstClrTypeReference(selector, selector.TargetType, false),
|
|
|
AvaloniaXamlIlTargetTypeMetadataNode.ScopeTypes.Style);
|
|
|
}
|
|
|
|
|
|
@@ -135,32 +139,32 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
|
|
|
|
|
|
|
|
|
- abstract class XamlIlSelectorNode : XamlIlAstNode, IXamlIlAstValueNode, IXamlIlAstEmitableNode
|
|
|
+ abstract class XamlIlSelectorNode : XamlAstNode, IXamlAstValueNode, IXamlAstEmitableNode<IXamlILEmitter, XamlILNodeEmitResult>
|
|
|
{
|
|
|
protected XamlIlSelectorNode Previous { get; }
|
|
|
- public abstract IXamlIlType TargetType { get; }
|
|
|
+ public abstract IXamlType TargetType { get; }
|
|
|
|
|
|
public XamlIlSelectorNode(XamlIlSelectorNode previous,
|
|
|
- IXamlIlLineInfo info = null,
|
|
|
- IXamlIlType selectorType = null) : base(info ?? previous)
|
|
|
+ IXamlLineInfo info = null,
|
|
|
+ IXamlType selectorType = null) : base(info ?? previous)
|
|
|
{
|
|
|
Previous = previous;
|
|
|
- Type = selectorType == null ? previous.Type : new XamlIlAstClrTypeReference(this, selectorType, false);
|
|
|
+ Type = selectorType == null ? previous.Type : new XamlAstClrTypeReference(this, selectorType, false);
|
|
|
}
|
|
|
|
|
|
- public IXamlIlAstTypeReference Type { get; }
|
|
|
+ public IXamlAstTypeReference Type { get; }
|
|
|
|
|
|
- public virtual XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public virtual XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
if (Previous != null)
|
|
|
context.Emit(Previous, codeGen, Type.GetClrType());
|
|
|
DoEmit(context, codeGen);
|
|
|
- return XamlIlNodeEmitResult.Type(0, Type.GetClrType());
|
|
|
+ return XamlILNodeEmitResult.Type(0, Type.GetClrType());
|
|
|
}
|
|
|
|
|
|
- protected abstract void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen);
|
|
|
+ protected abstract void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen);
|
|
|
|
|
|
- protected void EmitCall(XamlIlEmitContext context, IXamlIlEmitter codeGen, Func<IXamlIlMethod, bool> method)
|
|
|
+ protected void EmitCall(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen, Func<IXamlMethod, bool> method)
|
|
|
{
|
|
|
var selectors = context.Configuration.TypeSystem.GetType("Avalonia.Styling.Selectors");
|
|
|
var found = selectors.FindMethod(m => m.IsStatic && m.Parameters.Count > 0 && method(m));
|
|
|
@@ -170,27 +174,27 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
|
|
|
class XamlIlSelectorInitialNode : XamlIlSelectorNode
|
|
|
{
|
|
|
- public XamlIlSelectorInitialNode(IXamlIlLineInfo info,
|
|
|
- IXamlIlType selectorType) : base(null, info, selectorType)
|
|
|
+ public XamlIlSelectorInitialNode(IXamlLineInfo info,
|
|
|
+ IXamlType selectorType) : base(null, info, selectorType)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
- public override IXamlIlType TargetType => null;
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen) => codeGen.Ldnull();
|
|
|
+ public override IXamlType TargetType => null;
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen) => codeGen.Ldnull();
|
|
|
}
|
|
|
|
|
|
class XamlIlTypeSelector : XamlIlSelectorNode
|
|
|
{
|
|
|
public bool Concrete { get; }
|
|
|
|
|
|
- public XamlIlTypeSelector(XamlIlSelectorNode previous, IXamlIlType type, bool concrete) : base(previous)
|
|
|
+ public XamlIlTypeSelector(XamlIlSelectorNode previous, IXamlType type, bool concrete) : base(previous)
|
|
|
{
|
|
|
TargetType = type;
|
|
|
Concrete = concrete;
|
|
|
}
|
|
|
|
|
|
- public override IXamlIlType TargetType { get; }
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public override IXamlType TargetType { get; }
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
var name = Concrete ? "OfType" : "Is";
|
|
|
codeGen.Ldtype(TargetType);
|
|
|
@@ -217,8 +221,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
}
|
|
|
|
|
|
|
|
|
- public override IXamlIlType TargetType => Previous?.TargetType;
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public override IXamlType TargetType => Previous?.TargetType;
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
codeGen.Ldstr(String);
|
|
|
var name = _type.ToString();
|
|
|
@@ -242,8 +246,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
_type = type;
|
|
|
}
|
|
|
|
|
|
- public override IXamlIlType TargetType => null;
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public override IXamlType TargetType => null;
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
var name = _type.ToString();
|
|
|
EmitCall(context, codeGen,
|
|
|
@@ -260,8 +264,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
Argument = argument;
|
|
|
}
|
|
|
|
|
|
- public override IXamlIlType TargetType => Previous?.TargetType;
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public override IXamlType TargetType => Previous?.TargetType;
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
context.Emit(Argument, codeGen, Type.GetClrType());
|
|
|
EmitCall(context, codeGen,
|
|
|
@@ -272,22 +276,22 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
class XamlIlPropertyEqualsSelector : XamlIlSelectorNode
|
|
|
{
|
|
|
public XamlIlPropertyEqualsSelector(XamlIlSelectorNode previous,
|
|
|
- IXamlIlProperty property,
|
|
|
- IXamlIlAstValueNode value)
|
|
|
+ IXamlProperty property,
|
|
|
+ IXamlAstValueNode value)
|
|
|
: base(previous)
|
|
|
{
|
|
|
Property = property;
|
|
|
Value = value;
|
|
|
}
|
|
|
|
|
|
- public IXamlIlProperty Property { get; set; }
|
|
|
- public IXamlIlAstValueNode Value { get; set; }
|
|
|
+ public IXamlProperty Property { get; set; }
|
|
|
+ public IXamlAstValueNode Value { get; set; }
|
|
|
|
|
|
- public override IXamlIlType TargetType => Previous?.TargetType;
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ public override IXamlType TargetType => Previous?.TargetType;
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
if (!XamlIlAvaloniaPropertyHelper.Emit(context, codeGen, Property))
|
|
|
- throw new XamlIlLoadException(
|
|
|
+ throw new XamlLoadException(
|
|
|
$"{Property.Name} of {(Property.Setter ?? Property.Getter).DeclaringType.GetFqn()} doesn't seem to be an AvaloniaProperty",
|
|
|
this);
|
|
|
context.Emit(Value, codeGen, context.Configuration.WellKnownTypes.Object);
|
|
|
@@ -302,7 +306,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
class XamlIlOrSelectorNode : XamlIlSelectorNode
|
|
|
{
|
|
|
List<XamlIlSelectorNode> _selectors = new List<XamlIlSelectorNode>();
|
|
|
- public XamlIlOrSelectorNode(IXamlIlLineInfo info, IXamlIlType selectorType) : base(null, info, selectorType)
|
|
|
+ public XamlIlOrSelectorNode(IXamlLineInfo info, IXamlType selectorType) : base(null, info, selectorType)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
@@ -311,11 +315,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
_selectors.Add(node);
|
|
|
}
|
|
|
|
|
|
- public override IXamlIlType TargetType
|
|
|
+ public override IXamlType TargetType
|
|
|
{
|
|
|
get
|
|
|
{
|
|
|
- IXamlIlType result = null;
|
|
|
+ IXamlType result = null;
|
|
|
|
|
|
foreach (var selector in _selectors)
|
|
|
{
|
|
|
@@ -340,10 +344,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- protected override void DoEmit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
|
|
|
+ protected override void DoEmit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
|
|
|
{
|
|
|
if (_selectors.Count == 0)
|
|
|
- throw new XamlIlLoadException("Invalid selector count", this);
|
|
|
+ throw new XamlLoadException("Invalid selector count", this);
|
|
|
if (_selectors.Count == 1)
|
|
|
{
|
|
|
_selectors[0].Emit(context, codeGen);
|