public void Visit(ElementNode node, INode parentNode) { var ns = parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) ? new NameScope() : scopes[parentNode]; node.Namescope = ns; scopes[node] = ns; }
public bool IsResourceDictionary(ElementNode node) => false;
public void Visit(ElementNode node, INode parentNode) { if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) return; var value = Values[node]; var parentElement = parentNode as IElementNode; var markupExtension = value as IMarkupExtension; var valueProvider = value as IValueProvider; if (markupExtension != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = markupExtension.ProvideValue(serviceProvider); } if (valueProvider != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = valueProvider.ProvideValue(serviceProvider); } XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName)) { if (Skips.Contains(propertyName)) return; if (parentElement.SkipProperties.Contains(propertyName)) return; var source = Values[parentNode]; if (propertyName == XmlName._CreateContent && source is ElementTemplate) SetTemplate(source as ElementTemplate, node); else SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { // Collection element, implicit content, or implicit collection element. string contentProperty; if (typeof (IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types[parentElement].GetTypeInfo())) { var source = Values[parentNode]; if (!(typeof (ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]))) { var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); addMethod.Invoke(source, new[] { value }); } } else if ((contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (Skips.Contains(name)) return; if (parentElement.SkipProperties.Contains(propertyName)) return; var source = Values[parentNode]; SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { var parentList = (ListNode)parentNode; var source = Values[parentNode.Parent]; if (Skips.Contains(parentList.XmlName)) return; var elementType = source.GetType(); var localname = parentList.XmlName.LocalName; GetRealNameAndType(ref elementType, parentList.XmlName.NamespaceURI, ref localname, Context, node); PropertyInfo propertyInfo = null; try { propertyInfo = elementType.GetRuntimeProperty(localname); } catch (AmbiguousMatchException) { // Get most derived instance of property foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localname)) { if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) propertyInfo = property; } } if (propertyInfo == null) throw new XamlParseException(string.Format("Property {0} not found", localname), node); MethodInfo getter; if (!propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) throw new XamlParseException(string.Format("Property {0} does not have an accessible getter", localname), node); IEnumerable collection; if ((collection = getter.Invoke(source, new object[] { }) as IEnumerable) == null) throw new XamlParseException(string.Format("Property {0} is null or is not IEnumerable", localname), node); MethodInfo addMethod; if ( (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) == null) throw new XamlParseException(string.Format("Value of {0} does not have a Add() method", localname), node); addMethod.Invoke(collection, new[] { Values[node] }); } }
public void Visit(ElementNode node, INode parentNode) => _scopes[node] = node.Namescope = (parentNode == null || IsDataTemplate(node, parentNode) || IsStyle(node, parentNode) || IsVisualStateGroupList(node)) ? new NameScope() : _scopes[parentNode];
public void Visit(ElementNode node, INode parentNode) { }
static void SetDataTemplate(IElementNode parentNode, ElementNode node, ILContext parentContext, IXmlLineInfo xmlLineInfo) { var parentVar = parentContext.Variables[parentNode]; //Push the DataTemplate to the stack, for setting the template parentContext.IL.Emit(OpCodes.Ldloc, parentVar); //Create nested class // .class nested private auto ansi sealed beforefieldinit '<Main>c__AnonStorey0' // extends [mscorlib]System.Object var module = parentContext.Body.Method.Module; var anonType = new TypeDefinition( null, "<" + parentContext.Body.Method.Name + ">_anonXamlCDataTemplate_" + dtcount++, TypeAttributes.BeforeFieldInit | TypeAttributes.Sealed | TypeAttributes.NestedPrivate) { BaseType = module.TypeSystem.Object }; parentContext.Body.Method.DeclaringType.NestedTypes.Add(anonType); var ctor = anonType.AddDefaultConstructor(); var loadTemplate = new MethodDefinition("LoadDataTemplate", MethodAttributes.Assembly | MethodAttributes.HideBySig, module.TypeSystem.Object); anonType.Methods.Add(loadTemplate); var parentValues = new FieldDefinition("parentValues", FieldAttributes.Assembly, module.Import(typeof (object[]))); anonType.Fields.Add(parentValues); TypeReference rootType = null; var vdefRoot = parentContext.Root as VariableDefinition; if (vdefRoot != null) rootType = vdefRoot.VariableType; var fdefRoot = parentContext.Root as FieldDefinition; if (fdefRoot != null) rootType = fdefRoot.FieldType; var root = new FieldDefinition("root", FieldAttributes.Assembly, rootType); anonType.Fields.Add(root); //Fill the loadTemplate Body var templateIl = loadTemplate.Body.GetILProcessor(); templateIl.Emit(OpCodes.Nop); var templateContext = new ILContext(templateIl, loadTemplate.Body, parentValues) { Root = root }; node.Accept(new CreateObjectVisitor(templateContext), null); node.Accept(new SetNamescopesAndRegisterNamesVisitor(templateContext), null); node.Accept(new SetFieldVisitor(templateContext), null); node.Accept(new SetResourcesVisitor(templateContext), null); node.Accept(new SetPropertiesVisitor(templateContext), null); templateIl.Emit(OpCodes.Ldloc, templateContext.Variables[node]); templateIl.Emit(OpCodes.Ret); //Instanciate nested class var parentIl = parentContext.IL; parentIl.Emit(OpCodes.Newobj, ctor); //Copy required local vars parentIl.Emit(OpCodes.Dup); //Duplicate the nestedclass instance parentIl.Append(node.PushParentObjectsArray(parentContext)); parentIl.Emit(OpCodes.Stfld, parentValues); parentIl.Emit(OpCodes.Dup); //Duplicate the nestedclass instance if (parentContext.Root is VariableDefinition) parentIl.Emit(OpCodes.Ldloc, parentContext.Root as VariableDefinition); else if (parentContext.Root is FieldDefinition) { parentIl.Emit(OpCodes.Ldarg_0); parentIl.Emit(OpCodes.Ldfld, parentContext.Root as FieldDefinition); } else throw new InvalidProgramException(); parentIl.Emit(OpCodes.Stfld, root); //SetDataTemplate parentIl.Emit(OpCodes.Ldftn, loadTemplate); var funcCtor = module.Import(typeof (Func<>)) .MakeGenericInstanceType(module.TypeSystem.Object) .Resolve() .Methods.First(md => md.IsConstructor && md.Parameters.Count == 2) .MakeGeneric(module.TypeSystem.Object); parentIl.Emit(OpCodes.Newobj, module.Import(funcCtor)); var propertySetter = module.Import(typeof (IDataTemplate)).Resolve().Properties.First(p => p.Name == "LoadTemplate").SetMethod; parentContext.IL.Emit(OpCodes.Callvirt, module.Import(propertySetter)); }
public void Visit(ElementNode node, INode parentNode) { }
public void Visit(ElementNode node, INode parentNode) { object value = null; XamlParseException xpe; var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, out xpe); if (xpe != null) { throw xpe; } Context.Types[node] = type; string ctorargname; if (IsXaml2009LanguagePrimitive(node)) { value = CreateLanguagePrimitive(type, node); } else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) { value = CreateFromFactory(type, node); } else if ( type.GetTypeInfo() .DeclaredConstructors.Any( ci => ci.IsPublic && ci.GetParameters().Length != 0 && ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof(ParameterAttribute)))) && ValidateCtorArguments(type, node, out ctorargname)) { value = CreateFromParameterizedConstructor(type, node); } else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && !ValidateCtorArguments(type, node, out ctorargname)) { throw new XamlParseException($"The Property {ctorargname} is required to create a {type.FullName} object.", node); } else { //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 try { if (type == typeof(DataTemplate)) { value = new DataTemplate(); } if (type == typeof(ControlTemplate)) { value = new ControlTemplate(); } if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) { var serviceProvider = new XamlServiceProvider(node, Context); var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), serviceProvider); if (converted != null && converted.GetType() == type) { value = converted; } } if (value == null) { value = Activator.CreateInstance(type); } } catch (TargetInvocationException e) { if (e.InnerException is XamlParseException || e.InnerException is XmlException) { throw e.InnerException; } throw; } } Values[node] = value; var markup = value as IMarkupExtension; if (markup != null && (value is TypeExtension || value is StaticExtension || value is ArrayExtension)) { var serviceProvider = new XamlServiceProvider(node, Context); var visitor = new ApplyPropertiesVisitor(Context); foreach (var cnode in node.Properties.Values.ToList()) { cnode.Accept(visitor, node); } foreach (var cnode in node.CollectionItems) { cnode.Accept(visitor, node); } value = markup.ProvideValue(serviceProvider); INode xKey; if (!node.Properties.TryGetValue(XmlName.xKey, out xKey)) { xKey = null; } node.Properties.Clear(); node.CollectionItems.Clear(); if (xKey != null) { node.Properties.Add(XmlName.xKey, xKey); } Values[node] = value; } if (value is BindableObject) { NameScope.SetNameScope(value as BindableObject, node.Namescope); } }
static bool IsVisualStateGroupList(ElementNode node) { return(node != null && node.XmlType.Name == "VisualStateGroup" && node.Parent is IListNode); }
static bool IsVisualStateGroupList(ElementNode node) => node?.XmlType.Name == "VisualStateGroup" && node?.Parent is IListNode;
static INode ReadNode(XmlReader reader, bool nested = false) { var skipFirstRead = nested; Debug.Assert(reader.NodeType == XmlNodeType.Element); var name = reader.Name; List<INode> nodes = new List<INode>(); INode node = null; while (skipFirstRead || reader.Read()) { skipFirstRead = false; switch (reader.NodeType) { case XmlNodeType.EndElement: Debug.Assert(reader.Name == name); if (nodes.Count == 0) //Empty element return null; if (nodes.Count == 1) return nodes[0]; return new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition); case XmlNodeType.Element: var isEmpty = reader.IsEmptyElement && reader.Name == name; var elementName = reader.Name; var elementNsUri = reader.NamespaceURI; var elementXmlInfo = (IXmlLineInfo)reader; var attributes = ParseXamlAttributes(reader); IList<XmlType> typeArguments = null; if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)) { typeArguments = ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList<XmlType>; } node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri, reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition); ((IElementNode)node).Properties.AddRange(attributes); ParseXamlElementFor((IElementNode)node, reader); nodes.Add(node); if (isEmpty || nested) return node; break; case XmlNodeType.Text: node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition); nodes.Add(node); break; case XmlNodeType.Whitespace: break; default: Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); break; } } throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader); }
public bool IsResourceDictionary(ElementNode node) => Context.Types.TryGetValue(node, out var type) && typeof(ResourceDictionary).IsAssignableFrom(type);
public void Visit(ElementNode node, INode parentNode) { XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent) { var s0 = Values[parentNode]; if (s0 is ElementTemplate) { SetTemplate(s0 as ElementTemplate, node); return; } } var parentElement = parentNode as IElementNode; propertyName = XmlName.Empty; //Simplify ListNodes with single elements var pList = parentNode as ListNode; if (pList != null && pList.CollectionItems.Count == 1) { propertyName = pList.XmlName; parentNode = parentNode.Parent; parentElement = parentNode as IElementNode; } var value = Values[node]; if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) { if (Skips.Contains(propertyName)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } var source = Values[parentNode]; ProvideValue(ref value, node, source, propertyName); SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { var source = Values[parentNode]; ProvideValue(ref value, node, source, XmlName.Empty); string contentProperty; // Implicit Style Resource in a ResourceDictionary if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && value is Style && !node.Properties.ContainsKey(XmlName.xKey)) { ((ResourceDictionary)source).Add(value as Style); } // Resource without a x:Key in a ResourceDictionary else if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && !node.Properties.ContainsKey(XmlName.xKey)) { throw new XamlParseException("resources in ResourceDictionary require a x:Key attribute", node); } // Resource in a ResourceDictionary else if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && node.Properties.ContainsKey(XmlName.xKey)) { ((ResourceDictionary)source).Add((string)(((ValueNode)node.Properties[XmlName.xKey]).Value), value); } // Collection element, implicit content, or implicit collection element. else if (typeof(IEnumerable).IsAssignableFrom(Context.Types[parentElement]) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) { if (!(typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]))) { var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); addMethod.Invoke(source, new[] { value }); } } else if ((contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (Skips.Contains(name)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); } else { throw new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { var source = Values[parentNode.Parent]; ProvideValue(ref value, node, source, XmlName.Empty); var parentList = (ListNode)parentNode; if (Skips.Contains(parentList.XmlName)) { return; } var elementType = source.GetType(); var localname = parentList.XmlName.LocalName; GetRealNameAndType(ref elementType, parentList.XmlName.NamespaceURI, ref localname, Context, node); PropertyInfo propertyInfo = null; try { propertyInfo = elementType.GetRuntimeProperty(localname); } catch (AmbiguousMatchException) { // Get most derived instance of property foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localname)) { if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) { propertyInfo = property; } } } if (propertyInfo == null) { throw new XamlParseException(Format("Property {0} not found", localname), node); } MethodInfo getter; if (!propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) { throw new XamlParseException(Format("Property {0} does not have an accessible getter", localname), node); } IEnumerable collection; if ((collection = getter.Invoke(source, new object[] { }) as IEnumerable) == null) { throw new XamlParseException(Format("Property {0} is null or is not IEnumerable", localname), node); } MethodInfo addMethod; if ( (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) == null) { throw new XamlParseException(Format("Value of {0} does not have a Add() method", localname), node); } addMethod.Invoke(collection, new[] { Values[node] }); } }
public void Visit(ElementNode node, INode parentNode) { action(node, parentNode); }
public void Visit(ElementNode node, INode parentNode) { if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) { return; } var value = Values[node]; var parentElement = parentNode as IElementNode; var markupExtension = value as IMarkupExtension; var valueProvider = value as IValueProvider; if (markupExtension != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = markupExtension.ProvideValue(serviceProvider); } if (valueProvider != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = valueProvider.ProvideValue(serviceProvider); } XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName)) { if (Skips.Contains(propertyName)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } var source = Values[parentNode]; if (propertyName == XmlName._CreateContent && source is ElementTemplate) { SetTemplate(source as ElementTemplate, node); } else { SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { // Collection element, implicit content, or implicit collection element. string contentProperty; if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(Context.Types[parentElement].GetTypeInfo())) { var source = Values[parentNode]; if (!(typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]))) { var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); addMethod.Invoke(source, new[] { value }); } } else if ((contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (Skips.Contains(name)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } var source = Values[parentNode]; SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { var parentList = (ListNode)parentNode; var source = Values[parentNode.Parent]; if (Skips.Contains(parentList.XmlName)) { return; } var elementType = source.GetType(); var localname = parentList.XmlName.LocalName; GetRealNameAndType(ref elementType, parentList.XmlName.NamespaceURI, ref localname, Context, node); PropertyInfo propertyInfo = null; try { propertyInfo = elementType.GetRuntimeProperty(localname); } catch (AmbiguousMatchException) { // Get most derived instance of property foreach (var property in elementType.GetRuntimeProperties().Where(prop => prop.Name == localname)) { if (propertyInfo == null || propertyInfo.DeclaringType.IsAssignableFrom(property.DeclaringType)) { propertyInfo = property; } } } if (propertyInfo == null) { throw new XamlParseException(string.Format("Property {0} not found", localname), node); } MethodInfo getter; if (!propertyInfo.CanRead || (getter = propertyInfo.GetMethod) == null) { throw new XamlParseException(string.Format("Property {0} does not have an accessible getter", localname), node); } IEnumerable collection; if ((collection = getter.Invoke(source, new object[] { }) as IEnumerable) == null) { throw new XamlParseException(string.Format("Property {0} is null or is not IEnumerable", localname), node); } MethodInfo addMethod; if ( (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) == null) { throw new XamlParseException(string.Format("Value of {0} does not have a Add() method", localname), node); } addMethod.Invoke(collection, new[] { Values[node] }); } }
static INode ReadNode(XmlReader reader, bool nested = false) { var skipFirstRead = nested; Debug.Assert(reader.NodeType == XmlNodeType.Element); var name = reader.Name; List <INode> nodes = new List <INode>(); INode node = null; while (skipFirstRead || reader.Read()) { skipFirstRead = false; switch (reader.NodeType) { case XmlNodeType.EndElement: Debug.Assert(reader.Name == name); if (nodes.Count == 0) //Empty element { return(null); } if (nodes.Count == 1) { return(nodes[0]); } return(new ListNode(nodes, (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition)); case XmlNodeType.Element: var isEmpty = reader.IsEmptyElement && reader.Name == name; var elementName = reader.Name; var elementNsUri = reader.NamespaceURI; var elementXmlInfo = (IXmlLineInfo)reader; IList <KeyValuePair <string, string> > xmlns; var attributes = ParseXamlAttributes(reader, out xmlns); var prefixes = PrefixesToIgnore(xmlns); IList <XmlType> typeArguments = null; if (attributes.Any(kvp => kvp.Key == XmlName.xTypeArguments)) { typeArguments = ((ValueNode)attributes.First(kvp => kvp.Key == XmlName.xTypeArguments).Value).Value as IList <XmlType>; } node = new ElementNode(new XmlType(elementNsUri, elementName, typeArguments), elementNsUri, reader as IXmlNamespaceResolver, elementXmlInfo.LineNumber, elementXmlInfo.LinePosition); ((IElementNode)node).Properties.AddRange(attributes); (node.IgnorablePrefixes ?? (node.IgnorablePrefixes = new List <string>())).AddRange(prefixes); ParseXamlElementFor((IElementNode)node, reader); nodes.Add(node); if (isEmpty || nested) { return(node); } break; case XmlNodeType.Text: node = new ValueNode(reader.Value.Trim(), (IXmlNamespaceResolver)reader, ((IXmlLineInfo)reader).LineNumber, ((IXmlLineInfo)reader).LinePosition); nodes.Add(node); break; case XmlNodeType.Whitespace: break; default: Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value); break; } } throw new XamlParseException("Closing PropertyElement expected", (IXmlLineInfo)reader); }
public void Visit(ElementNode node, INode parentNode) { XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent) { var s0 = Values[parentNode]; if (s0 is ElementTemplate) { SetTemplate(s0 as ElementTemplate, node); return; } } var parentElement = parentNode as IElementNode; propertyName = XmlName.Empty; //Simplify ListNodes with single elements var pList = parentNode as ListNode; if (pList != null && pList.CollectionItems.Count == 1) { propertyName = pList.XmlName; parentNode = parentNode.Parent; parentElement = parentNode as IElementNode; } var value = Values[node]; if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) { if (Skips.Contains(propertyName)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } var source = Values[parentNode]; ProvideValue(ref value, node, source, propertyName); SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { var source = Values[parentNode]; ProvideValue(ref value, node, source, XmlName.Empty); string contentProperty; Exception xpe = null; var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; //ResourceDictionary if (xpe == null && TryAddToResourceDictionary(source as ResourceDictionary, value, xKey, node, out xpe)) { return; } // Collection element, implicit content, or implicit collection element. if (xpe == null && typeof(IEnumerable).IsAssignableFrom(Context.Types[parentElement]) && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) { var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1); addMethod.Invoke(source, new[] { value }); return; } if (xpe == null && (contentProperty = GetContentPropertyName(Context.Types[parentElement].GetTypeInfo())) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (Skips.Contains(name)) { return; } if (parentElement.SkipProperties.Contains(propertyName)) { return; } SetPropertyValue(source, name, value, Context.RootElement, node, Context, node); return; } xpe = xpe ?? new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xpe); } else { throw xpe; } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { var source = Values[parentNode.Parent]; ProvideValue(ref value, node, source, XmlName.Empty); var parentList = (ListNode)parentNode; if (Skips.Contains(parentList.XmlName)) { return; } Exception xpe = null; var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null; object _; var collection = GetPropertyValue(source, parentList.XmlName, Context, parentList, out _) as IEnumerable; if (collection == null) { xpe = new XamlParseException($"Property {parentList.XmlName.LocalName} is null or is not IEnumerable", node); } if (xpe == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, node, out xpe)) { return; } MethodInfo addMethod; if (xpe == null && (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) != null) { addMethod.Invoke(collection, new[] { Values[node] }); return; } xpe = xpe ?? new XamlParseException($"Value of {parentList.XmlName.LocalName} does not have a Add() method", node); if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xpe); } else { throw xpe; } } }
public void Visit(ElementNode node, INode parentNode) { object value = null; if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) return; XamlParseException xpe; var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, out xpe); if (xpe != null) throw xpe; Context.Types[node] = type; string ctorargname; if (IsXaml2009LanguagePrimitive(node)) value = CreateLanguagePrimitive(type, node); else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) value = CreateFromFactory(type, node); else if ( type.GetTypeInfo() .DeclaredConstructors.Any( ci => ci.IsPublic && ci.GetParameters().Length != 0 && ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof (ParameterAttribute)))) && ValidateCtorArguments(type, node, out ctorargname)) value = CreateFromParameterizedConstructor(type, node); else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && !ValidateCtorArguments(type, node, out ctorargname)) { throw new XamlParseException( String.Format("The Property {0} is required to create a {1} object.", ctorargname, type.FullName), node); } else { //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 try { if (type == typeof (DataTemplate)) value = new DataTemplate(); if (type == typeof (ControlTemplate)) value = new ControlTemplate(); if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) { var serviceProvider = new XamlServiceProvider(node, Context); var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), serviceProvider); if (converted != null && converted.GetType() == type) value = converted; } if (value == null) value = Activator.CreateInstance(type); } catch (TargetInvocationException e) { if (e.InnerException is XamlParseException || e.InnerException is XmlException) throw e.InnerException; throw; } } Values[node] = value; var typeExtension = value as TypeExtension; if (typeExtension != null) { var serviceProvider = new XamlServiceProvider(node, Context); var visitor = new ApplyPropertiesVisitor(Context); foreach (var cnode in node.Properties.Values.ToList()) cnode.Accept(visitor, node); foreach (var cnode in node.CollectionItems) cnode.Accept(visitor, node); value = typeExtension.ProvideValue(serviceProvider); node.Properties.Clear(); node.CollectionItems.Clear(); Values[node] = value; } if (value is BindableObject) NameScope.SetNameScope(value as BindableObject, node.Namescope); }
public void Visit(ElementNode node, INode parentNode) { if (node.SkipPrefix(node.NamespaceResolver.LookupPrefix(node.NamespaceURI))) { return; } var value = Values[node]; var parentElement = parentNode as IElementNode; var markupExtension = value as IMarkupExtension; var valueProvider = value as IValueProvider; //Set Resources in ResourcesDictionaries if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { if (typeof(IEnumerable).IsAssignableFrom(Context.Types[parentElement])) { var source = Values[parentNode]; if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && value is Style && !node.Properties.ContainsKey(XmlName.xKey)) { node.Accept(new ApplyPropertiesVisitor(Context), parentNode); if (markupExtension != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = markupExtension.ProvideValue(serviceProvider); } if (valueProvider != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = valueProvider.ProvideValue(serviceProvider); } ((ResourceDictionary)source).Add(value as Style); } else if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && !node.Properties.ContainsKey(XmlName.xKey)) { throw new XamlParseException("resources in ResourceDictionary require a x:Key attribute", node); } else if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[parentElement]) && node.Properties.ContainsKey(XmlName.xKey)) { node.Accept(new ApplyPropertiesVisitor(Context), parentNode); if (markupExtension != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = markupExtension.ProvideValue(serviceProvider); } if (valueProvider != null) { var serviceProvider = new XamlServiceProvider(node, Context); value = valueProvider.ProvideValue(serviceProvider); } ((ResourceDictionary)source).Add((string)(((ValueNode)node.Properties[XmlName.xKey]).Value), value); } } } //Set RD to VE XmlName propertyName; if (ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) { if ((propertyName.LocalName == "Resources" || propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary) { var source = Values[parentNode]; ApplyPropertiesVisitor.SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } } }
public static IEnumerable<Instruction> ProvideValue(VariableDefinitionReference vardefref, ILContext context, ModuleDefinition module, ElementNode node) { GenericInstanceType markupExtension; IList<TypeReference> genericArguments; if (vardefref.VariableDefinition.VariableType.FullName == "Xamarin.Forms.Xaml.ArrayExtension" && vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Xamarin.Forms.Xaml.IMarkupExtension`1", out markupExtension, out genericArguments)) { var markExt = markupExtension.Resolve(); var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); var provideValue = module.Import(provideValueInfo); provideValue = module.Import(provideValue.MakeGeneric(markupExtension.GenericArguments.Select(tr => module.Import(tr)).ToArray())); var typeNode = node.Properties[new XmlName("", "Type")]; TypeReference arrayTypeRef; if (context.TypeExtensions.TryGetValue(typeNode, out arrayTypeRef)) vardefref.VariableDefinition = new VariableDefinition(module.Import(arrayTypeRef.MakeArrayType())); else vardefref.VariableDefinition = new VariableDefinition(module.Import(genericArguments.First())); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); foreach (var instruction in node.PushServiceProvider(context)) yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); if (arrayTypeRef != null) yield return Instruction.Create(OpCodes.Castclass, module.Import(arrayTypeRef.MakeArrayType())); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } else if (vardefref.VariableDefinition.VariableType.ImplementsGenericInterface("Xamarin.Forms.Xaml.IMarkupExtension`1", out markupExtension, out genericArguments)) { var markExt = markupExtension.Resolve(); var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); var provideValue = module.Import(provideValueInfo); provideValue = module.Import(provideValue.MakeGeneric(markupExtension.GenericArguments.Select(tr => module.Import(tr)).ToArray())); vardefref.VariableDefinition = new VariableDefinition(module.Import(genericArguments.First())); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); foreach (var instruction in node.PushServiceProvider(context)) yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } else if (context.Variables[node].VariableType.ImplementsInterface(module.Import(typeof (IMarkupExtension)))) { var markExt = module.Import(typeof (IMarkupExtension)).Resolve(); var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); var provideValue = module.Import(provideValueInfo); vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); foreach (var instruction in node.PushServiceProvider(context)) yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } else if (context.Variables[node].VariableType.ImplementsInterface(module.Import(typeof (IValueProvider)))) { var markExt = module.Import(typeof (IValueProvider)).Resolve(); var provideValueInfo = markExt.Methods.First(md => md.Name == "ProvideValue"); var provideValue = module.Import(provideValueInfo); vardefref.VariableDefinition = new VariableDefinition(module.TypeSystem.Object); yield return Instruction.Create(OpCodes.Ldloc, context.Variables[node]); foreach (var instruction in node.PushServiceProvider(context)) yield return instruction; yield return Instruction.Create(OpCodes.Callvirt, provideValue); yield return Instruction.Create(OpCodes.Stloc, vardefref.VariableDefinition); } }
public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
public void Visit(ElementNode node, INode parentNode) { if (node.SkipPrefix((node.NamespaceResolver ?? parentNode.NamespaceResolver)?.LookupPrefix(node.NamespaceURI))) return; //if this node is an IMarkupExtension, invoke ProvideValue() and replace the variable var vardef = Context.Variables[node]; var vardefref = new VariableDefinitionReference(vardef); Context.IL.Append(ProvideValue(vardefref, Context, Module, node)); if (vardef != vardefref.VariableDefinition) { vardef = vardefref.VariableDefinition; Context.Body.Variables.Add(vardef); Context.Variables[node] = vardef; } XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName)) { if (skips.Contains(propertyName)) return; if (propertyName == XmlName._CreateContent) SetDataTemplate((IElementNode)parentNode, node, Context, node); else SetPropertyValue(Context.Variables[(IElementNode)parentNode], propertyName, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { // Collection element, implicit content, or implicit collection element. string contentProperty; var parentVar = Context.Variables[(IElementNode)parentNode]; if (parentVar.VariableType.ImplementsInterface(Module.Import(typeof (IEnumerable)))) { var elementType = parentVar.VariableType; if (elementType.FullName != "Xamarin.Forms.ResourceDictionary" && elementType.Resolve().BaseType.FullName != "Xamarin.Forms.ResourceDictionary") { var adderTuple = elementType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).First(); var adderRef = Module.Import(adderTuple.Item1); adderRef = Module.Import(adderRef.ResolveGenericParameters(adderTuple.Item2, Module)); Context.IL.Emit(OpCodes.Ldloc, parentVar); Context.IL.Emit(OpCodes.Ldloc, vardef); Context.IL.Emit(OpCodes.Callvirt, adderRef); if (adderRef.ReturnType.FullName != "System.Void") Context.IL.Emit(OpCodes.Pop); } } else if ((contentProperty = GetContentProperty(parentVar.VariableType)) != null) { var name = new XmlName(node.NamespaceURI, contentProperty); if (skips.Contains(name)) return; SetPropertyValue(Context.Variables[(IElementNode)parentNode], name, node, Context, node); } } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { // IL_000d: ldloc.2 // IL_000e: callvirt instance class [mscorlib]System.Collections.Generic.IList`1<!0> class [Xamarin.Forms.Core]Xamarin.Forms.Layout`1<class [Xamarin.Forms.Core]Xamarin.Forms.View>::get_Children() // IL_0013: ldloc.0 // IL_0014: callvirt instance void class [mscorlib]System.Collections.Generic.ICollection`1<class [Xamarin.Forms.Core]Xamarin.Forms.View>::Add(!0) var parentList = (ListNode)parentNode; var parent = Context.Variables[((IElementNode)parentNode.Parent)]; if (skips.Contains(parentList.XmlName)) return; var elementType = parent.VariableType; var localname = parentList.XmlName.LocalName; GetNameAndTypeRef(ref elementType, parentList.XmlName.NamespaceURI, ref localname, Context, node); TypeReference propertyDeclaringType; var property = elementType.GetProperty(pd => pd.Name == localname, out propertyDeclaringType); MethodDefinition propertyGetter; if (property != null && (propertyGetter = property.GetMethod) != null && propertyGetter.IsPublic) { var propertyGetterRef = Module.Import(propertyGetter); propertyGetterRef = Module.Import(propertyGetterRef.ResolveGenericParameters(propertyDeclaringType, Module)); var propertyType = propertyGetterRef.ReturnType.ResolveGenericParameters(propertyDeclaringType); var adderTuple = propertyType.GetMethods(md => md.Name == "Add" && md.Parameters.Count == 1, Module).First(); var adderRef = Module.Import(adderTuple.Item1); adderRef = Module.Import(adderRef.ResolveGenericParameters(adderTuple.Item2, Module)); Context.IL.Emit(OpCodes.Ldloc, parent); Context.IL.Emit(OpCodes.Callvirt, propertyGetterRef); Context.IL.Emit(OpCodes.Ldloc, vardef); Context.IL.Emit(OpCodes.Callvirt, adderRef); if (adderRef.ReturnType.FullName != "System.Void") Context.IL.Emit(OpCodes.Pop); } } }
public void Visit(ElementNode node, INode parentNode) { object value = null; var type = XamlParser.GetElementType(node.XmlType, node, Context.RootElement?.GetType().GetTypeInfo().Assembly, out XamlParseException xpe); if (xpe != null) { if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xpe); return; } throw xpe; } Context.Types[node] = type; if (IsXaml2009LanguagePrimitive(node)) { value = CreateLanguagePrimitive(type, node); } else if (node.Properties.ContainsKey(XmlName.xArguments) || node.Properties.ContainsKey(XmlName.xFactoryMethod)) { value = CreateFromFactory(type, node); } else if ( type.GetTypeInfo() .DeclaredConstructors.Any( ci => ci.IsPublic && ci.GetParameters().Length != 0 && ci.GetParameters().All(pi => pi.CustomAttributes.Any(attr => attr.AttributeType == typeof(ParameterAttribute)))) && ValidateCtorArguments(type, node, out string ctorargname)) { value = CreateFromParameterizedConstructor(type, node); } else if (!type.GetTypeInfo().DeclaredConstructors.Any(ci => ci.IsPublic && ci.GetParameters().Length == 0) && !ValidateCtorArguments(type, node, out ctorargname)) { throw new XamlParseException($"The Property {ctorargname} is required to create a {type.FullName} object.", node); } else { //this is a trick as the DataTemplate parameterless ctor is internal, and we can't CreateInstance(..., false) on WP7 try { if (type == typeof(DataTemplate)) { value = new DataTemplate(); } if (type == typeof(ControlTemplate)) { value = new ControlTemplate(); } if (value == null && node.CollectionItems.Any() && node.CollectionItems.First() is ValueNode) { var serviceProvider = new XamlServiceProvider(node, Context); var converted = ((ValueNode)node.CollectionItems.First()).Value.ConvertTo(type, () => type.GetTypeInfo(), serviceProvider, out Exception exception); if (exception != null) { if (Context.ExceptionHandler != null) { Context.ExceptionHandler(exception); return; } throw exception; } if (converted != null && converted.GetType() == type) { value = converted; } } if (value == null) { try { value = Activator.CreateInstance(type); } catch (Exception e) when(e is TargetInvocationException || e is MemberAccessException) { value = XamlLoader.InstantiationFailedCallback?.Invoke(new XamlLoader.CallbackTypeInfo { XmlNamespace = node.XmlType.NamespaceUri, XmlTypeName = node.XmlType.Name }, type, e) ?? throw e; } } } catch (TargetInvocationException e) when(e.InnerException is XamlParseException || e.InnerException is XmlException) { throw e.InnerException; } catch (MissingMemberException mme) { throw new XamlParseException(mme.Message, node, mme); } } Values[node] = value; if (value is IMarkupExtension markup && (value is TypeExtension || value is StaticExtension || value is ArrayExtension)) { var serviceProvider = new XamlServiceProvider(node, Context); var visitor = new ApplyPropertiesVisitor(Context); foreach (var cnode in node.Properties.Values.ToList()) { cnode.Accept(visitor, node); } foreach (var cnode in node.CollectionItems) { cnode.Accept(visitor, node); } try { value = markup.ProvideValue(serviceProvider); } catch (Exception e) { var xamlpe = e as XamlParseException ?? new XamlParseException("Markup extension failed", serviceProvider, e); if (Context.ExceptionHandler != null) { Context.ExceptionHandler(xamlpe); } else { throw xamlpe; } } if (!node.Properties.TryGetValue(XmlName.xKey, out INode xKey)) { xKey = null; } node.Properties.Clear(); node.CollectionItems.Clear(); if (xKey != null) { node.Properties.Add(XmlName.xKey, xKey); } Values[node] = value; } if (value is BindableObject bindableValue && node.NameScopeRef != (parentNode as IElementNode)?.NameScopeRef) { NameScope.SetNameScope(bindableValue, node.NameScopeRef.NameScope); } if (XamlLoader.ValueCreatedCallback != null) { var name = node.XmlType.Name; if (name.Contains(":")) { name = name.Substring(name.LastIndexOf(':') + 1); } XamlLoader.ValueCreatedCallback(new XamlLoader.CallbackTypeInfo { XmlNamespace = node.XmlType.NamespaceUri, XmlTypeName = name }, value); } var assemblyName = (Context.RootAssembly ?? Context.RootElement?.GetType().GetTypeInfo().Assembly)?.GetName().Name; if (assemblyName != null && value != null && !value.GetType().GetTypeInfo().IsValueType&& XamlFilePathAttribute.GetFilePathForObject(Context.RootElement) is string path) { Diagnostics.VisualDiagnostics.RegisterSourceInfo(value, new Uri($"{path};assembly={assemblyName}", UriKind.Relative), ((IXmlLineInfo)node).LineNumber, ((IXmlLineInfo)node).LinePosition); } }
public void Visit(ElementNode node, INode parentNode) { action(node, parentNode); }
public void Visit(ElementNode node, INode parentNode) { //Set Resources in ResourcesDictionaries if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { // Collection element, implicit content, or implicit collection element. CustomAttribute cpAttr; var parentVar = Context.Variables[(IElementNode)parentNode]; if (parentVar.VariableType.ImplementsInterface(Module.Import(typeof (IEnumerable)))) { if ((parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary" || parentVar.VariableType.Resolve().BaseType.FullName == "Xamarin.Forms.ResourceDictionary") && !node.Properties.ContainsKey(XmlName.xKey)) { node.Accept(new SetPropertiesVisitor(Context), parentNode); if (node.XmlType.Name != "Style") throw new XamlParseException("resources in ResourceDictionary require a x:Key attribute", node); //if this node is an IMarkupExtension, invoke ProvideValue() and replace the variable var vardef = Context.Variables[node]; var vardefref = new VariableDefinitionReference(vardef); Context.IL.Append(SetPropertiesVisitor.ProvideValue(vardefref, Context, Module, node)); if (vardef != vardefref.VariableDefinition) { vardef = vardefref.VariableDefinition; Context.Body.Variables.Add(vardef); Context.Variables[node] = vardef; } Context.IL.Emit(OpCodes.Ldloc, parentVar); Context.IL.Emit(OpCodes.Ldloc, Context.Variables[node]); Context.IL.Emit(OpCodes.Callvirt, Module.Import( Module.Import(typeof (ResourceDictionary)) .Resolve() .Methods.Single(md => md.Name == "Add" && md.Parameters.Count == 1))); } else if ((parentVar.VariableType.FullName == "Xamarin.Forms.ResourceDictionary" || parentVar.VariableType.Resolve().BaseType.FullName == "Xamarin.Forms.ResourceDictionary") && node.Properties.ContainsKey(XmlName.xKey)) { node.Accept(new SetPropertiesVisitor(Context), parentNode); //if this node is an IMarkupExtension, invoke ProvideValue() and replace the variable var vardef = Context.Variables[node]; var vardefref = new VariableDefinitionReference(vardef); Context.IL.Append(SetPropertiesVisitor.ProvideValue(vardefref, Context, Module, node)); if (vardef != vardefref.VariableDefinition) { vardef = vardefref.VariableDefinition; Context.Body.Variables.Add(vardef); Context.Variables[node] = vardef; } // IL_0013: ldloc.0 // IL_0014: ldstr "key" // IL_0019: ldstr "foo" // IL_001e: callvirt instance void class [Xamarin.Forms.Core]Xamarin.Forms.ResourceDictionary::Add(string, object) Context.IL.Emit(OpCodes.Ldloc, parentVar); Context.IL.Emit(OpCodes.Ldstr, (node.Properties[XmlName.xKey] as ValueNode).Value as string); var varDef = Context.Variables[node]; Context.IL.Emit(OpCodes.Ldloc, varDef); if (varDef.VariableType.IsValueType) Context.IL.Emit(OpCodes.Box, Module.Import(varDef.VariableType)); Context.IL.Emit(OpCodes.Callvirt, Module.Import( Module.Import(typeof (ResourceDictionary)) .Resolve() .Methods.Single(md => md.Name == "Add" && md.Parameters.Count == 2))); } } } //Set ResourcesDictionaries to their parents XmlName propertyName; if (SetPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName) && (propertyName.LocalName == "Resources" || propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && (Context.Variables[node].VariableType.FullName == "Xamarin.Forms.ResourceDictionary" || Context.Variables[node].VariableType.Resolve().BaseType.FullName == "Xamarin.Forms.ResourceDictionary")) SetPropertiesVisitor.SetPropertyValue(Context.Variables[(IElementNode)parentNode], propertyName, node, Context, node); }