Esempio n. 1
0
        /// <summary>
        ///     Dump out an attribute.
        /// </summary>
        /// <param name="attribute">
        ///     The target attribute.
        /// </param>
        /// <param name="depth">
        ///     The current element depth.
        /// </param>
        static void DumpAttribute(XAttribute attribute, int depth)
        {
            AttributeLocation location = attribute.Annotation <AttributeLocation>();

            Log.Information("{Indent}@{Name}='{Value}' ({StartLine},{StartColumn}) to ({EndLine},{EndColumn})",
                            new String(' ', depth * 4 + 4 /* Extra indent for attributes */),
                            attribute.Name,
                            attribute.Value,
                            location.Start.LineNumber, location.Start.ColumnNumber,
                            location.End.LineNumber, location.End.ColumnNumber
                            );
        }
Esempio n. 2
0
        /// <summary>
        ///     Capture location information for the current element.
        /// </summary>
        void CaptureLocation()
        {
            Log.Verbose("[Capture{NodeType}Location] {Name} ({LineNumber},{ColumnNumber}) (IsEmpty={IsEmptyElement}, EmitEndElement={EmitEndElement}, ElementLocationStack={StackDepth})",
                        NodeType, Name, LineNumber, LinePosition, IsEmptyElement, _emitEndElement, DumpElementStack()
                        );

            // This logic is pretty ugly, and needs serious reworking (would work better modeled as a state machine).
            // It's functional, there are almost certainly edge-cases it will fail (e.g. the last element).
            if (NodeType == XmlNodeType.Element)
            {
                ElementLocation elementLocation;
                if (_emitEndElement)
                {
                    // Element followed by element; capture the end of the previous element.
                    elementLocation     = _elementLocationStack.Pop();
                    elementLocation.End = CurrentPosition.Move(columnCount: -1);

                    Log.Verbose("[Capture{NodeType}LocationEnd] {Name} ({StartLineNumber},{StartColumnNumber}-{EndLineNumber},{EndColumnNumber})",
                                NodeType, Name,
                                elementLocation.Start.LineNumber, elementLocation.Start.ColumnNumber,
                                elementLocation.End.LineNumber, elementLocation.End.ColumnNumber
                                );

                    _emitEndElement = false;
                }

                Log.Verbose("[Capture{NodeType}LocationStart] {Name} ({LineNumber},{ColumnNumber})",
                            NodeType, Name, LineNumber, LinePosition
                            );

                // Capture the start of the new element.
                elementLocation = new ElementLocation
                {
                    Depth = Depth,
                    Start = CurrentPosition.Move(columnCount: -1)
                };
                _locations.Add(elementLocation);
                _elementLocationStack.Push(elementLocation);
            }
            else if (NodeType == XmlNodeType.EndElement || _emitEndElement)
            {
                // Element, followed by whitespace / text, followed by element.
                ElementLocation elementLocation = _elementLocationStack.Pop();
                elementLocation.End = CurrentPosition;

                Log.Verbose("[Capture{NodeType}LocationEnd] {Name} ({StartLineNumber},{StartColumnNumber}-{EndLineNumber},{EndColumnNumber})",
                            NodeType, Name,
                            elementLocation.Start.LineNumber, elementLocation.Start.ColumnNumber,
                            elementLocation.End.LineNumber, elementLocation.End.ColumnNumber
                            );

                _emitEndElement = false;
            }
            else if (NodeType == XmlNodeType.Attribute)
            {
                // Attribute
                _locations.Add(
                    AttributeLocation.Create(CurrentPosition, Name, Value)
                    );
            }
            else
            {
                // We don't care, but log it anyway to help track down weird edge-case behaviour.
                Log.Verbose("[SkipCapture{NodeType}Location] {Name} ({LineNumber},{ColumnNumber})",
                            NodeType, Name, LineNumber, LinePosition
                            );
            }
        }