public ParsedMarkupExtensionInfo(ParsedMarkupExtensionInfo info)
		{
			this.value = info.value;
			this.index = info.index;
			this.nsResolver = info.nsResolver;
			this.sctx = info.sctx;
		}
Esempio n. 2
0
        IEnumerable <XamlXmlNodeInfo> ReadMarkup(ParsedMarkupExtensionInfo pai)
        {
            yield return(Node(XamlNodeType.StartObject, pai.Type));

            foreach (var xepair in pai.Arguments)
            {
                yield return(Node(XamlNodeType.StartMember, xepair.Key));

                var list = xepair.Value as List <object>;
                if (list != null)
                {
                    foreach (var s in list)
                    {
                        foreach (var node in ReadMarkupArgument(s))
                        {
                            yield return(node);
                        }
                    }
                }
                else
                {
                    foreach (var node in ReadMarkupArgument(xepair.Value))
                    {
                        yield return(node);
                    }
                }
                yield return(Node(XamlNodeType.EndMember, xepair.Key));
            }

            yield return(Node(XamlNodeType.EndObject, pai.Type));
        }
Esempio n. 3
0
 public ParsedMarkupExtensionInfo(ParsedMarkupExtensionInfo info)
 {
     this.value      = info.value;
     this.index      = info.index;
     this.nsResolver = info.nsResolver;
     this.sctx       = info.sctx;
 }
Esempio n. 4
0
        public ParsedMarkupExtensionInfo(ParsedMarkupExtensionInfo info)
        {
            //before creating new ParsedMarkupExtensionInfo with another ParsedMarkupExtensionInfo
            //we must calculate bounds of our new pmei. Scan rest of string and search first true-close bracket
            int nastedExtensionsCount = 0;

            for (int i = info.index + 1; i < info.value.Length; i++)
            {
                if (info.value[i] == '{')
                {
                    nastedExtensionsCount++;
                }
                if (info.value[i] == '}')
                {
                    if (nastedExtensionsCount > 0)
                    {
                        nastedExtensionsCount--;
                    }
                    else
                    {
                        this.value = info.value.Substring(info.index, i - info.index + 1);
                        break;
                    }
                }
            }

            this.index      = 0;
            this.nsResolver = info.nsResolver;
            this.sctx       = info.sctx;
        }
Esempio n. 5
0
        ParsedMarkupExtensionInfo ReadMarkup()
        {
            var info = new ParsedMarkupExtensionInfo(this);

            try {
                info.Parse();
                index = info.index;
                return(info);
            } catch {
            }
            return(null);
        }
		public static ParsedMarkupExtensionInfo Parse (string raw, IXamlNamespaceResolver nsResolver, XamlSchemaContext sctx)
		{
			if (raw == null)
				throw new ArgumentNullException ("raw");
			if (raw.Length == 0 || raw [0] != '{')
				throw Error ("Invalid markup extension attribute. It should begin with '{{', but was {0}", raw);
			var ret = new ParsedMarkupExtensionInfo ();
			int idx = raw.IndexOf ('}');
			if (idx < 0)
				throw Error ("Expected '}}' in the markup extension attribute: '{0}'", raw);
			raw = raw.Substring (1, idx - 1);
			idx = raw.IndexOf (' ');
			string name = idx < 0 ? raw : raw.Substring (0, idx);

			XamlTypeName xtn;
			if (!XamlTypeName.TryParse (name, nsResolver, out xtn))
				throw Error ("Failed to parse type name '{0}'", name);
			var xt = sctx.GetXamlType (xtn);
			ret.Type = xt;

			if (idx < 0)
				return ret;

			string [] vpairs = raw.Substring (idx + 1, raw.Length - idx - 1).Split (',');
			List<string> posPrms = null;
			foreach (string vpair in vpairs) {
				idx = vpair.IndexOf ('=');
				// FIXME: unescape string (e.g. comma)
				if (idx < 0) {
					if (posPrms == null) {
						posPrms = new List<string> ();
						ret.Arguments.Add (XamlLanguage.PositionalParameters, posPrms);
					}
					posPrms.Add (UnescapeValue (vpair.Trim ()));
				} else {
					var key = vpair.Substring (0, idx).Trim ();
					// FIXME: is unknown member always isAttacheable = false?
					var xm = xt.GetMember (key) ?? new XamlMember (key, xt, false);
					ret.Arguments.Add (xm, UnescapeValue (vpair.Substring (idx + 1).Trim ()));
				}
			}
			return ret;
		}
Esempio n. 7
0
        // Note that it could return invalid (None) node to tell the caller that it is not really an object element.
        IEnumerable <XamlXmlNodeInfo> ReadObjectElement(XamlType parentType, XamlMember currentMember)
        {
            if (r.NodeType == XmlNodeType.EndElement)
            {
                yield break;
            }

            if (r.NodeType == XmlNodeType.Text || r.NodeType == XmlNodeType.CDATA)
            {
                //throw new XamlParseException (String.Format ("Element is expected, but got {0}", r.NodeType));
                yield return(Node(XamlNodeType.Value, r.Value));

                r.Read();
                yield break;
            }

            if (r.NodeType != XmlNodeType.Element)
            {
                throw new XamlParseException(String.Format("Element is expected, but got {0}", r.NodeType));
            }

            if (r.MoveToFirstAttribute())
            {
                do
                {
                    if (r.NamespaceURI == XamlLanguage.Xmlns2000Namespace)
                    {
                        yield return(Node(XamlNodeType.NamespaceDeclaration, new NamespaceDeclaration(r.Value, r.Prefix == "xmlns" ? r.LocalName : String.Empty)));
                    }
                } while (r.MoveToNextAttribute());
                r.MoveToElement();
            }

            var sti = GetStartTagInfo();

            var xt = sctx.GetXamlType(sti.TypeName);

            if (xt == null)
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && (r.LocalName.IndexOf('.') > 0 || parentType.GetMember(r.LocalName) != null))
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
                xt = new XamlType(sti.Namespace, sti.Name, sti.TypeName.TypeArguments == null ? null : sti.TypeName.TypeArguments.Select <XamlTypeName, XamlType> (xxtn => sctx.GetXamlType(xxtn)).ToArray(), sctx);
            }

            bool isGetObject = false;

            if (currentMember != null && !xt.CanAssignTo(currentMember.Type))
            {
                if (currentMember.DeclaringType != null && currentMember.DeclaringType.ContentProperty == currentMember)
                {
                    isGetObject = true;
                }

                // It could still be GetObject if current_member
                // is not a directive and current type is not
                // a markup extension.
                // (I'm not very sure about the condition;
                // it could be more complex.)
                // seealso: bug #682131
                else if (!(currentMember is XamlDirective) &&
                         !xt.IsMarkupExtension)
                {
                    isGetObject = true;
                }
            }

            if (isGetObject)
            {
                yield return(Node(XamlNodeType.GetObject, currentMember.Type));

                foreach (var ni in ReadMembers(parentType, currentMember.Type))
                {
                    yield return(ni);
                }
                yield return(Node(XamlNodeType.EndObject, currentMember.Type));

                yield break;
            }
            // else

            yield return(Node(XamlNodeType.StartObject, xt));

            // process attribute members (including MarkupExtensions)
            ProcessAttributesToMember(sti, xt);

            foreach (var pair in sti.Members)
            {
                yield return(Node(XamlNodeType.StartMember, pair.Key));

                // Try markup extension
                // FIXME: is this rule correct?
                var v = pair.Value;
                if (!String.IsNullOrEmpty(v) && v [0] == '{')
                {
                    var pai = ParsedMarkupExtensionInfo.Parse(v, xaml_namespace_resolver, sctx);
                    yield return(Node(XamlNodeType.StartObject, pai.Type));

                    foreach (var xepair in pai.Arguments)
                    {
                        yield return(Node(XamlNodeType.StartMember, xepair.Key));

                        if (xepair.Value is List <string> )
                        {
                            foreach (var s in (List <string>)xepair.Value)
                            {
                                yield return(Node(XamlNodeType.Value, s));
                            }
                        }
                        else
                        {
                            yield return(Node(XamlNodeType.Value, xepair.Value));
                        }
                        yield return(Node(XamlNodeType.EndMember, xepair.Key));
                    }
                    yield return(Node(XamlNodeType.EndObject, pai.Type));
                }
                else
                {
                    yield return(Node(XamlNodeType.Value, pair.Value));
                }

                yield return(Node(XamlNodeType.EndMember, pair.Key));
            }

            // process content members
            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMembers(parentType, xt))
                {
                    yield return(ni);
                }
                r.ReadEndElement();
            }
            else
            {
                r.Read();                  // consume empty element.
            }
            yield return(Node(XamlNodeType.EndObject, xt));
        }
Esempio n. 8
0
        // Note that it could return invalid (None) node to tell the caller that it is not really an object element.
        IEnumerable <XamlXmlNodeInfo> ReadObjectElement(XamlType parentType, XamlMember currentMember)
        {
            if (r.NodeType == XmlNodeType.EndElement)
            {
                yield break;
            }

            if (r.NodeType == XmlNodeType.Text || r.NodeType == XmlNodeType.CDATA)
            {
                yield return(Node(XamlNodeType.Value, NormalizeWhitespace(r.Value)));

                r.Read();
                yield break;
            }

            if (r.NodeType != XmlNodeType.Element)
            {
                throw new XamlParseException(String.Format("Element is expected, but got {0}", r.NodeType));
            }

            if (r.MoveToFirstAttribute())
            {
                do
                {
                    if (r.NamespaceURI == XamlLanguage.Xmlns2000Namespace)
                    {
                        yield return(Node(XamlNodeType.NamespaceDeclaration, new NamespaceDeclaration(ResolveLocalNamespace(r.Value), r.Prefix == "xmlns" ? r.LocalName : String.Empty)));
                    }
                } while (r.MoveToNextAttribute());
                r.MoveToElement();
            }

            var sti = GetStartTagInfo();

            var xt = sctx.GetXamlType(sti.TypeName);

            if (ReferenceEquals(xt, null))
            {
                // Current element could be for another member in the parent type (if exists)
                if (parentType != null && (r.LocalName.IndexOf('.') > 0 || parentType.GetMember(r.LocalName) != null))
                {
                    // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
                    yield return(Node(XamlNodeType.None, null));

                    yield break;
                }

                // creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
                xt = new XamlType(sti.Namespace, sti.Name, sti.TypeName.TypeArguments?.Select(xxtn => sctx.GetXamlType(xxtn)).ToArray(), sctx);
            }

            // It could still be GetObject if current_member is not defer-loaded, it
            // is not a directive, and current type is not
            // a markup extension.
            // (I'm not very sure about the condition;
            // it could be more complex.)
            // seealso: bug #682131
            if (!ReferenceEquals(currentMember, null) &&
                ReferenceEquals(currentMember.DeferringLoader, null) &&
                !xt.CanAssignTo(currentMember.Type) &&
                !ReferenceEquals(xt, XamlLanguage.Reference) &&
                (
                    currentMember.DeclaringType?.ContentProperty == currentMember ||
                    (!currentMember.IsDirective && !xt.IsMarkupExtension)
                )
                )
            {
                yield return(Node(XamlNodeType.GetObject, currentMember.Type));

                foreach (var ni in ReadMembers(parentType, currentMember.Type))
                {
                    yield return(ni);
                }
                yield return(Node(XamlNodeType.EndObject, currentMember.Type));

                yield break;
            }


            yield return(Node(XamlNodeType.StartObject, xt));

            // process attribute members (including MarkupExtensions)
            ProcessAttributesToMember(sti, xt);

            for (int i = 0; i < sti.Members.Count; i++)
            {
                var pair = sti.Members[i];
                yield return(Node(XamlNodeType.StartMember, pair.Key));

                // Try markup extension
                // FIXME: is this rule correct?
                var v = pair.Value;
                if (!string.IsNullOrEmpty(v) && v[0] == '{')
                {
                    if (v.Length >= 2 && v[1] == '}')
                    {
                        // escaped value with {} at the beginning of the string
                        yield return(Node(XamlNodeType.Value, v.Substring(2)));
                    }
                    else
                    {
                        var pai = new ParsedMarkupExtensionInfo(v, xaml_namespace_resolver, sctx);
                        pai.Parse();
                        foreach (var node in ReadMarkup(pai))
                        {
                            yield return(node);
                        }
                    }
                }
                else
                {
                    yield return(Node(XamlNodeType.Value, v));
                }

                yield return(Node(XamlNodeType.EndMember, pair.Key));
            }

            // process content members
            if (!r.IsEmptyElement)
            {
                r.Read();
                foreach (var ni in ReadMembers(parentType, xt))
                {
                    yield return(ni);
                }
                r.ReadEndElement();
            }
            else
            {
                r.Read();                  // consume empty element.
            }
            yield return(Node(XamlNodeType.EndObject, xt));
        }
        public static ParsedMarkupExtensionInfo Parse(string raw, IXamlNamespaceResolver nsResolver, XamlSchemaContext sctx)
        {
            if (raw == null)
            {
                throw new ArgumentNullException("raw");
            }
            if (raw.Length == 0 || raw [0] != '{')
            {
                throw Error("Invalid markup extension attribute. It should begin with '{{', but was {0}", raw);
            }
            var ret = new ParsedMarkupExtensionInfo();
            int idx = raw.IndexOf('}');

            if (idx < 0)
            {
                throw Error("Expected '}}' in the markup extension attribute: '{0}'", raw);
            }
            raw = raw.Substring(1, idx - 1);
            idx = raw.IndexOf(' ');
            string name = idx < 0 ? raw : raw.Substring(0, idx);

            XamlTypeName xtn;

            if (!XamlTypeName.TryParse(name, nsResolver, out xtn))
            {
                throw Error("Failed to parse type name '{0}'", name);
            }
            var xt = sctx.GetXamlType(xtn);

            ret.Type = xt;

            if (idx < 0)
            {
                return(ret);
            }

            string []     vpairs  = raw.Substring(idx + 1, raw.Length - idx - 1).Split(',');
            List <string> posPrms = null;

            foreach (string vpair in vpairs)
            {
                idx = vpair.IndexOf('=');
                // FIXME: unescape string (e.g. comma)
                if (idx < 0)
                {
                    if (posPrms == null)
                    {
                        posPrms = new List <string> ();
                        ret.Arguments.Add(XamlLanguage.PositionalParameters, posPrms);
                    }
                    posPrms.Add(UnescapeValue(vpair.Trim()));
                }
                else
                {
                    var key = vpair.Substring(0, idx).Trim();
                    // FIXME: is unknown member always isAttacheable = false?
                    var xm = xt.GetMember(key) ?? new XamlMember(key, xt, false);
                    ret.Arguments.Add(xm, UnescapeValue(vpair.Substring(idx + 1).Trim()));
                }
            }
            return(ret);
        }
		ParsedMarkupExtensionInfo ReadMarkup()
		{
			var info = new ParsedMarkupExtensionInfo (this);
			try {
				info.Parse ();
				index = info.index;
				return info;
			} catch {
			}
			return null;
		}
Esempio n. 11
0
		IEnumerable<XamlXmlNodeInfo> ReadMarkup(ParsedMarkupExtensionInfo pai)
		{
			yield return Node (XamlNodeType.StartObject, pai.Type);

			foreach (var xepair in pai.Arguments) {
				yield return Node (XamlNodeType.StartMember, xepair.Key);
				var list = xepair.Value as List<object>;
				if (list != null) {
					foreach (var s in list) {
						foreach (var node in ReadMarkupArgument(s))
							yield return node;
					}
				}
				else {
					foreach (var node in ReadMarkupArgument(xepair.Value))
						yield return node;
				}
				yield return Node (XamlNodeType.EndMember, xepair.Key);
			}

			yield return Node (XamlNodeType.EndObject, pai.Type);
		}
Esempio n. 12
0
		// Note that it could return invalid (None) node to tell the caller that it is not really an object element.
		IEnumerable<XamlXmlNodeInfo> ReadObjectElement (XamlType parentType, XamlMember currentMember)
		{
			if (r.NodeType == XmlNodeType.EndElement)
				yield break;

			if (r.NodeType == XmlNodeType.Text || r.NodeType == XmlNodeType.CDATA) {
				//throw new XamlParseException (String.Format ("Element is expected, but got {0}", r.NodeType));
				yield return Node (XamlNodeType.Value, r.Value);
				r.Read();
				yield break;
			}
			
			if (r.NodeType != XmlNodeType.Element)
			{
				throw new XamlParseException (String.Format ("Element is expected, but got {0}", r.NodeType));
			}

			if (r.MoveToFirstAttribute ()) {
				do {
					if (r.NamespaceURI == XamlLanguage.Xmlns2000Namespace)
						yield return Node (XamlNodeType.NamespaceDeclaration, new NamespaceDeclaration (ResolveLocalNamespace(r.Value), r.Prefix == "xmlns" ? r.LocalName : String.Empty));
				} while (r.MoveToNextAttribute ());
				r.MoveToElement ();
			}

			var sti = GetStartTagInfo ();

			var xt = sctx.GetXamlType (sti.TypeName);
			if (xt == null) {
				// Current element could be for another member in the parent type (if exists)
				if (parentType != null && (r.LocalName.IndexOf ('.') > 0 || parentType.GetMember (r.LocalName) != null)) {
					// stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object".
					yield return Node (XamlNodeType.None, null);
					yield break;
				}

				// creates name-only XamlType. Also, it does not seem that it does not store this XamlType to XamlSchemaContext (Try GetXamlType(xtn) after reading such xaml node, it will return null).
				xt = new XamlType (sti.Namespace, sti.Name, sti.TypeName.TypeArguments == null ? null : sti.TypeName.TypeArguments.Select<XamlTypeName,XamlType> (xxtn => sctx.GetXamlType (xxtn)).ToArray (), sctx);
			}
			
			bool isGetObject = false;
			if (currentMember != null && !xt.CanAssignTo (currentMember.Type)) {
				if (currentMember.DeclaringType != null && currentMember.DeclaringType.ContentProperty == currentMember)
					isGetObject = true;

				// It could still be GetObject if current_member
				// is not a directive and current type is not
				// a markup extension.
				// (I'm not very sure about the condition;
				// it could be more complex.)
				// seealso: bug #682131
				else if (!(currentMember is XamlDirective) &&
				    !xt.IsMarkupExtension)
					isGetObject = true;
			}

			if (isGetObject) {
				yield return Node (XamlNodeType.GetObject, currentMember.Type);
				foreach (var ni in ReadMembers (parentType, currentMember.Type))
					yield return ni;
				yield return Node (XamlNodeType.EndObject, currentMember.Type);
				yield break;
			}
			// else

			yield return Node (XamlNodeType.StartObject, xt);

			// process attribute members (including MarkupExtensions)
			ProcessAttributesToMember (sti, xt);

			foreach (var pair in sti.Members) {
				yield return Node (XamlNodeType.StartMember, pair.Key);

				// Try markup extension
				// FIXME: is this rule correct?
				var v = pair.Value;
				if (!String.IsNullOrEmpty (v) && v [0] == '{') {
					var pai = new ParsedMarkupExtensionInfo(v, xaml_namespace_resolver, sctx);
					pai.Parse ();
					foreach (var node in ReadMarkup(pai))
						yield return node;
				}
				else
					yield return Node (XamlNodeType.Value, pair.Value);

				yield return Node (XamlNodeType.EndMember, pair.Key);
			}

			// process content members
			if (!r.IsEmptyElement) {
				r.Read ();
				foreach (var ni in ReadMembers (parentType, xt))
					yield return ni;
				r.ReadEndElement ();
			}
			else
				r.Read (); // consume empty element.

			yield return Node (XamlNodeType.EndObject, xt);
		}