Browse Source

FontFamily and TimeSpan intrinsics

pull/5046/head
Nikita Tsukanov 6 years ago
parent
commit
ee470af59a
  1. 43
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AstNodes/AvaloniaXamlIlFontFamilyAstNode.cs
  2. 51
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  3. 10
      src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

43
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AstNodes/AvaloniaXamlIlFontFamilyAstNode.cs

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlX.Ast;
using XamlX.Emit;
using XamlX.IL;
using XamlX.TypeSystem;
namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.AstNodes
{
class AvaloniaXamlIlFontFamilyAstNode: XamlAstNode, IXamlAstValueNode, IXamlAstILEmitableNode
{
private readonly AvaloniaXamlIlWellKnownTypes _types;
private readonly string _text;
public IXamlAstTypeReference Type { get; }
public AvaloniaXamlIlFontFamilyAstNode(AvaloniaXamlIlWellKnownTypes types,
string text,
IXamlLineInfo lineInfo) : base(lineInfo)
{
_types = types;
_text = text;
Type = new XamlAstClrTypeReference(lineInfo, types.FontFamily, false);
}
public XamlILNodeEmitResult Emit(XamlEmitContext<IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen)
{
codeGen
.Ldloc(context.ContextLocal)
.Castclass(context.Configuration.TypeMappings.UriContextProvider)
.EmitCall(context.Configuration.TypeMappings.UriContextProvider.FindMethod(
"get_BaseUri", _types.Uri, false))
.Ldstr(_text)
.Newobj(_types.FontFamilyConstructorUriName);
return XamlILNodeEmitResult.Type(0, _types.FontFamily);
}
}
}

51
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.AstNodes;
using Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers;
using XamlX;
using XamlX.Ast;
@ -166,17 +168,41 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
public static bool CustomValueConverter(AstTransformationContext context,
IXamlAstValueNode node, IXamlType type, out IXamlAstValueNode result)
{
if (type.FullName == "System.TimeSpan"
&& node is XamlAstTextNode tn
&& !tn.Text.Contains(":"))
if (!(node is XamlAstTextNode textNode))
{
var seconds = double.Parse(tn.Text, CultureInfo.InvariantCulture);
result = new XamlStaticOrTargetedReturnMethodCallNode(tn,
type.FindMethod("FromSeconds", type, false, context.Configuration.WellKnownTypes.Double),
new[]
{
new XamlConstantNode(tn, context.Configuration.WellKnownTypes.Double, seconds)
});
result = null;
return false;
}
var text = textNode.Text;
var types = context.GetAvaloniaTypes();
if (type.FullName == "System.TimeSpan")
{
var tsText = text.Trim();
if (!TimeSpan.TryParse(tsText, CultureInfo.InvariantCulture, out var timeSpan))
{
// // shorthand seconds format (ie. "0.25")
if (!tsText.Contains(":") && double.TryParse(tsText,
NumberStyles.Float | NumberStyles.AllowThousands,
CultureInfo.InvariantCulture, out var seconds))
timeSpan = TimeSpan.FromSeconds(seconds);
else
throw new XamlX.XamlLoadException($"Unable to parse {text} as a time span", node);
}
result = new XamlStaticOrTargetedReturnMethodCallNode(node,
type.FindMethod("FromTicks", type, false, types.Long),
new[] { new XamlConstantNode(node, types.Long, timeSpan.Ticks) });
return true;
}
if (type.Equals(types.FontFamily))
{
result = new AvaloniaXamlIlFontFamilyAstNode(types, text, node);
return true;
}
@ -185,9 +211,8 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
var scope = context.ParentNodes().OfType<AvaloniaXamlIlTargetTypeMetadataNode>().FirstOrDefault();
if (scope == null)
throw new XamlX.XamlLoadException("Unable to find the parent scope for AvaloniaProperty lookup", node);
if (!(node is XamlAstTextNode text))
throw new XamlX.XamlLoadException("Property should be a text node", node);
result = XamlIlAvaloniaPropertyHelper.CreateNode(context, text.Text, scope.TargetType, text);
result = XamlIlAvaloniaPropertyHelper.CreateNode(context, text, scope.TargetType, node );
return true;
}

10
src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@ -1,3 +1,4 @@
using System.Collections.Generic;
using XamlX.Emit;
using XamlX.IL;
using XamlX.Transform;
@ -47,6 +48,11 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
public IXamlType ReflectionBindingExtension { get; }
public IXamlType RelativeSource { get; }
public IXamlType Long { get; }
public IXamlType Uri { get; }
public IXamlType FontFamily { get; }
public IXamlConstructor FontFamilyConstructorUriName { get; }
public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg)
{
@ -104,6 +110,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
ItemsRepeater = cfg.TypeSystem.GetType("Avalonia.Controls.ItemsRepeater");
ReflectionBindingExtension = cfg.TypeSystem.GetType("Avalonia.Markup.Xaml.MarkupExtensions.ReflectionBindingExtension");
RelativeSource = cfg.TypeSystem.GetType("Avalonia.Data.RelativeSource");
Long = cfg.TypeSystem.GetType("System.Int64");
Uri = cfg.TypeSystem.GetType("System.Uri");
FontFamily = cfg.TypeSystem.GetType("Avalonia.Media.FontFamily");
FontFamilyConstructorUriName = FontFamily.FindConstructor(new List<IXamlType> { Uri, XamlIlTypes.String });
}
}

Loading…
Cancel
Save