Example #1
0
        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")) });
Example #2
0
        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) },
Example #3
0
        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);
        }
Example #4
0
        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));
        }
Example #5
0
        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));
        }
Example #6
0
 public SetFieldVisitor(ILContext context)
 {
     Context = context;
 }
Example #7
0
 public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef)
 {
     typeRef = module.TypeSystem.Object;
     return(new[] { Instruction.Create(OpCodes.Ldnull) });
 }
Example #8
0
        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) });
        }
Example #9
0
        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));
                }
            }
        }
Example #10
0
        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));
        }