Пример #1
0
        private static int ComputeFullWidthIterative(SyntaxNode node, int start = 0)
        {
            if (node.fullWidth >= 0)
            {
                return(node.fullWidth);
            }

            node.Start = start;

            Stack <ComputeFullWidthState> nodes = new Stack <ComputeFullWidthState>();

            nodes.Push(new ComputeFullWidthState()
            {
                Node = node
            });

            while (nodes.Count != 0)
            {
                var state = nodes.Pop();

AfterPopState:
                node = state.Node;
                if (node.fullWidth == -1)
                {
                    node.fullWidth = node.GetTextWidth();

                    // Node full width is now zero or the node is a token/trivial
                    // and the full width represents the width of the text
                    // for the token/trivia. Therefore, start is only incremented
                    // for tokens and trivia.
                    start += node.fullWidth;
                }

                var parent = state.Parent;

                var slotCount = node.GetSlotCountIncludingTrivia();
                for (; state.Index < slotCount; state.Index++)
                {
                    var child = node.GetSlotIncludingTrivia(state.Index);
                    if (child == null)
                    {
                        continue;
                    }

                    child.Parent = node;
                    child.Start  = start;

                    if (child.fullWidth == -1)
                    {
                        state.Index++;
                        nodes.Push(state);

                        state = new ComputeFullWidthState()
                        {
                            Node   = child,
                            Parent = node
                        };

                        goto AfterPopState;
                    }
                    else
                    {
                        start          += child.fullWidth;
                        node.fullWidth += child.fullWidth;
                    }
                }

                if (parent != null)
                {
                    if (parent.fullWidth == -1)
                    {
                        parent.fullWidth = 0;
                    }

                    parent.fullWidth += node.fullWidth;
                }
            }

            return(node.fullWidth);
        }