public static TypeReference GetTypeReference(string xmlType, ModuleDefinition module, IElementNode node)
        {
            var split = xmlType.Split(':');

            if (split.Length > 2)
            {
                throw new XamlParseException($"Type \"{xmlType}\" is invalid", node as IXmlLineInfo);
            }

            string prefix, name;

            if (split.Length == 2)
            {
                prefix = split [0];
                name   = split [1];
            }
            else
            {
                prefix = "";
                name   = split [0];
            }
            var namespaceuri = node.NamespaceResolver.LookupNamespace(prefix) ?? "";

            return(XmlTypeExtensions.GetTypeReference(new XmlType(namespaceuri, name, null), module, node as IXmlLineInfo));
        }
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
        {
            memberRef = module.ImportReference(("mscorlib", "System", "Type"));
            INode typeNameNode;

            var name = new XmlName("", "TypeName");

            if (!node.Properties.TryGetValue(name, out typeNameNode) && node.CollectionItems.Any())
            {
                typeNameNode = node.CollectionItems[0];
            }

            var valueNode = typeNameNode as ValueNode;

            if (valueNode == null)
            {
                throw new XamlParseException("TypeName isn't set.", node as XmlLineInfo);
            }

            if (!node.Properties.ContainsKey(name))
            {
                node.Properties[name] = typeNameNode;
                node.CollectionItems.Clear();
            }

            var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode));

            context.TypeExtensions[node] = typeref ?? throw new XamlParseException($"Can't resolve type `{valueNode.Value}'.", node as IXmlLineInfo);

            return(new List <Instruction> {
                Create(Ldtoken, module.ImportReference(typeref)),
                Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
                                                          methodName: "GetTypeFromHandle",
                                                          parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
Exemple #3
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
        {
            memberRef = module.ImportReference(("mscorlib", "System", "Type"));
            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(Xamarin.Forms.Xaml.TypeExtension));
            }

            if (!node.Properties.ContainsKey(name))
            {
                node.Properties[name] = typeNameNode;
                node.CollectionItems.Clear();
            }

            var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode));

            context.TypeExtensions[node] = typeref ?? throw new BuildException(BuildExceptionCode.TypeResolution, node as IXmlLineInfo, null, valueNode.Value);

            return(new List <Instruction> {
                Create(Ldtoken, module.ImportReference(typeref)),
                Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
                                                          methodName: "GetTypeFromHandle",
                                                          parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
Exemple #4
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef)
        {
            typeRef = module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "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(Xamarin.Forms.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")) });
Exemple #5
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference typeRef)
        {
            typeRef = module.ImportReference(("Xamarin.Forms.Core", "Xamarin.Forms", "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 XamlParseException("TypeName isn't set.", node as XmlLineInfo);
            }

            var contentTypeRef = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode))
                                 ?? throw new XamlParseException($"Can't resolve type `{valueNode.Value}'.", node as IXmlLineInfo);

            var dataTemplateCtor = module.ImportCtorReference(typeRef, new[] { module.ImportReference(("mscorlib", "System", "Type")) });
Exemple #6
0
        public IEnumerable <Instruction> ProvideValue(IElementNode node, ModuleDefinition module, ILContext context, out TypeReference memberRef)
        {
            memberRef = module.ImportReferenceCached(typeof(Type));
            INode typeNameNode;

            var name = new XmlName("", "TypeName");

            if (!node.Properties.TryGetValue(name, out typeNameNode) && node.CollectionItems.Any())
            {
                typeNameNode = node.CollectionItems[0];
            }

            var valueNode = typeNameNode as ValueNode;

            if (valueNode == null)
            {
                throw new XamlParseException("TypeName isn't set.", node as XmlLineInfo);
            }

            if (!node.Properties.ContainsKey(name))
            {
                node.Properties[name] = typeNameNode;
                node.CollectionItems.Clear();
            }

            var typeref = module.ImportReference(XmlTypeExtensions.GetTypeReference(valueNode.Value as string, module, node as BaseNode));

            if (typeref == null)
            {
                throw new XamlParseException($"Can't resolve type `{valueNode.Value}'.", node as IXmlLineInfo);
            }

            context.TypeExtensions[node] = typeref;

            var getTypeFromHandle = module.ImportReferenceCached(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) }));

            return(new List <Instruction> {
                Instruction.Create(OpCodes.Ldtoken, module.ImportReference(typeref)),
                Instruction.Create(OpCodes.Call, module.ImportReference(getTypeFromHandle))
            });
        }
Exemple #7
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("."))
            {
                var lineInfo = node as IXmlLineInfo;
                throw new XamlParseException("Syntax for x:Static is [Member=][prefix:]typeName.staticMemberName", lineInfo);
            }

            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 XamlParseException($"x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named {membername} in {typename}", node as IXmlLineInfo);
            }

            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) });
        }