Esempio n. 1
0
        public static SyntaxNode FindNode(
            this SyntaxNode node,
            int position,
            Func <SyntaxNode, bool> descendIntoChildren = null)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            int  offset         = position;
            bool searchChildren = true;

            while (searchChildren)
            {
                if (descendIntoChildren?.Invoke(node) == false)
                {
                    break;
                }

                // set to false, so loop will only continue if explicitly
                // specified in a later stage
                searchChildren = false;

                int index;
                node.GetIndexAndOffset(offset, out index, out offset);
                if (index > 0)
                {
                    index--;
                }

                var slotCount = node.GetSlotCountIncludingTrivia();

                for (int i = index; i < slotCount; i++)
                {
                    var child = node.GetSlotIncludingTrivia(i);
                    if (child != null)
                    {
                        if (child.Start > position)
                        {
                            // child is after position
                            break;
                        }
                        else if ((child.Start + child.FullWidth) <= position)
                        {
                            // child ends before position, go to next child
                            continue;
                        }
                        else
                        {
                            node           = child;
                            searchChildren = true;
                            break;
                        }
                    }
                }
            }

            return(node);
        }
Esempio n. 2
0
        public static int VisitRecursive(
            SyntaxNode node,
            int windowStart,
            int windowLength,
            Action <int, int, SyntaxNode, XmlClassificationTypes> resultCollector,
            int start = 0)
        {
            if (node == null)
            {
                return(0);
            }

            XmlClassificationTypes[] childTypes = null;
            kindMap.TryGetValue(node.Kind, out childTypes);

            int visitedCount = 0;
            int windowEnd    = windowStart + windowLength;
            var targetOffset = windowStart - start;

            int offset;
            int index;

            node.GetIndexAndOffset(targetOffset, out index, out offset);
            start += offset;

            for (int i = index; i < node.SlotCount; i++)
            {
                if (start > windowEnd)
                {
                    break;
                }

                var child = node.GetNodeSlot(i);
                visitedCount++;
                if (child == null)
                {
                    continue;
                }

                var currentStart  = Math.Max(start, windowStart);
                var currentLength = Math.Min(windowEnd, start + child.FullWidth) - currentStart;
                if (currentLength >= 0)
                {
                    var childType = childTypes == null ? XmlClassificationTypes.None : childTypes[i];

                    if (childType == XmlClassificationTypes.None)
                    {
                        if (child.Kind == SyntaxKind.XmlTextLiteralToken)
                        {
                            childType = XmlClassificationTypes.XmlText;
                        }
                        else if (child.Kind == SyntaxKind.XmlEntityLiteralToken)
                        {
                            childType = XmlClassificationTypes.XmlEntityReference;
                        }
                    }

                    if (childType == XmlClassificationTypes.None)
                    {
                        visitedCount += VisitRecursive(child, windowStart, windowLength, resultCollector, start);
                    }
                    else
                    {
                        if (currentLength > 0)
                        {
                            resultCollector(currentStart, currentLength, child, childType);
                        }
                    }
                }

                start += child.FullWidth;
            }

            return(visitedCount);
        }
        private static int VisitChildren(
            SyntaxNode syntaxNode,
            int windowStart,
            int windowLength,
            Action<int, int, SyntaxNode, XmlClassificationTypes> resultCollector,
            int start,
            XmlClassificationTypes[] childTypes)
        {
            int visitedCount = 0;
            int windowEnd = windowStart + windowLength;
            var targetOffset = windowStart - start;

            int offset;
            int index;
            syntaxNode.GetIndexAndOffset(targetOffset, out index, out offset);
            start += offset;

            for (int i = index; i < syntaxNode.SlotCount; i++)
            {
                if (start > windowEnd)
                {
                    break;
                }

                var child = syntaxNode.GetSlot(i);
                visitedCount++;
                if (child == null)
                {
                    continue;
                }

                var currentStart = Math.Max(start, windowStart);
                var currentLength = Math.Min(windowEnd, start + child.FullWidth) - currentStart;
                if (currentLength >= 0)
                {
                    var childType = childTypes == null ? XmlClassificationTypes.None : childTypes[i];

                    if (childType == XmlClassificationTypes.None)
                    {
                        if (child.Kind == SyntaxKind.XmlTextLiteralToken)
                        {
                            childType = XmlClassificationTypes.XmlText;
                        }
                        else if (child.Kind == SyntaxKind.XmlEntityLiteralToken)
                        {
                            childType = XmlClassificationTypes.XmlEntityReference;
                        }
                    }

                    if (childType == XmlClassificationTypes.None)
                    {
                        visitedCount += Visit(child, windowStart, windowLength, resultCollector, start);
                    }
                    else
                    {
                        if (currentLength > 0)
                        {
                            resultCollector(currentStart, currentLength, child, childType);
                        }
                    }
                }

                start += child.FullWidth;
            }

            return visitedCount;
        }