11from abc import ABCMeta , abstractmethod
22
3- from collections import namedtuple , deque
3+ from collections import deque
44from collections .abc import Iterator
5- from typing import Any
5+ from typing import Any , NamedTuple
66
77from .errors import CircularReferencing
88from .nodes .node import Node
99from .nodes .references import Reference , TypeReference
1010from .syntax_tree import SyntaxTree
1111
1212
13+ class BfsAttr (NamedTuple ):
14+ distance : int
15+
16+
17+ class DfsAttr (NamedTuple ):
18+ pass
19+
20+
21+ class _DfsState (NamedTuple ):
22+ node : Node
23+ processed : bool
24+
25+
1326class _Traversal (metaclass = ABCMeta ):
1427 def __init__ (self , tree : SyntaxTree | Node ) -> None :
1528 self ._root : Node = tree .root
@@ -25,16 +38,14 @@ def iterate(self) -> Iterator[tuple[Node, Any]]:
2538
2639
2740class BfsTraversal (_Traversal ):
28- def iterate (self ) -> Iterator [tuple [Node , Any ]]:
29- Attr = namedtuple ("Attr" , ["distance" ])
30-
41+ def iterate (self ) -> Iterator [tuple [Node , BfsAttr ]]:
3142 queue : deque [tuple [Node , int ]] = deque ([(self ._root , 0 )])
3243 processed : set [Node ] = set ()
3344 while queue :
3445 node , distance = queue .popleft ()
3546 if node in processed :
3647 continue
37- yield node , Attr (distance = distance )
48+ yield node , BfsAttr (distance = distance )
3849 # We want to preserve original order if possible, and traverse
3950 # children in *original* order: That way they are popped in order
4051 for child in _Traversal .children (node ):
@@ -47,10 +58,8 @@ class DfsTraversal(_Traversal):
4758 _PROCESS_NODE_EARLY = 0
4859 _PROCESS_NODE_LATE = 1
4960
50- def _iterate (self ) -> Iterator [tuple [int , Node , Any ]]:
51- State = namedtuple ("State" , ["node" , "processed" ])
52- Attr = namedtuple ("Attr" , [])
53- stack = [State (node = self ._root , processed = False )]
61+ def _iterate (self ) -> Iterator [tuple [int , Node , DfsAttr ]]:
62+ stack = [_DfsState (node = self ._root , processed = False )]
5463 discovered : set [Node ] = set ()
5564 processed : set [Node ] = set ()
5665
@@ -60,27 +69,27 @@ def _iterate(self) -> Iterator[tuple[int, Node, Any]]:
6069 if node in processed :
6170 continue
6271
63- yield self ._PROCESS_NODE_EARLY , node , Attr ()
72+ yield self ._PROCESS_NODE_EARLY , node , DfsAttr ()
6473 discovered .add (node )
65- stack .append (State (node = node , processed = True ))
74+ stack .append (_DfsState (node = node , processed = True ))
6675
6776 # We want to preserve original order if possible, and traverse
6877 # children in *reverse* order: That way they are popped in order
6978 for child in reversed (_Traversal .children (node )):
7079 if child not in discovered and child not in processed :
71- stack .append (State (node = child , processed = False ))
80+ stack .append (_DfsState (node = child , processed = False ))
7281 elif child not in processed :
7382 raise CircularReferencing (node , child )
7483 else :
75- yield self ._PROCESS_NODE_LATE , node , Attr ()
84+ yield self ._PROCESS_NODE_LATE , node , DfsAttr ()
7685 processed .add (node )
7786
78- def iterate (self ) -> Iterator [tuple [Node , Any ]]:
87+ def iterate (self ) -> Iterator [tuple [Node , DfsAttr ]]:
7988 for event , node , attr in self ._iterate ():
8089 if event == self ._PROCESS_NODE_EARLY :
8190 yield node , attr
8291
83- def dependency_order (self ) -> Iterator [tuple [Node , Any ]]:
92+ def dependency_order (self ) -> Iterator [tuple [Node , DfsAttr ]]:
8493 for event , node , attr in self ._iterate ():
8594 if event == self ._PROCESS_NODE_LATE :
8695 yield node , attr
0 commit comments