public bool EmitCall(IXamlPropertySetter setter, IXamlILEmitter emitter) { if (setter is XamlDirectEventSetter xdirect) { var paramType = setter.Parameters[0]; var expectedParameters = new [] { xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.XamlPropertyIndex, paramType }; IXamlType xamlDirectType = xdirect.WinUITypes.XamlDirect; var setterMethod = xamlDirectType.GetMethod( new FindMethodMethodSignature("AddEventHandler", emitter.TypeSystem.GetType("System.Void"), xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.XamlEventIndex, emitter.TypeSystem.GetType("System.Object"))); using (var objLocal = emitter.LocalsPool.GetLocal(xdirect.WinUITypes.IXamlDirectObject)) using (var valLocal = emitter.LocalsPool.GetLocal(paramType)) { emitter .Stloc(valLocal.Local) .Stloc(objLocal.Local) .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })) .Ldloc(objLocal.Local) .Ldc_I4((int)xdirect.EventIndex.GetLiteralValue()) .Ldloc(valLocal.Local) .EmitCall(setterMethod); } return(true); } return(false); }
public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen) { if (node is XamlObjectFromDirectObjectNode objNode) { IXamlType xamlDirectType = context.GetWinUITypes().XamlDirect; codeGen .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })); context.Emit(objNode.Value, codeGen, context.GetWinUITypes().IXamlDirectObject); codeGen .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetObject", context.Configuration.WellKnownTypes.Object, context.GetWinUITypes().IXamlDirectObject))) .Castclass(objNode.Type.GetClrType()); return(XamlILNodeEmitResult.Type(0, objNode.Type.GetClrType())); } else if (node is XamlDirectObjectFromObjectNode directObjNode) { IXamlType xamlDirectType = context.GetWinUITypes().XamlDirect; codeGen .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })); context.Emit(directObjNode.Value, codeGen, context.Configuration.WellKnownTypes.Object); codeGen .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetXamlDirectObject", context.GetWinUITypes().IXamlDirectObject, context.Configuration.WellKnownTypes.Object))); return(XamlILNodeEmitResult.Type(0, context.GetWinUITypes().IXamlDirectObject)); } return(null); }
public bool EmitCall(IXamlPropertySetter setter, IXamlILEmitter emitter) { if (setter is XamlDirectAdderSetter xdirect) { var paramType = setter.Parameters[0]; IXamlType xamlDirectType = xdirect.WinUITypes.XamlDirect; var getCollectionMethod = xamlDirectType.GetMethod( new FindMethodMethodSignature("GetXamlDirectObjectProperty", xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.XamlPropertyIndex)); var addToCollection = xamlDirectType.GetMethod( new FindMethodMethodSignature("AddToCollection", emitter.TypeSystem.GetType("System.Void"), xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.IXamlDirectObject)); using (var objLocal = emitter.LocalsPool.GetLocal(xdirect.WinUITypes.IXamlDirectObject)) using (var valLocal = emitter.LocalsPool.GetLocal(paramType)) { emitter .Stloc(valLocal.Local) .Stloc(objLocal.Local) .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })) .Dup(); emitter .Ldloc(objLocal.Local) .Ldc_I4((int)xdirect.PropertyIndex.GetLiteralValue()) .EmitCall(getCollectionMethod); if (paramType != xdirect.WinUITypes.IXamlDirectObject) { emitter .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })) .Ldloc(valLocal.Local) .EmitCall(xamlDirectType.FindMethod(m => m.Name == "GetXamlDirectObject")); } else { emitter.Ldloc(valLocal.Local); } emitter .EmitCall(addToCollection); } return(true); } return(false); }
public AvaloniaXamlIlAvaloniaListConstantAstNode(IXamlLineInfo lineInfo, AvaloniaXamlIlWellKnownTypes types, IXamlType listType, IXamlType elementType, IReadOnlyList <IXamlAstValueNode> values) : base(lineInfo) { _constructor = listType.GetConstructor(); _listAddMethod = listType.GetMethod(new FindMethodMethodSignature("Add", types.XamlIlTypes.Void, elementType)); _listSetCapacityMethod = listType.GetMethod(new FindMethodMethodSignature("set_Capacity", types.XamlIlTypes.Void, types.Int)); _elementType = elementType; _values = values; Type = new XamlAstClrTypeReference(lineInfo, listType, false); }
public bool EmitCall(IXamlPropertySetter setter, IXamlILEmitter emitter) { if (setter is XamlDirectSetter xdirect) { var paramType = setter.Parameters[0]; var expectedParameters = new [] { xdirect.WinUITypes.IXamlDirectObject, xdirect.WinUITypes.XamlPropertyIndex, paramType }; IXamlType xamlDirectType = xdirect.WinUITypes.XamlDirect; var setterMethod = xamlDirectType .FindMethod(m => !m.IsStatic && m.Name.StartsWith("Set") && m.ReturnType == emitter.TypeSystem.FindType("System.Void") && m.Parameters.SequenceEqual(expectedParameters)); using (var objLocal = emitter.LocalsPool.GetLocal(xdirect.WinUITypes.IXamlDirectObject)) using (var valLocal = emitter.LocalsPool.GetLocal(paramType)) { emitter .Stloc(valLocal.Local) .Stloc(objLocal.Local) .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })) .Ldloc(objLocal.Local) .Ldc_I4((int)xdirect.PropertyIndex.GetLiteralValue()) .Ldloc(valLocal.Local) .EmitCall(setterMethod); } return(true); } return(false); }
public XamlILNodeEmitResult Emit(IXamlAstNode node, XamlEmitContext <IXamlILEmitter, XamlILNodeEmitResult> context, IXamlILEmitter codeGen) { if (node is XamlDirectNewObjectNode objNode) { IXamlType xamlDirectType = context.GetWinUITypes().XamlDirect; codeGen .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("GetDefault", xamlDirectType) { IsStatic = true })) .Ldc_I4((int)objNode.TypeIndex.GetLiteralValue()) .EmitCall(xamlDirectType.GetMethod(new FindMethodMethodSignature("CreateInstance", context.GetWinUITypes().IXamlDirectObject, context.GetWinUITypes().XamlTypeIndex))); return(XamlILNodeEmitResult.Type(0, context.GetWinUITypes().IXamlDirectObject)); } return(null); }
private void EmitLoadPropertyAccessorFactory(XamlIlEmitContext context, IXamlILEmitter codeGen, IXamlType type, string accessorFactoryName, bool isStatic = true) { var types = context.GetAvaloniaTypes(); var weakReferenceType = context.Configuration.TypeSystem.GetType("System.WeakReference`1").MakeGenericType(context.Configuration.WellKnownTypes.Object); FindMethodMethodSignature accessorFactorySignature = new FindMethodMethodSignature(accessorFactoryName, types.IPropertyAccessor, weakReferenceType, types.IPropertyInfo) { IsStatic = isStatic }; codeGen.Ldftn(type.GetMethod(accessorFactorySignature)); }
public static bool TryConvert(AstTransformationContext context, IXamlAstValueNode node, string text, IXamlType type, AvaloniaXamlIlWellKnownTypes types, out IXamlAstValueNode result) { 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); } if (type.Equals(types.Thickness)) { try { var thickness = Thickness.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Thickness, types.ThicknessFullConstructor, new[] { thickness.Left, thickness.Top, thickness.Right, thickness.Bottom }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a thickness", node); } } if (type.Equals(types.Point)) { try { var point = Point.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Point, types.PointFullConstructor, new[] { point.X, point.Y }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a point", node); } } if (type.Equals(types.Vector)) { try { var vector = Vector.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Vector, types.VectorFullConstructor, new[] { vector.X, vector.Y }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a vector", node); } } if (type.Equals(types.Size)) { try { var size = Size.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Size, types.SizeFullConstructor, new[] { size.Width, size.Height }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a size", node); } } if (type.Equals(types.Matrix)) { try { var matrix = Matrix.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Matrix, types.MatrixFullConstructor, new[] { matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.M31, matrix.M32 }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a matrix", node); } } if (type.Equals(types.CornerRadius)) { try { var cornerRadius = CornerRadius.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.CornerRadius, types.CornerRadiusFullConstructor, new[] { cornerRadius.TopLeft, cornerRadius.TopRight, cornerRadius.BottomRight, cornerRadius.BottomLeft }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a corner radius", node); } } if (type.Equals(types.Color)) { if (!Color.TryParse(text, out Color color)) { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a color", node); } result = new XamlStaticOrTargetedReturnMethodCallNode(node, type.GetMethod( new FindMethodMethodSignature("FromUInt32", type, types.UInt) { IsStatic = true }), new[] { new XamlConstantNode(node, types.UInt, color.ToUint32()) }); return(true); } if (type.Equals(types.GridLength)) { try { var gridLength = GridLength.Parse(text); result = new AvaloniaXamlIlGridLengthAstNode(node, types, gridLength); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a grid length", node); } } if (type.Equals(types.Cursor)) { if (TypeSystemHelpers.TryGetEnumValueNode(types.StandardCursorType, text, node, out var enumConstantNode)) { var cursorTypeRef = new XamlAstClrTypeReference(node, types.Cursor, false); result = new XamlAstNewClrObjectNode(node, cursorTypeRef, types.CursorTypeConstructor, new List <IXamlAstValueNode> { enumConstantNode }); return(true); } } if (type.Equals(types.ColumnDefinitions)) { return(ConvertDefinitionList(node, text, types, types.ColumnDefinitions, types.ColumnDefinition, "column definitions", out result)); } if (type.Equals(types.RowDefinitions)) { return(ConvertDefinitionList(node, text, types, types.RowDefinitions, types.RowDefinition, "row definitions", out result)); } if (type.Equals(types.Classes)) { var classes = text.Split(' '); var classNodes = classes.Select(c => new XamlAstTextNode(node, c, types.XamlIlTypes.String)).ToArray(); result = new AvaloniaXamlIlAvaloniaListConstantAstNode(node, types, types.Classes, types.XamlIlTypes.String, classNodes); return(true); } result = null; return(false); }
public static bool CustomValueConverter(AstTransformationContext context, IXamlAstValueNode node, IXamlType type, out IXamlAstValueNode result) { if (!(node is XamlAstTextNode textNode)) { 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); } if (type.Equals(types.Thickness)) { try { var thickness = Thickness.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Thickness, types.ThicknessFullConstructor, new[] { thickness.Left, thickness.Top, thickness.Right, thickness.Bottom }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a thickness", node); } } if (type.Equals(types.Point)) { try { var point = Point.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Point, types.PointFullConstructor, new[] { point.X, point.Y }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a point", node); } } if (type.Equals(types.Vector)) { try { var vector = Vector.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Vector, types.VectorFullConstructor, new[] { vector.X, vector.Y }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a vector", node); } } if (type.Equals(types.Size)) { try { var size = Size.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Size, types.SizeFullConstructor, new[] { size.Width, size.Height }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a size", node); } } if (type.Equals(types.Matrix)) { try { var matrix = Matrix.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.Matrix, types.MatrixFullConstructor, new[] { matrix.M11, matrix.M12, matrix.M21, matrix.M22, matrix.M31, matrix.M32 }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a matrix", node); } } if (type.Equals(types.CornerRadius)) { try { var cornerRadius = CornerRadius.Parse(text); result = new AvaloniaXamlIlVectorLikeConstantAstNode(node, types, types.CornerRadius, types.CornerRadiusFullConstructor, new[] { cornerRadius.TopLeft, cornerRadius.TopRight, cornerRadius.BottomRight, cornerRadius.BottomLeft }); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a corner radius", node); } } if (type.Equals(types.Color)) { if (!Color.TryParse(text, out Color color)) { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a color", node); } result = new XamlStaticOrTargetedReturnMethodCallNode(node, type.GetMethod( new FindMethodMethodSignature("FromUInt32", type, types.UInt) { IsStatic = true }), new[] { new XamlConstantNode(node, types.UInt, color.ToUint32()) }); return(true); } if (type.Equals(types.GridLength)) { try { var gridLength = GridLength.Parse(text); result = new AvaloniaXamlIlGridLengthAstNode(node, types, gridLength); return(true); } catch { throw new XamlX.XamlLoadException($"Unable to parse \"{text}\" as a grid length", node); } } if (type.Equals(types.Cursor)) { if (TypeSystemHelpers.TryGetEnumValueNode(types.StandardCursorType, text, node, out var enumConstantNode)) { var cursorTypeRef = new XamlAstClrTypeReference(node, types.Cursor, false); result = new XamlAstNewClrObjectNode(node, cursorTypeRef, types.CursorTypeConstructor, new List <IXamlAstValueNode> { enumConstantNode }); return(true); } } if (type.FullName == "Avalonia.AvaloniaProperty") { var scope = context.ParentNodes().OfType <AvaloniaXamlIlTargetTypeMetadataNode>().FirstOrDefault(); if (scope == null) { throw new XamlX.XamlLoadException("Unable to find the parent scope for AvaloniaProperty lookup", node); } result = XamlIlAvaloniaPropertyHelper.CreateNode(context, text, scope.TargetType, node); return(true); } result = null; return(false); }