Exemple #1
0
 internal Enumerator(IndexStack <T> stack)
 {
     _stack          = stack;
     _version        = stack._version;
     _index          = -2;
     _currentElement = default(T);
 }
        private static IndexStack <SyntaxNodeInfo> GetChildren(
            ISyntaxNode node,
            IVisitationMap visitationMap)
        {
            var children = new IndexStack <SyntaxNodeInfo>();

            visitationMap.ResolveChildren(node, children);
            return(children);
        }
        public static void Accept(
            this ISyntaxNode node,
            ISyntaxNodeVisitor visitor,
            IVisitationMap visitationMap)
        {
            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (visitor is null)
            {
                throw new ArgumentNullException(nameof(visitor));
            }

            if (visitationMap is null)
            {
                throw new ArgumentNullException(nameof(visitationMap));
            }

            var path          = new IndexStack <object>();
            var ancestors     = new IndexStack <SyntaxNodeInfo>();
            var ancestorNodes = new IndexStack <ISyntaxNode>();
            var level         = new IndexStack <IndexStack <SyntaxNodeInfo> >();

            var root = new IndexStack <SyntaxNodeInfo>();

            root.Push(new SyntaxNodeInfo(node, null));
            level.Push(root);

            int index = 0;

            while (level.Count != 0)
            {
                bool           isLeaving = level[index].Count == 0;
                VisitorAction  action    = default;
                SyntaxNodeInfo parent    = default;
                SyntaxNodeInfo current   = default;

                if (isLeaving)
                {
                    if (index == 0)
                    {
                        break;
                    }

                    level.Pop();
                    ancestorNodes.Pop();
                    current = ancestors.Pop();
                    parent  = ancestors.Count == 0
                        ? default
                        : ancestors.Peek();

                    action = Leave(
                        visitor,
                        current.Node,
                        parent.Node,
                        path,
                        ancestorNodes);

                    if (current.Name != null)
                    {
                        path.Pop();
                    }

                    if (current.Index.HasValue)
                    {
                        path.Pop();
                    }

                    index--;
                }
                else
                {
                    current = level[index].Pop();

                    if (current.Name != null)
                    {
                        path.Push(current.Name);
                    }

                    if (current.Index.HasValue)
                    {
                        path.Push(current.Index.Value);
                    }

                    action = Enter(
                        visitor,
                        current.Node,
                        parent.Node,
                        path,
                        ancestorNodes);

                    if (action == VisitorAction.Continue)
                    {
                        level.Push(GetChildren(current.Node, visitationMap));
                    }
                    else if (action == VisitorAction.Skip)
                    {
                        // TODO : replace with empty
                        level.Push(new IndexStack <SyntaxNodeInfo>());
                    }

                    parent = current;
                    ancestors.Push(current);
                    ancestorNodes.Push(current.Node);
                    index++;
                }

                if (action == VisitorAction.Break)
                {
                    break;
                }
            }

            level.Clear();
        }