示例#1
0
        /// <summary>
        /// It seems like BamlReader will always output 'x:Key' as last property. However, it must be specified as attribute in valid .xaml, so we move it to the front
        /// of the attribute list.
        /// </summary>
        void MoveXKeyToFront(XamlNode node)
        {
            foreach (XamlNode child in node.Children)
            {
                MoveXKeyToFront(child);
            }

            XamlObjectNode obj = node as XamlObjectNode;

            if (obj != null && obj.Children.Count > 0)
            {
                XamlMemberNode memberNode = obj.Children[obj.Children.Count - 1] as XamlMemberNode;
                if (memberNode != null && memberNode.Member == XamlLanguage.Key)
                {
                    // move memberNode in front of the first member node:
                    for (int i = 0; i < obj.Children.Count; i++)
                    {
                        if (obj.Children[i] is XamlMemberNode)
                        {
                            obj.Children.Insert(i, memberNode);
                            obj.Children.RemoveAt(obj.Children.Count - 1);
                            break;
                        }
                    }
                }
            }
        }
示例#2
0
        private static void CloseTag(string name, SymbolScanner scanner, Stack <XamlObjectNode> objStack)
        {
            XamlObjectNode objectNode = null;

            List <XamlObjectNode> children = new List <XamlObjectNode>();

            while (objStack.Count > 0)
            {
                objectNode = objStack.Peek();
                if (objectNode.Name == name)
                {
                    objectNode.LineNumberEnd = scanner.LineNumber + 1;
                    // it must be point to the next symbol so '-1'
                    objectNode.LinePositionEnd = scanner.CharPosition;
                    foreach (XamlObjectNode node in children)
                    {
                        objectNode.AddChild(node);
                    }

                    objectNode.SetState(XamlNodeBase.EState.Closed);

                    //remove found node from stack
                    objStack.Pop();
                    break;
                }

                children.Add(objectNode);
                objectNode = objStack.Pop();
            }
        }
示例#3
0
        static List <XamlNode> Parse(XamlReader reader)
        {
            List <XamlNode>          currentList = new List <XamlNode>();
            Stack <List <XamlNode> > stack       = new Stack <List <XamlNode> >();

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XamlNodeType.None:
                    break;

                case XamlNodeType.StartObject:
                    XamlObjectNode obj = new XamlObjectNode(reader.Type);
                    currentList.Add(obj);
                    stack.Push(currentList);
                    currentList = obj.Children;
                    break;

                case XamlNodeType.GetObject:
                    XamlGetObjectNode getObject = new XamlGetObjectNode();
                    currentList.Add(getObject);
                    stack.Push(currentList);
                    currentList = getObject.Children;
                    break;

                case XamlNodeType.StartMember:
                    XamlMemberNode member = new XamlMemberNode(reader.Member);
                    currentList.Add(member);
                    stack.Push(currentList);
                    currentList = member.Children;
                    break;

                case XamlNodeType.Value:
                    currentList.Add(new XamlValueNode(reader.Value));
                    break;

                case XamlNodeType.NamespaceDeclaration:
                    currentList.Add(new XamlNamespaceDeclarationNode(reader.Namespace));
                    break;

                case XamlNodeType.EndObject:
                case XamlNodeType.EndMember:
                    currentList = stack.Pop();
                    break;

                default:
                    throw new InvalidOperationException("Invalid value for XamlNodeType");
                }
            }
            if (stack.Count != 0)
            {
                throw new InvalidOperationException("Imbalanced stack");
            }
            return(currentList);
        }
示例#4
0
        void RemoveConnectionIds(XamlNode node, Dictionary <int, EventRegistration[]> eventMappings, XamlSchemaContext context)
        {
            foreach (XamlNode child in node.Children)
            {
                RemoveConnectionIds(child, eventMappings, context);
            }

            XamlObjectNode obj = node as XamlObjectNode;

            if (obj != null && obj.Children.Count > 0)
            {
                var removableNodes = new List <XamlMemberNode>();
                var addableNodes   = new List <XamlMemberNode>();
                foreach (XamlMemberNode memberNode in obj.Children.OfType <XamlMemberNode>())
                {
                    if (memberNode.Member == XamlLanguage.ConnectionId && memberNode.Children.Single() is XamlValueNode)
                    {
                        var value = memberNode.Children.Single() as XamlValueNode;
                        int id;
                        if (value.Value is string && int.TryParse(value.Value as string, out id) && eventMappings.ContainsKey(id))
                        {
                            var map = eventMappings[id];
                            foreach (var entry in map)
                            {
                                if (entry.IsAttached)
                                {
                                    var type   = context.GetXamlType(Type.GetType(entry.AttachSourceType));
                                    var member = new XamlMemberNode(new XamlMember(entry.EventName, type, true));
                                    member.Children.Add(new XamlValueNode(entry.MethodName));
                                    addableNodes.Add(member);
                                }
                                else
                                {
                                    var member = new XamlMemberNode(obj.Type.GetMember(entry.EventName));
                                    member.Children.Add(new XamlValueNode(entry.MethodName));
                                    addableNodes.Add(member);
                                }
                            }
                            removableNodes.Add(memberNode);
                        }
                    }
                }
                foreach (var rnode in removableNodes)
                {
                    node.Children.Remove(rnode);
                }
                node.Children.InsertRange(node.Children.Count > 1 ? node.Children.Count - 1 : 0, addableNodes);
            }
        }
示例#5
0
        void AvoidContentProperties(XamlNode node)
        {
            foreach (XamlNode child in node.Children)
            {
                AvoidContentProperties(child);
            }


            XamlObjectNode obj = node as XamlObjectNode;

            if (obj != null)
            {
                // Visit all except for the last child:
                for (int i = 0; i < obj.Children.Count - 1; i++)
                {
                    // Avoids using content property syntax for simple string values, if the content property is not the last member.
                    // Without this, we cannot decompile &lt;GridViewColumn Header="Culture" DisplayMemberBinding="{Binding Culture}" /&gt;,
                    // because the Header property is the content property, but there is no way to represent the Binding as an element.
                    XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode;
                    if (memberNode != null && memberNode.Member == obj.Type.ContentProperty)
                    {
                        if (memberNode.Children.Count == 1 && memberNode.Children[0] is XamlValueNode)
                        {
                            // By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
                            XamlMember member = memberNode.Member;
                            memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable);
                        }
                    }
                }
                // We also need to avoid using content properties that have a markup extension as value, as the XamlXmlWriter would always expand those:
                for (int i = 0; i < obj.Children.Count; i++)
                {
                    XamlMemberNode memberNode = obj.Children[i] as XamlMemberNode;
                    if (memberNode != null && memberNode.Member == obj.Type.ContentProperty && memberNode.Children.Count == 1)
                    {
                        XamlObjectNode me = memberNode.Children[0] as XamlObjectNode;
                        if (me != null && me.Type.IsMarkupExtension)
                        {
                            // By creating a clone of the XamlMember, we prevent WPF from knowing that it's the content property.
                            XamlMember member = memberNode.Member;
                            memberNode.Member = new XamlMember(member.Name, member.DeclaringType, member.IsAttachable);
                        }
                    }
                }
            }
        }
示例#6
0
        private void Visit(XamlNodeBase node, IXamlNodeVisitor visitor)
        {
            if (visitor.IsAllowedToVisit(node))
            {
                visitor.Visit(node, this);
            }

            XamlObjectNode objectNode = node as XamlObjectNode;

            if (objectNode != null)
            {
                foreach (XamlAttribute attribute in objectNode.Attributes)
                {
                    Visit(attribute, visitor);
                }

                foreach (XamlNodeBase child in objectNode.Children)
                {
                    Visit(child, visitor);
                }
            }
        }
示例#7
0
		static List<XamlNode> Parse(XamlReader reader)
		{
			List<XamlNode> currentList = new List<XamlNode>();
			Stack<List<XamlNode>> stack = new Stack<List<XamlNode>>();
			while (reader.Read()) {
				switch (reader.NodeType) {
					case XamlNodeType.None:
						break;
					case XamlNodeType.StartObject:
						XamlObjectNode obj = new XamlObjectNode(reader.Type);
						currentList.Add(obj);
						stack.Push(currentList);
						currentList = obj.Children;
						break;
					case XamlNodeType.GetObject:
						XamlGetObjectNode getObject = new XamlGetObjectNode();
						currentList.Add(getObject);
						stack.Push(currentList);
						currentList = getObject.Children;
						break;
					case XamlNodeType.StartMember:
						XamlMemberNode member = new XamlMemberNode(reader.Member);
						currentList.Add(member);
						stack.Push(currentList);
						currentList = member.Children;
						break;
					case XamlNodeType.Value:
						currentList.Add(new XamlValueNode(reader.Value));
						break;
					case XamlNodeType.NamespaceDeclaration:
						currentList.Add(new XamlNamespaceDeclarationNode(reader.Namespace));
						break;
					case XamlNodeType.EndObject:
					case XamlNodeType.EndMember:
						currentList = stack.Pop();
						break;
					default:
						throw new InvalidOperationException("Invalid value for XamlNodeType");
				}
			}
			if (stack.Count != 0)
				throw new InvalidOperationException("Imbalanced stack");
			return currentList;
		}
示例#8
0
        public XamlMainObjectNode Parse(StreamReader fileStream)
        {
            if (fileStream == null)
            {
                throw new ArgumentNullException(nameof(fileStream));
            }

            Stack <XamlObjectNode> objStack    = new Stack <XamlObjectNode>();
            XamlObjectNode         currentNode = null;
            XamlMainObjectNode     mainObject  = null;

            SymbolScanner scanner = new SymbolScanner(fileStream);

            int lineNumberStart   = 0;
            int linePositionStart = 0;
            //long newLineStreamPosition = fileStream.BaseStream.Position;
            string ident;

            //bool tagBracketClosed = false;
            while (!fileStream.EndOfStream)
            {
                scanner.SkipSpaces();
                char ch = scanner.GetSymbol();
                if (ch == '\0')
                {
                    break;
                }

                if (ch == SymbolScanner.SymbolStartTag)
                {
                    //tagBracketClosed = false;
                    lineNumberStart = scanner.LineNumber;
                    //open tag symbol must be start not the next symbol
                    linePositionStart = scanner.CharPosition - 1;
                    char chNext = scanner.NextSymbol;
                    if (chNext == SymbolScanner.SymbolCloseTag)
                    {
                        scanner.SkipSymbol();
                        ident = scanner.GetName();
                        if (DoEndTag(ident, scanner))
                        {
                            CloseTag(ident, scanner, objStack);
                        }
                    }
                    else if (chNext == SymbolScanner.SymbolStartComment)
                    {
                        string comment = scanner.ReadComment();
                        Trace.WriteLine($"{lineNumberStart + 1}:{linePositionStart + 1} Comment:{comment}");
                        XamlCommentNode commentNode = new XamlCommentNode
                        {
                            LineNumberStart   = lineNumberStart + 1,
                            LinePositionStart = linePositionStart + 1,
                            Comment           = comment
                        };
                        commentNode.LineNumberEnd = scanner.LineNumber + 1;
                        //end position is outside comment tag
                        commentNode.LinePositionEnd = scanner.CharPosition;
                        objStack.Push(commentNode);
                    }
                    else
                    {
                        char breakSymbol;
                        ident       = scanner.GetName();
                        breakSymbol = scanner.NextSymbol;
                        //ident = GetIdent(fileStream, out breakSymbol);
                        Trace.WriteLine($"{lineNumberStart + 1}:{linePositionStart + 1} Start Tag:{ident}");
                        if (mainObject == null)
                        {
                            mainObject = new XamlMainObjectNode {
                                LineNumberStart = lineNumberStart + 1, LinePositionStart = linePositionStart + 1
                            };
                            mainObject.Name = ident;
                            currentNode     = mainObject;
                            //root.MainObject = mainObject;
                            objStack.Push(mainObject);
                        }
                        else
                        {
                            currentNode = new XamlObjectNode {
                                LineNumberStart = lineNumberStart + 1, LinePositionStart = linePositionStart + 1
                            };
                            currentNode.Name = ident;
                            objStack.Push(currentNode);
                        }

                        if (breakSymbol != SymbolScanner.SymbolEndTag)
                        {
                            scanner.SkipSpaces();
                            breakSymbol = scanner.NextSymbol;
                        }

                        if (breakSymbol == SymbolScanner.SymbolCloseTag)
                        {
                            //end of tag
                            if (DoEndTag(ident, scanner))
                            {
                                CloseTag(ident, scanner, objStack);
                            }
                        }
                        else if (breakSymbol != SymbolScanner.SymbolEndTag)
                        {
                            XamlObjectNode objectNode = null;
                            if (objStack.Count > 0)
                            {
                                objectNode = objStack.Peek();
                            }

                            bool isClosed = ReadAttributes(objectNode, scanner, breakSymbol);
                            if (isClosed)
                            {
                                //tagBracketClosed = true;
                                if (objectNode != null)
                                {
                                    objectNode.SetState(XamlNodeBase.EState.EndTagPresent);
                                    //objectNode.IsTagBracketClosed = true;
                                }

                                Trace.WriteLine("Tag end symbol for:" + ident);
                            }

                            if (scanner.NextSymbol == SymbolScanner.SymbolCloseTag)
                            {
                                //end of tag
                                if (DoEndTag(ident, scanner))
                                {
                                    CloseTag(ident, scanner, objStack);
                                }
                            }
                        }
                        else
                        {
                            // skip '>'
                            scanner.SkipSymbol();

                            XamlObjectNode objectNode = objStack.Peek();
                            objectNode.SetState(XamlNodeBase.EState.EndTagPresent);
                            Trace.WriteLine("Tag end symbol for:" + ident);
                        }

                        //chNext = scanner.NextSymbol;
                    }
                }
                else
                {
                    if (objStack.Count > 0)
                    {
                        XamlObjectNode objectNode = objStack.Peek();
                        if (objectNode.IsState(XamlNodeBase.EState.EndTagPresent))
                        {
                            lineNumberStart = scanner.LineNumber;
                            //text symbol must be current not the next symbol
                            linePositionStart = scanner.CharPosition - 1;

                            string text = scanner.ReadText(ch);
                            Trace.WriteLine("Text node:" + text);
                            XamlTextNode textNode = new XamlTextNode(text)
                            {
                                LineNumberStart = lineNumberStart + 1, LinePositionStart = linePositionStart + 1
                            };
                            textNode.LineNumberEnd = scanner.LastTextLineNumberEnd + 1;
                            // it must be the next symbol
                            textNode.LinePositionEnd = scanner.LastTextCharPositionEnd;
                            objectNode.SetState(XamlNodeBase.EState.TextNodePresent);
                            objectNode.AddChild(textNode);
                        }
                        else
                        {
                            //Trace.Write(ch);
                            _errorHandler?.Error($"Not expected symbol :'{ch}'", scanner);
                        }
                    }
                    else
                    {
                        //Trace.Write(ch);
                        _errorHandler?.Error($"Not expected symbol, no tag found :'{ch}'", scanner);
                    }
                }

                char chNext1 = scanner.CheckEndOfLine(scanner.NextSymbol);
            }

            if (objStack.Count > 0)
            {
                //ignore exception by non closed main state. Temporary
                if (mainObject != null && objStack.Count == 1)
                {
                    if (!mainObject.IsState(XamlNodeBase.EState.Closed))
                    {
                        return(mainObject);
                    }
                }
                _errorHandler?.Error($"unused {objStack.Count} nodes", scanner);
            }

            return(mainObject);
        }
示例#9
0
        private static bool ReadAttributes(XamlObjectNode xamlObjectNode, SymbolScanner scanner, char chNext)
        {
            bool   ret = false;
            char   breakSymbol;
            string attributeName  = string.Empty;
            string attributeValue = string.Empty;

            while (chNext != SymbolScanner.SymbolEndTag)
            {
                scanner.SkipSpaces();

                XamlAttribute attribute            = null;
                int           lineNumberValue      = -1;
                int           linePositionValue    = -1;
                int           lineNumberAttrName   = scanner.LineNumber;
                int           linePositionAttrName = scanner.CharPosition;
                if (scanner.NextSymbol == SymbolScanner.SymbolCloseTag || scanner.NextSymbol == SymbolScanner.SymbolEndTag)
                {
                    if (attribute != null)
                    {
                        attribute.LineNumberEnd   = scanner.LineNumber;
                        attribute.LinePositionEnd = scanner.CharPosition;
                    }

                    chNext = scanner.NextSymbol;
                    break;
                }

                attributeName = scanner.GetName();
                scanner.SkipSpaces();
                breakSymbol = scanner.NextSymbol;

                if (breakSymbol == SymbolScanner.SymbolEq)
                {
                    //skip '='
                    scanner.SkipSymbol();
                    scanner.SkipSpaces();
                    lineNumberValue   = scanner.LineNumber;
                    linePositionValue = scanner.CharPosition;
                    attributeValue    = scanner.ReadString();
                    chNext            = scanner.CheckEndOfLine(scanner.NextSymbol);
                }
                else if (breakSymbol == SymbolScanner.SymbolEndTag)
                {
                    if (attribute != null)
                    {
                        attribute.LineNumberEnd   = scanner.LineNumber;
                        attribute.LinePositionEnd = scanner.CharPosition;
                    }

                    chNext = breakSymbol;
                }
                else if (breakSymbol == SymbolScanner.SymbolCloseTag)
                {
                    chNext = scanner.GetSymbol();
                    chNext = scanner.NextSymbol;
                }
                else
                {
                    scanner.SkipSpaces();
                    chNext = scanner.NextSymbol;
                }

                attribute = new XamlAttribute(attributeName, attributeValue)
                {
                    LineNumberStart   = lineNumberAttrName + 1,
                    LineNumberEnd     = scanner.LineNumber + 1,
                    LinePositionStart = linePositionAttrName + 1,
                    LinePositionEnd   = scanner.CharPosition,


                    LineNumberValueStart   = lineNumberValue + 1,
                    LineNumberValueEnd     = scanner.LineNumber + 1,
                    LinePositionValueStart = linePositionValue + 1,
                    LinePositionValueEnd   = scanner.CharPosition
                };

                xamlObjectNode.Attributes.Add(attribute);

                Trace.WriteLine(
                    string.Format(
                        "\t{0}:{1} Attribute Name:{2}, {3}:{4} Value:{5}",
                        lineNumberAttrName + 1,
                        linePositionAttrName + 1,
                        attributeName,
                        lineNumberValue + 1,
                        linePositionValue + 1,
                        attributeValue));
            }

            ret    = chNext == SymbolScanner.SymbolEndTag;
            chNext = scanner.CheckEndOfLine(scanner.NextSymbol);
            if (ret)
            {
                chNext = scanner.GetSymbol();
                //chNext = TestNextSymbol(fileStream);
                chNext = scanner.CheckEndOfLine(chNext);
            }

            return(ret);
        }