public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef) { typeRef = module.ImportReference(("Microsoft.Maui.Controls", "Microsoft.Maui.Controls", "DataTemplate")); var name = new XmlName("", "TypeName"); if (!node.Properties.TryGetValue(name, out INode typeNameNode) && node.CollectionItems.Any()) { typeNameNode = node.CollectionItems[0]; } if (!(typeNameNode is ValueNode valueNode)) { throw new BuildException(BuildExceptionCode.PropertyMissing, node as IXmlLineInfo, null, "TypeName", typeof(Microsoft.Maui.Controls.Xaml.DataTemplateExtension)); } var contentTypeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode)) ?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value); var dataTemplateCtor = module.ImportCtorReference(typeRef, new[] { module.ImportReference(("mscorlib", "System", "Type")) });
public static IEnumerable <Instruction> PushConvertedValue(this ValueNode node, ILContext context, TypeReference targetTypeRef, TypeReference typeConverter, IEnumerable <Instruction> pushServiceProvider, bool boxValueTypes, bool unboxValueTypes) { var module = context.Body.Method.Module; if (KnownCompiledTypeConverters == null) { KnownCompiledTypeConverters = new Dictionary <TypeReference, Type>(TypeRefComparer.Default) { { module.ImportReference(("Microsoft.Maui", "Microsoft.Maui.Converters", "ThicknessTypeConverter")), typeof(ThicknessTypeConverter) },
public static bool CanConvertValue(this ValueNode node, ILContext context, TypeReference targetTypeRef, TypeReference typeConverter) { var str = (string)node.Value; var module = context.Body.Method.Module; //If there's a [TypeConverter], assume we can convert if (typeConverter != null && str != null) { return(true); } //check if it's assignable from a string if (targetTypeRef.ResolveCached().FullName == "System.Nullable`1") { targetTypeRef = ((GenericInstanceType)targetTypeRef).GenericArguments[0]; } if (targetTypeRef.ResolveCached().BaseType != null && targetTypeRef.ResolveCached().BaseType.FullName == "System.Enum") { return(true); } if (targetTypeRef.FullName == "System.Char") { return(true); } if (targetTypeRef.FullName == "System.SByte") { return(true); } if (targetTypeRef.FullName == "System.Int16") { return(true); } if (targetTypeRef.FullName == "System.Int32") { return(true); } if (targetTypeRef.FullName == "System.Int64") { return(true); } if (targetTypeRef.FullName == "System.Byte") { return(true); } if (targetTypeRef.FullName == "System.UInt16") { return(true); } if (targetTypeRef.FullName == "System.UInt32") { return(true); } if (targetTypeRef.FullName == "System.UInt64") { return(true); } if (targetTypeRef.FullName == "System.Single") { return(true); } if (targetTypeRef.FullName == "System.Double") { return(true); } if (targetTypeRef.FullName == "System.Boolean") { return(true); } if (targetTypeRef.FullName == "System.TimeSpan") { return(true); } if (targetTypeRef.FullName == "System.DateTime") { return(true); } if (targetTypeRef.FullName == "System.String") { return(true); } if (targetTypeRef.FullName == "System.Object") { return(true); } if (targetTypeRef.FullName == "System.Decimal") { return(true); } var implicitOperator = module.TypeSystem.String.GetImplicitOperatorTo(targetTypeRef, module); if (implicitOperator != null) { return(true); } return(false); }
public static IEnumerable <Instruction> PushConvertedValue(this ValueNode node, ILContext context, TypeReference targetTypeRef, IEnumerable <ICustomAttributeProvider> attributeProviders, IEnumerable <Instruction> pushServiceProvider, bool boxValueTypes, bool unboxValueTypes) { TypeReference typeConverter = null; foreach (var attributeProvider in attributeProviders) { CustomAttribute typeConverterAttribute; if ( (typeConverterAttribute = attributeProvider.CustomAttributes.FirstOrDefault( cad => cad.AttributeType.FullName == "System.ComponentModel.TypeConverterAttribute")) != null) { typeConverter = typeConverterAttribute.ConstructorArguments[0].Value as TypeReference; break; } } if (typeConverter == null) { foreach (var(t, tc) in TypeConversionExtensions.KnownConverters) { if (TypeRefComparer.Default.Equals(context.Module.ImportReference(t), targetTypeRef)) { typeConverter = context.Module.ImportReference(tc); break; } } } return(node.PushConvertedValue(context, targetTypeRef, typeConverter, pushServiceProvider, boxValueTypes, unboxValueTypes)); }
public static IEnumerable <Instruction> PushConvertedValue(this ValueNode node, ILContext context, FieldReference bpRef, IEnumerable <Instruction> pushServiceProvider, bool boxValueTypes, bool unboxValueTypes) { var module = context.Body.Method.Module; var targetTypeRef = bpRef.GetBindablePropertyType(node, module); var typeConverter = bpRef.GetBindablePropertyTypeConverter(module); return(node.PushConvertedValue(context, targetTypeRef, typeConverter, pushServiceProvider, boxValueTypes, unboxValueTypes)); }
public SetFieldVisitor(ILContext context) { Context = context; }
public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef) { typeRef = module.TypeSystem.Object; return(new[] { Instruction.Create(OpCodes.Ldnull) }); }
public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef) { INode ntype; if (!node.Properties.TryGetValue(new XmlName("", "Member"), out ntype)) { ntype = node.CollectionItems[0]; } var member = ((ValueNode)ntype).Value as string; if (IsNullOrEmpty(member) || !member.Contains(".")) { throw new BuildException(BuildExceptionCode.XStaticSyntax, node as IXmlLineInfo, null); } var dotIdx = member.LastIndexOf('.'); var typename = member.Substring(0, dotIdx); var membername = member.Substring(dotIdx + 1); var typeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(typename, module, node as BaseNode)); var fieldRef = GetFieldReference(typeRef, membername, module); var propertyDef = GetPropertyDefinition(typeRef, membername, module); if (fieldRef == null && propertyDef == null) { throw new BuildException(BuildExceptionCode.XStaticResolution, node as IXmlLineInfo, null, membername, typename); } var fieldDef = fieldRef?.Resolve(); if (fieldRef != null) { memberRef = fieldRef.FieldType; if (!fieldDef.HasConstant) { return new[] { Instruction.Create(OpCodes.Ldsfld, fieldRef) } } ; //Constants can be numbers, Boolean values, strings, or a null reference. (https://msdn.microsoft.com/en-us/library/e6w8fe1b.aspx) if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Boolean)) { return new[] { Instruction.Create(((bool)fieldDef.Constant) ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.String)) { return new[] { Instruction.Create(OpCodes.Ldstr, (string)fieldDef.Constant) } } ; if (fieldDef.Constant == null) { return new[] { Instruction.Create(OpCodes.Ldnull) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Char)) { return new[] { Instruction.Create(OpCodes.Ldc_I4, (char)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Single)) { return new[] { Instruction.Create(OpCodes.Ldc_R4, (float)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Double)) { return new[] { Instruction.Create(OpCodes.Ldc_R8, (double)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Byte) || TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Int16) || TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Int32)) { return new[] { Instruction.Create(OpCodes.Ldc_I4, (int)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.SByte) || TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.UInt16) || TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.UInt32)) { return new[] { Instruction.Create(OpCodes.Ldc_I4, (uint)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.Int64)) { return new[] { Instruction.Create(OpCodes.Ldc_I8, (long)fieldDef.Constant) } } ; if (TypeRefComparer.Default.Equals(memberRef, module.TypeSystem.UInt64)) { return new[] { Instruction.Create(OpCodes.Ldc_I8, (ulong)fieldDef.Constant) } } ; //enum values if (memberRef.ResolveCached().IsEnum) { if (fieldDef.Constant is long) { return new[] { Instruction.Create(OpCodes.Ldc_I8, (long)fieldDef.Constant) } } ; if (fieldDef.Constant is ulong) { return new[] { Instruction.Create(OpCodes.Ldc_I8, (ulong)fieldDef.Constant) } } ; if (fieldDef.Constant is uint) { return new[] { Instruction.Create(OpCodes.Ldc_I4, (uint)fieldDef.Constant) } } ; //everything else will cast just fine to an int return(new[] { Instruction.Create(OpCodes.Ldc_I4, (int)fieldDef.Constant) }); } } memberRef = propertyDef.PropertyType; var getterDef = module.ImportReference(propertyDef.GetMethod); return(new[] { Instruction.Create(OpCodes.Call, getterDef) }); }
IEnumerable <Instruction> ProvideValue(TypeReference typeTypeRef, IReadOnlyList <INode> items, ModuleDefinition module, ILContext context) { var n = items.Count; yield return(Instruction.Create(OpCodes.Ldc_I4, n)); yield return(Instruction.Create(OpCodes.Newarr, typeTypeRef)); for (var i = 0; i < n; i++) { var vardef = context.Variables[items[i] as IElementNode]; if (typeTypeRef.IsValueType) { yield return(Instruction.Create(OpCodes.Dup)); yield return(Instruction.Create(OpCodes.Ldc_I4, i)); yield return(Instruction.Create(OpCodes.Ldelema, typeTypeRef)); foreach (var instruction in vardef.LoadAs(typeTypeRef, module)) { yield return(instruction); } yield return(Instruction.Create(OpCodes.Stobj, typeTypeRef)); } else { yield return(Instruction.Create(OpCodes.Dup)); yield return(Instruction.Create(OpCodes.Ldc_I4, i)); foreach (var instruction in vardef.LoadAs(typeTypeRef, module)) { yield return(instruction); } yield return(Instruction.Create(OpCodes.Stelem_Ref)); } } }
public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef) { var typeNode = node.Properties[new XmlName("", "Type")] as IElementNode; var typeTypeRef = context.TypeExtensions[typeNode]; memberRef = typeTypeRef.MakeArrayType(); return(ProvideValue(typeTypeRef, node.CollectionItems, module, context)); }