Esempio n. 1
0
        private bool ValidatesReflectionAccessPatterns(TypeDefinition testCaseTypeDefinition)
        {
            if (testCaseTypeDefinition.HasNestedTypes)
            {
                var nestedTypes = new Queue <TypeDefinition> (testCaseTypeDefinition.NestedTypes.ToList());
                while (nestedTypes.Count > 0)
                {
                    if (ValidatesReflectionAccessPatterns(nestedTypes.Dequeue()))
                    {
                        return(true);
                    }
                }
            }

            if (testCaseTypeDefinition.CustomAttributes.Any(attr =>
                                                            attr.AttributeType.Name == nameof(VerifyAllReflectionAccessPatternsAreValidatedAttribute)) ||
                testCaseTypeDefinition.AllMethods().Any(method => method.CustomAttributes.Any(attr =>
                                                                                              attr.AttributeType.Name == nameof(RecognizedReflectionAccessPatternAttribute) ||
                                                                                              attr.AttributeType.Name == nameof(UnrecognizedReflectionAccessPatternAttribute))))
            {
                return(true);
            }

            return(false);
        }
Esempio n. 2
0
 public static MethodDefinition Find(this TypeDefinition typeReference, string name, params string[] paramTypes)
 {
     foreach (var method in typeReference.AllMethods())
     {
         if (method.IsMatch(name, paramTypes))
         {
             return(method);
         }
     }
     throw new WeavingException($"Could not find '{name}' on '{typeReference.Name}'");
 }
Esempio n. 3
0
        public virtual void CustomizeLinker(LinkerDriver linker, LinkerCustomizations customizations)
        {
            if (_testCaseTypeDefinition.CustomAttributes.Any(attr =>
                                                             attr.AttributeType.Name == nameof(DependencyRecordedAttribute)))
            {
                customizations.DependencyRecorder = new TestDependencyRecorder();
                customizations.CustomizeContext  += context => {
                    context.Tracer.AddRecorder(customizations.DependencyRecorder);
                };
            }

            if (_testCaseTypeDefinition.CustomAttributes.Any(attr =>
                                                             attr.AttributeType.Name == nameof(VerifyAllReflectionAccessPatternsAreValidatedAttribute)) ||
                _testCaseTypeDefinition.AllMethods().Any(method => method.CustomAttributes.Any(attr =>
                                                                                               attr.AttributeType.Name == nameof(RecognizedReflectionAccessPatternAttribute) ||
                                                                                               attr.AttributeType.Name == nameof(UnrecognizedReflectionAccessPatternAttribute))))
            {
                customizations.ReflectionPatternRecorder = new TestReflectionPatternRecorder();
                customizations.CustomizeContext         += context => {
                    context.ReflectionPatternRecorder = customizations.ReflectionPatternRecorder;
                };
            }
            else if (_testCaseTypeDefinition.HasNestedTypes &&
                     _testCaseTypeDefinition.NestedTypes.Any(nestedType =>
                                                             nestedType.CustomAttributes.Any(attr =>
                                                                                             attr.AttributeType.Name == nameof(VerifyAllReflectionAccessPatternsAreValidatedAttribute) ||
                                                                                             nestedType.AllMethods().Any(method => method.CustomAttributes.Any(attr =>
                                                                                                                                                               attr.AttributeType.Name == nameof(RecognizedReflectionAccessPatternAttribute) ||
                                                                                                                                                               attr.AttributeType.Name == nameof(UnrecognizedReflectionAccessPatternAttribute))))))
            {
                customizations.ReflectionPatternRecorder = new TestReflectionPatternRecorder();
                customizations.CustomizeContext         += context => {
                    context.ReflectionPatternRecorder = customizations.ReflectionPatternRecorder;
                };
            }
        }
Esempio n. 4
0
        public void Visit(ElementNode node, INode parentNode)
        {
            var            typeref = Module.Import(node.XmlType.GetTypeReference(Module, node));
            TypeDefinition typedef = typeref.Resolve();

            if (IsXaml2009LanguagePrimitive(node))
            {
                var vardef = new VariableDefinition(typeref);
                Context.Variables [node] = vardef;
                Context.Body.Variables.Add(vardef);

                Context.IL.Append(PushValueFromLanguagePrimitive(typedef, node));
                Context.IL.Emit(OpCodes.Stloc, vardef);
                return;
            }

            if (typeref.FullName == "Xamarin.Forms.Xaml.StaticExtension")
            {
                var markupProvider = new StaticExtension();

                var il = markupProvider.ProvideValue(node, Module, Context, out typeref);
                typeref = Module.Import(typeref);

                var vardef = new VariableDefinition(typeref);
                Context.Variables [node] = vardef;
                Context.Body.Variables.Add(vardef);

                Context.IL.Append(il);
                Context.IL.Emit(OpCodes.Stloc, vardef);

                //clean the node as it has been fully exhausted
                node.Properties.Clear();
                node.CollectionItems.Clear();
                return;
            }

            MethodDefinition factoryCtorInfo       = null;
            MethodDefinition factoryMethodInfo     = null;
            MethodDefinition parameterizedCtorInfo = null;
            MethodDefinition ctorInfo = null;

            if (node.Properties.ContainsKey(XmlName.xArguments) && !node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                factoryCtorInfo = typedef.AllMethods().FirstOrDefault(md => md.IsConstructor &&
                                                                      !md.IsStatic &&
                                                                      md.HasParameters &&
                                                                      md.MatchXArguments(node, Module, Context));
                if (factoryCtorInfo == null)
                {
                    throw new XamlParseException(
                              string.Format("No constructors found for {0} with matching x:Arguments", typedef.FullName), node);
                }
                ctorInfo = factoryCtorInfo;
                if (!typedef.IsValueType)                 //for ctor'ing typedefs, we first have to ldloca before the params
                {
                    Context.IL.Append(PushCtorXArguments(factoryCtorInfo, node));
                }
            }
            else if (node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                var factoryMethod = (string)(node.Properties [XmlName.xFactoryMethod] as ValueNode).Value;
                factoryMethodInfo = typedef.AllMethods().FirstOrDefault(md => !md.IsConstructor &&
                                                                        md.Name == factoryMethod &&
                                                                        md.IsStatic &&
                                                                        md.MatchXArguments(node, Module, Context));
                if (factoryMethodInfo == null)
                {
                    throw new XamlParseException(
                              String.Format("No static method found for {0}::{1} ({2})", typedef.FullName, factoryMethod, null), node);
                }
                Context.IL.Append(PushCtorXArguments(factoryMethodInfo, node));
            }
            if (ctorInfo == null && factoryMethodInfo == null)
            {
                parameterizedCtorInfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor &&
                                                                       !md.IsStatic &&
                                                                       md.HasParameters &&
                                                                       md.Parameters.All(
                                                                           pd =>
                                                                           pd.CustomAttributes.Any(
                                                                               ca =>
                                                                               ca.AttributeType.FullName ==
                                                                               "Xamarin.Forms.ParameterAttribute")));
            }
            if (parameterizedCtorInfo != null && ValidateCtorArguments(parameterizedCtorInfo, node))
            {
                ctorInfo = parameterizedCtorInfo;
//				IL_0000:  ldstr "foo"
                Context.IL.Append(PushCtorArguments(parameterizedCtorInfo, node));
            }
            ctorInfo = ctorInfo ?? typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters && !md.IsStatic);

            var ctorinforef          = ctorInfo?.ResolveGenericParameters(typeref, Module);
            var factorymethodinforef = factoryMethodInfo?.ResolveGenericParameters(typeref, Module);
            var implicitOperatorref  = typedef.Methods.FirstOrDefault(md =>
                                                                      md.IsPublic &&
                                                                      md.IsStatic &&
                                                                      md.IsSpecialName &&
                                                                      md.Name == "op_Implicit" && md.Parameters [0].ParameterType.FullName == "System.String");

            if (ctorinforef != null || factorymethodinforef != null || typedef.IsValueType)
            {
                VariableDefinition vardef = new VariableDefinition(typeref);
                Context.Variables [node] = vardef;
                Context.Body.Variables.Add(vardef);

                ValueNode vnode = null;
                if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                    vardef.VariableType.IsValueType)
                {
                    //<Color>Purple</Color>
                    Context.IL.Append(vnode.PushConvertedValue(Context, typeref, new ICustomAttributeProvider [] { typedef },
                                                               node.PushServiceProvider(Context), false, true));
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                         implicitOperatorref != null)
                {
                    //<FileImageSource>path.png</FileImageSource>
                    var implicitOperator = Module.Import(implicitOperatorref);
                    Context.IL.Emit(OpCodes.Ldstr, ((ValueNode)(node.CollectionItems.First())).Value as string);
                    Context.IL.Emit(OpCodes.Call, implicitOperator);
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (factorymethodinforef != null)
                {
                    Context.IL.Emit(OpCodes.Call, Module.Import(factorymethodinforef));
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (!typedef.IsValueType)
                {
                    var ctor = Module.Import(ctorinforef);
//					IL_0001:  newobj instance void class [Xamarin.Forms.Core]Xamarin.Forms.Button::'.ctor'()
//					IL_0006:  stloc.0
                    Context.IL.Emit(OpCodes.Newobj, ctor);
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (ctorInfo != null && node.Properties.ContainsKey(XmlName.xArguments) &&
                         !node.Properties.ContainsKey(XmlName.xFactoryMethod) && ctorInfo.MatchXArguments(node, Module, Context))
                {
//					IL_0008:  ldloca.s 1
//					IL_000a:  ldc.i4.1
//					IL_000b:  call instance void valuetype Test/Foo::'.ctor'(bool)

                    var ctor = Module.Import(ctorinforef);
                    Context.IL.Emit(OpCodes.Ldloca, vardef);
                    Context.IL.Append(PushCtorXArguments(factoryCtorInfo, node));
                    Context.IL.Emit(OpCodes.Call, ctor);
                }
                else
                {
//					IL_0000:  ldloca.s 0
//					IL_0002:  initobj Test/Foo
                    Context.IL.Emit(OpCodes.Ldloca, vardef);
                    Context.IL.Emit(OpCodes.Initobj, Module.Import(typedef));
                }

                if (typeref.FullName == "Xamarin.Forms.Xaml.TypeExtension")
                {
                    var visitor = new SetPropertiesVisitor(Context);
                    foreach (var cnode in node.Properties.Values.ToList())
                    {
                        cnode.Accept(visitor, node);
                    }
                    foreach (var cnode in node.CollectionItems)
                    {
                        cnode.Accept(visitor, node);
                    }

                    //As we're stripping the TypeExtension bare, keep the type if we need it later (hint: we do need it)
                    INode ntype;
                    if (!node.Properties.TryGetValue(new XmlName("", "TypeName"), out ntype))
                    {
                        ntype = node.CollectionItems [0];
                    }

                    var type   = ((ValueNode)ntype).Value as string;
                    var prefix = "";
                    if (type.Contains(":"))
                    {
                        prefix = type.Split(':') [0].Trim();
                        type   = type.Split(':') [1].Trim();
                    }
                    var namespaceuri = node.NamespaceResolver.LookupNamespace(prefix);
                    Context.TypeExtensions [node] = new XmlType(namespaceuri, type, null).GetTypeReference(Module, node);

                    if (!node.SkipProperties.Contains(new XmlName("", "TypeName")))
                    {
                        node.SkipProperties.Add(new XmlName("", "TypeName"));
                    }

                    var vardefref = new VariableDefinitionReference(vardef);
                    Context.IL.Append(SetPropertiesVisitor.ProvideValue(vardefref, Context, Module, node));
                    if (vardef != vardefref.VariableDefinition)
                    {
                        Context.Variables [node] = vardefref.VariableDefinition;
                        Context.Body.Variables.Add(vardefref.VariableDefinition);
                    }
                }

                if (typeref.FullName == "Xamarin.Forms.Xaml.ArrayExtension")
                {
                    var visitor = new SetPropertiesVisitor(Context);
                    foreach (var cnode in node.Properties.Values.ToList())
                    {
                        cnode.Accept(visitor, node);
                    }
                    foreach (var cnode in node.CollectionItems)
                    {
                        cnode.Accept(visitor, node);
                    }

                    var markupProvider = new ArrayExtension();

                    var il = markupProvider.ProvideValue(node, Module, Context, out typeref);

                    vardef = new VariableDefinition(typeref);
                    Context.Variables[node] = vardef;
                    Context.Body.Variables.Add(vardef);

                    Context.IL.Append(il);
                    Context.IL.Emit(OpCodes.Stloc, vardef);

                    //clean the node as it has been fully exhausted
                    node.Properties.Remove(new XmlName("", "Type"));
                    node.CollectionItems.Clear();
                }
            }
        }
Esempio n. 5
0
        public void Visit(ElementNode node, INode parentNode)
        {
            var            typeref = Module.ImportReference(node.XmlType.GetTypeReference(Module, node));
            TypeDefinition typedef = typeref.ResolveCached();

            if (IsXaml2009LanguagePrimitive(node))
            {
                var vardef = new VariableDefinition(typeref);
                Context.Variables [node] = vardef;
                Context.Body.Variables.Add(vardef);

                Context.IL.Append(PushValueFromLanguagePrimitive(typedef, node));
                Context.IL.Emit(OpCodes.Stloc, vardef);
                return;
            }

            //if this is a MarkupExtension that can be compiled directly, compile and returns the value
            var compiledMarkupExtensionName = typeref
                                              .GetCustomAttribute(Module, ("Xamarin.Forms.Core", "Xamarin.Forms.Xaml", "ProvideCompiledAttribute"))
                                              ?.ConstructorArguments?[0].Value as string;
            Type compiledMarkupExtensionType;
            ICompiledMarkupExtension markupProvider;

            if (compiledMarkupExtensionName != null &&
                (compiledMarkupExtensionType = Type.GetType(compiledMarkupExtensionName)) != null &&
                (markupProvider = Activator.CreateInstance(compiledMarkupExtensionType) as ICompiledMarkupExtension) != null)
            {
                var il = markupProvider.ProvideValue(node, Module, Context, out typeref);
                typeref = Module.ImportReference(typeref);

                var vardef = new VariableDefinition(typeref);
                Context.Variables[node] = vardef;
                Context.Body.Variables.Add(vardef);

                Context.IL.Append(il);
                Context.IL.Emit(OpCodes.Stloc, vardef);

                //clean the node as it has been fully exhausted
                foreach (var prop in node.Properties)
                {
                    if (!node.SkipProperties.Contains(prop.Key))
                    {
                        node.SkipProperties.Add(prop.Key);
                    }
                }
                node.CollectionItems.Clear();
                return;
            }

            MethodDefinition factoryCtorInfo       = null;
            MethodDefinition factoryMethodInfo     = null;
            MethodDefinition parameterizedCtorInfo = null;
            MethodDefinition ctorInfo = null;

            if (node.Properties.ContainsKey(XmlName.xArguments) && !node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                factoryCtorInfo = typedef.AllMethods().FirstOrDefault(md => md.IsConstructor &&
                                                                      !md.IsStatic &&
                                                                      md.HasParameters &&
                                                                      md.MatchXArguments(node, typeref, Module, Context));
                if (factoryCtorInfo == null)
                {
                    throw new XamlParseException(
                              string.Format("No constructors found for {0} with matching x:Arguments", typedef.FullName), node);
                }
                ctorInfo = factoryCtorInfo;
                if (!typedef.IsValueType)                 //for ctor'ing typedefs, we first have to ldloca before the params
                {
                    Context.IL.Append(PushCtorXArguments(factoryCtorInfo, node));
                }
            }
            else if (node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                var factoryMethod = (string)(node.Properties [XmlName.xFactoryMethod] as ValueNode).Value;
                factoryMethodInfo = typedef.AllMethods().FirstOrDefault(md => !md.IsConstructor &&
                                                                        md.Name == factoryMethod &&
                                                                        md.IsStatic &&
                                                                        md.MatchXArguments(node, typeref, Module, Context));
                if (factoryMethodInfo == null)
                {
                    throw new XamlParseException(
                              String.Format("No static method found for {0}::{1} ({2})", typedef.FullName, factoryMethod, null), node);
                }
                Context.IL.Append(PushCtorXArguments(factoryMethodInfo, node));
            }
            if (ctorInfo == null && factoryMethodInfo == null)
            {
                parameterizedCtorInfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor &&
                                                                       !md.IsStatic &&
                                                                       md.HasParameters &&
                                                                       md.Parameters.All(
                                                                           pd =>
                                                                           pd.CustomAttributes.Any(
                                                                               ca =>
                                                                               ca.AttributeType.FullName ==
                                                                               "Xamarin.Forms.ParameterAttribute")));
            }
            string missingCtorParameter = null;

            if (parameterizedCtorInfo != null && ValidateCtorArguments(parameterizedCtorInfo, node, out missingCtorParameter))
            {
                ctorInfo = parameterizedCtorInfo;
//				IL_0000:  ldstr "foo"
                Context.IL.Append(PushCtorArguments(parameterizedCtorInfo, node));
            }
            ctorInfo = ctorInfo ?? typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters && !md.IsStatic);
            if (parameterizedCtorInfo != null && ctorInfo == null)
            {
                //there was a parameterized ctor, we didn't use it
                throw new XamlParseException($"The Property '{missingCtorParameter}' is required to create a '{typedef.FullName}' object.", node);
            }
            var ctorinforef          = ctorInfo?.ResolveGenericParameters(typeref, Module);
            var factorymethodinforef = factoryMethodInfo?.ResolveGenericParameters(typeref, Module);
            var implicitOperatorref  = typedef.Methods.FirstOrDefault(md =>
                                                                      md.IsPublic &&
                                                                      md.IsStatic &&
                                                                      md.IsSpecialName &&
                                                                      md.Name == "op_Implicit" && md.Parameters [0].ParameterType.FullName == "System.String");

            if (ctorinforef != null || factorymethodinforef != null || typedef.IsValueType)
            {
                VariableDefinition vardef = new VariableDefinition(typeref);
                Context.Variables [node] = vardef;
                Context.Body.Variables.Add(vardef);

                ValueNode vnode = null;
                if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                    vardef.VariableType.IsValueType)
                {
                    //<Color>Purple</Color>
                    Context.IL.Append(vnode.PushConvertedValue(Context, typeref, new ICustomAttributeProvider [] { typedef },
                                                               node.PushServiceProvider(Context), false, true));
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                         implicitOperatorref != null)
                {
                    //<FileImageSource>path.png</FileImageSource>
                    var implicitOperator = Module.ImportReference(implicitOperatorref);
                    Context.IL.Emit(OpCodes.Ldstr, ((ValueNode)(node.CollectionItems.First())).Value as string);
                    Context.IL.Emit(OpCodes.Call, implicitOperator);
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (factorymethodinforef != null)
                {
                    Context.IL.Emit(OpCodes.Call, Module.ImportReference(factorymethodinforef));
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (!typedef.IsValueType)
                {
                    var ctor = Module.ImportReference(ctorinforef);
//					IL_0001:  newobj instance void class [Xamarin.Forms.Core]Xamarin.Forms.Button::'.ctor'()
//					IL_0006:  stloc.0
                    Context.IL.Emit(OpCodes.Newobj, ctor);
                    Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (ctorInfo != null && node.Properties.ContainsKey(XmlName.xArguments) &&
                         !node.Properties.ContainsKey(XmlName.xFactoryMethod) && ctorInfo.MatchXArguments(node, typeref, Module, Context))
                {
//					IL_0008:  ldloca.s 1
//					IL_000a:  ldc.i4.1
//					IL_000b:  call instance void valuetype Test/Foo::'.ctor'(bool)

                    var ctor = Module.ImportReference(ctorinforef);
                    Context.IL.Emit(OpCodes.Ldloca, vardef);
                    Context.IL.Append(PushCtorXArguments(factoryCtorInfo, node));
                    Context.IL.Emit(OpCodes.Call, ctor);
                }
                else
                {
//					IL_0000:  ldloca.s 0
//					IL_0002:  initobj Test/Foo
                    Context.IL.Emit(OpCodes.Ldloca, vardef);
                    Context.IL.Emit(OpCodes.Initobj, Module.ImportReference(typedef));
                }

                if (typeref.FullName == "Xamarin.Forms.Xaml.ArrayExtension")
                {
                    var visitor = new SetPropertiesVisitor(Context);
                    foreach (var cnode in node.Properties.Values.ToList())
                    {
                        cnode.Accept(visitor, node);
                    }
                    foreach (var cnode in node.CollectionItems)
                    {
                        cnode.Accept(visitor, node);
                    }

                    markupProvider = new ArrayExtension();

                    var il = markupProvider.ProvideValue(node, Module, Context, out typeref);

                    vardef = new VariableDefinition(typeref);
                    Context.Variables[node] = vardef;
                    Context.Body.Variables.Add(vardef);

                    Context.IL.Append(il);
                    Context.IL.Emit(OpCodes.Stloc, vardef);

                    //clean the node as it has been fully exhausted
                    foreach (var prop in node.Properties)
                    {
                        if (!node.SkipProperties.Contains(prop.Key))
                        {
                            node.SkipProperties.Add(prop.Key);
                        }
                    }
                    node.CollectionItems.Clear();

                    return;
                }
            }
        }
Esempio n. 6
0
        public void Visit(ElementNode node, INode parentNode)
        {
            var typeref = Module.ImportReference(node.XmlType.GetTypeReference(XmlTypeExtensions.ModeOfGetType.Both, Module, node));

            if (IsXaml2009LanguagePrimitive(node))
            {
                var vardef = new VariableDefinition(typeref);
                Context.Variables[node] = vardef;

                var value = GetValueFromLanguagePrimitive(typeref, node);

                Context.Values[node] = value;
                return;
            }

            TypeDefinition typedef = typeref.ResolveCached();

            //if this is a MarkupExtension that can be compiled directly, compile and returns the value
            var compiledMarkupExtensionName = typeref
                                              .GetCustomAttribute(Module, (XamlTask.xamlAssemblyName, XamlTask.xamlNameSpace, "ProvideCompiledAttribute"))
                                              ?.ConstructorArguments?[0].Value as string;
            Type compiledMarkupExtensionType;
            ICompiledMarkupExtension markupProvider;

            if (compiledMarkupExtensionName != null &&
                (compiledMarkupExtensionType = Type.GetType(compiledMarkupExtensionName)) != null &&
                (markupProvider = Activator.CreateInstance(compiledMarkupExtensionType) as ICompiledMarkupExtension) != null)
            {
                Context.Values[node] = markupProvider.ProvideValue(node, Module, Context);

                VariableDefinition vardef = new VariableDefinition(typeref);
                Context.Variables[node] = vardef;

                //clean the node as it has been fully exhausted
                foreach (var prop in node.Properties)
                {
                    if (!node.SkipProperties.Contains(prop.Key))
                    {
                        node.SkipProperties.Add(prop.Key);
                    }
                }
                node.CollectionItems.Clear();
                return;
            }

            MethodDefinition factoryCtorInfo       = null;
            MethodDefinition factoryMethodInfo     = null;
            MethodDefinition parameterizedCtorInfo = null;
            MethodDefinition ctorInfo = null;

            if (node.Properties.ContainsKey(XmlName.xArguments) && !node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                factoryCtorInfo = typedef.AllMethods().FirstOrDefault(md => md.IsConstructor &&
                                                                      !md.IsStatic &&
                                                                      md.HasParameters &&
                                                                      md.MatchXArguments(node, typeref, Module, Context));
                if (factoryCtorInfo == null)
                {
                    throw new XamlParseException(
                              string.Format("No constructors found for {0} with matching x:Arguments", typedef.FullName), node);
                }
                ctorInfo = factoryCtorInfo;
                if (!typedef.IsValueType) //for ctor'ing typedefs, we first have to ldloca before the params
                {
                    VariableDefinition vardef = new VariableDefinition(typeref);
                    Context.Variables[node] = vardef;

                    var argumentList = GetCtorXArguments(node, factoryCtorInfo.Parameters.Count, true);
                    Context.Values[node] = new EXamlCreateObject(Context, null, typedef, argumentList.ToArray());
                    return;
                }
            }
            else if (node.Properties.ContainsKey(XmlName.xFactoryMethod))
            {
                var factoryMethod = (string)(node.Properties[XmlName.xFactoryMethod] as ValueNode).Value;
                factoryMethodInfo = typedef.AllMethods().FirstOrDefault(md => !md.IsConstructor &&
                                                                        md.Name == factoryMethod &&
                                                                        md.IsStatic &&
                                                                        md.MatchXArguments(node, typeref, Module, Context));

                if (factoryMethodInfo == null)
                {
                    var typeExtensionRef = Module.ImportReference(node.XmlType.GetTypeReference(XmlTypeExtensions.ModeOfGetType.OnlyGetTypeExtension, Module, node));
                    typeExtensionRef = typeExtensionRef?.ResolveCached();

                    if (null != typeExtensionRef)
                    {
                        factoryMethodInfo = typeExtensionRef.ResolveCached().AllMethods().FirstOrDefault(md => !md.IsConstructor &&
                                                                                                         md.Name == factoryMethod &&
                                                                                                         md.IsStatic &&
                                                                                                         md.MatchXArguments(node, typeExtensionRef, Module, Context));
                    }
                }

                if (factoryMethodInfo == null)
                {
                    throw new XamlParseException(
                              String.Format("No static method found for {0}::{1} ({2})", typedef.FullName, factoryMethod, null), node);
                }

                VariableDefinition vardef = new VariableDefinition(typeref);
                Context.Variables[node] = vardef;

                var argumentList = GetCtorXArguments(node, factoryMethodInfo.Parameters.Count, false);
                Context.Values[node] = new EXamlCreateObject(Context, null, typedef, factoryMethodInfo, argumentList?.ToArray());
                return;
            }

            if (ctorInfo == null && factoryMethodInfo == null)
            {
                parameterizedCtorInfo = typedef.Methods.FirstOrDefault(md => md.IsConstructor &&
                                                                       !md.IsStatic &&
                                                                       md.HasParameters &&
                                                                       md.Parameters.All(
                                                                           pd =>
                                                                           pd.CustomAttributes.Any(
                                                                               ca =>
                                                                               ca.AttributeType.FullName ==
                                                                               "Tizen.NUI.Binding.ParameterAttribute")));
            }
            string        missingCtorParameter    = null;
            List <object> parameterizedCtorParams = null;

            if (parameterizedCtorInfo != null && ValidateCtorArguments(parameterizedCtorInfo, node, out missingCtorParameter))
            {
                ctorInfo = parameterizedCtorInfo;
                parameterizedCtorParams = GetCtorArguments(parameterizedCtorInfo, node, Context);
                //Fang
                //IL_0000:  ldstr "foo"
                //Context.IL.Append(PushCtorArguments(parameterizedCtorInfo, node));
            }

            ctorInfo = ctorInfo ?? typedef.Methods.FirstOrDefault(md => md.IsConstructor && !md.HasParameters && !md.IsStatic);

            if (null == ctorInfo)
            {
                foreach (var method in typedef.Methods)
                {
                    if (method.IsConstructor && !method.IsStatic)
                    {
                        bool areAllParamsDefault = true;

                        foreach (var param in method.Parameters)
                        {
                            if (!param.HasDefault)
                            {
                                areAllParamsDefault = false;
                                break;
                            }
                        }

                        if (areAllParamsDefault)
                        {
                            if (null == ctorInfo)
                            {
                                ctorInfo = method;
                            }
                            else
                            {
                                throw new XamlParseException($"{typedef.FullName} has more than one constructor which params are all default.", node);
                            }
                        }
                    }
                }

                if (null == ctorInfo && !typedef.IsValueType)
                {
                    throw new XamlParseException($"{typedef.FullName} has no constructor which params are all default.", node);
                }
            }

            if (parameterizedCtorInfo != null && ctorInfo == null)
            {
                //there was a parameterized ctor, we didn't use it
                throw new XamlParseException($"The Property '{missingCtorParameter}' is required to create a '{typedef.FullName}' object.", node);
            }
            var ctorinforef = ctorInfo?.ResolveGenericParameters(typeref, Module);

            var factorymethodinforef = factoryMethodInfo?.ResolveGenericParameters(typeref, Module);
            var implicitOperatorref  = typedef.Methods.FirstOrDefault(md =>
                                                                      md.IsPublic &&
                                                                      md.IsStatic &&
                                                                      md.IsSpecialName &&
                                                                      md.Name == "op_Implicit" && md.Parameters[0].ParameterType.FullName == "System.String");

            if (ctorinforef != null || factorymethodinforef != null || typedef.IsValueType)
            {
                VariableDefinition vardef = new VariableDefinition(typeref);
                Context.Variables[node] = vardef;

                ValueNode vnode = null;
                if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                    vardef.VariableType.IsValueType)
                {
                    Context.Values[node] = vnode.GetBaseValue(Context, typeref);
                }
                else if (node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null &&
                         implicitOperatorref != null)
                {
                    var converterType = vnode.GetConverterType(new ICustomAttributeProvider[] { typeref.ResolveCached() });
                    if (null == converterType)
                    {
                        var realValue = vnode.GetBaseValue(Context, typeref);
                        Context.Values[node] = new EXamlCreateObject(Context, realValue, typeref);
                    }
                    else
                    {
                        var converterValue = new EXamlValueConverterFromString(Context, converterType.Resolve(), vnode.Value as string);
                        Context.Values[node] = new EXamlCreateObject(Context, converterValue, typeref);
                    }
                }
                else if (factorymethodinforef != null)
                {
                    //Fang
                    //Context.IL.Emit(OpCodes.Call, Module.ImportReference(factorymethodinforef));
                    //Context.IL.Emit(OpCodes.Stloc, vardef);
                }
                else if (!typedef.IsValueType)
                {
                    var ctor = Module.ImportReference(ctorinforef);
                    //IL_0001:  newobj instance void class [Tizen.NUI.Xaml.UIComponents]Tizen.NUI.Xaml.UIComponents.Button::'.ctor'()
                    //IL_0006:  stloc.0
                    //Context.IL.Emit(OpCodes.Newobj, ctor);
                    //Context.IL.Emit(OpCodes.Stloc, vardef);
                    if (typeref.FullName == "Tizen.NUI.Xaml.ArrayExtension")
                    {
                        typeref = Module.ImportReference(typeof(ArrayExtension));
                    }

                    var accordingType = this.GetType().Assembly.GetType(typeref.FullName);

                    if (null != accordingType && accordingType != typeof(Binding.Setter) && accordingType != typeof(ResourceDictionary))
                    {
                        Context.Values[node] = new EXamlCreateObject(Context, Activator.CreateInstance(accordingType), typeref);
                    }
                    else if (null != parameterizedCtorParams)
                    {
                        Context.Values[node] = new EXamlCreateObject(Context, null, typeref, parameterizedCtorParams.ToArray());
                    }
                    else
                    {
                        bool canConvertCollectionItem = false;

                        if (!typeref.InheritsFromOrImplements(Context.Module.ImportReference(typeof(List <string>)).Resolve())
                            &&
                            node.CollectionItems.Count == 1 && (vnode = node.CollectionItems.First() as ValueNode) != null)
                        {
                            var valueNode = node.CollectionItems.First() as ValueNode;

                            if (valueNode.CanConvertValue(Context.Module, typeref, (TypeReference)null))
                            {
                                var converterType = valueNode.GetConverterType(new ICustomAttributeProvider[] { typeref.Resolve() });
                                if (null != converterType)
                                {
                                    var converterValue = new EXamlValueConverterFromString(Context, converterType.Resolve(), valueNode.Value as string);
                                    Context.Values[node] = new EXamlCreateObject(Context, converterValue, typeref);
                                }
                                else
                                {
                                    var valueItem = valueNode.GetBaseValue(Context, typeref);
                                    if (null == valueItem)
                                    {
                                        throw new XamlParseException($"Can't convert collection item \"{vnode.Value}\" to object", node);
                                    }

                                    Context.Values[node] = valueItem;
                                }

                                canConvertCollectionItem = true;
                            }
                        }

                        if (false == canConvertCollectionItem)
                        {
                            if (!ctorInfo.HasParameters)
                            {
                                Context.Values[node] = new EXamlCreateObject(Context, null, typeref);
                            }
                            else
                            {
                                object[] @params = new object[ctorInfo.Parameters.Count];

                                for (int i = 0; i < ctorInfo.Parameters.Count; i++)
                                {
                                    var param = ctorInfo.Parameters[i];

                                    if (ctorInfo.Parameters[i].ParameterType.ResolveCached().IsEnum)
                                    {
                                        @params[i] = NodeILExtensions.GetParsedEnum(Context, param.ParameterType, param.Constant.ToString());
                                    }
                                    else
                                    {
                                        @params[i] = param.Constant;
                                    }
                                }

                                Context.Values[node] = new EXamlCreateObject(Context, null, typeref, @params);
                            }
                        }
                    }
                }
                else if (ctorInfo != null && node.Properties.ContainsKey(XmlName.xArguments) &&
                         !node.Properties.ContainsKey(XmlName.xFactoryMethod) && ctorInfo.MatchXArguments(node, typeref, Module, Context))
                {
                    var argumentList = GetCtorXArguments(node, factoryCtorInfo.Parameters.Count, true);
                    Context.Values[node] = new EXamlCreateObject(Context, null, typedef, argumentList.ToArray());
                    return;
                }
                else
                {
                    Context.Values[node] = new EXamlCreateObject(Context, null, typedef, null);
                    return;
                }

                if (typeref.FullName == "Tizen.NUI.Xaml.ArrayExtension")
                {
                    //Fang
                    //var visitor = new SetPropertiesVisitor(Context);
                    //foreach (var cnode in node.Properties.Values.ToList())
                    //    cnode.Accept(visitor, node);
                    //foreach (var cnode in node.CollectionItems)
                    //    cnode.Accept(visitor, node);

                    //markupProvider = new ArrayExtension();

                    //var il = markupProvider.ProvideValue(node, Module, Context, out typeref);

                    //vardef = new VariableDefinition(typeref);
                    //Context.Variables[node] = vardef;
                    //Context.Body.Variables.Add(vardef);

                    //Context.IL.Append(il);
                    //Context.IL.Emit(OpCodes.Stloc, vardef);

                    ////clean the node as it has been fully exhausted
                    //foreach (var prop in node.Properties)
                    //    if (!node.SkipProperties.Contains(prop.Key))
                    //        node.SkipProperties.Add(prop.Key);
                    //node.CollectionItems.Clear();

                    return;
                }
            }
        }