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(); }