You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Inspired by the Python bindings for libclang, we can provide an iterator-based API to walk through specialization trees.
As a simple example, this would allow us to replace the entire TreePrinter class with a loop like:
fornodeintree.walk():
print(node)
Request attributes
Would this be a refactor of existing code?
Does this proposal require new package dependencies?
Would this change break backwards compatibility?
Related issues
No response
Solution description
Add iterator methods to SourceTree.
Refactor all usage of "walker" classes to use the new iterator-based API.
Remove all the "walker" classes.
Additional notes
If it becomes apparent during the refactoring process that some of our existing "walkers" need a visitor pattern, we should also expose a dedicated visit(Visitor) interface that does not require users of the tree to implement their own recursive tree traversal.
The text was updated successfully, but these errors were encountered:
It turns out that we do need a visitor approach to complement the simple walk() function.
@laserkelvin, I've been working on this recently and I have what I think is quite an elegant solution. But there's an open design question that I'd like your feedback on before I finalize the implementation and open a pull request.
The basic idea is to have a visit function that accepts any callable, and then invoke that callable on every node in the tree. For very simple cases the callable can be a lambda or a function, and for more complicated cases (that require state) you can use an object.
For example, the following could be used to count all the nodes in the tree:
classNodeCounter:
def__init__(self):
self.count=0def__call__(self, node):
self.count+=1returnTrue# see belowvisitor=NodeCounter()
tree.visit(visitor)
print(visitor.count)
The return True is the bit I'm unsure about. What it currently means is "visit the children of this node", but it doesn't feel obvious and I can imagine people wanting slightly different use-cases (e.g., "don't visit any more nodes at all", "skip the children of this node", "return to the parent of this node", etc).
My proposal is to change the return handling such that:
None (or no return statement at all) => Visit the next node.
Visit.NEXT => Same as above.
Visit.NEXT_SIBLING => Don't process this node's children, and skip to its next sibling.
None or Visit.NEXT would be equivalent to returning True in the current implementation, while Visit.NEXT_SIBLING would be equivalent to returning False in the current implementation. I think that explicit values would be more readable, and we can extend things later if we decide we need to support more patterns.
Feature/behavior summary
Inspired by the Python bindings for
libclang
, we can provide an iterator-based API to walk through specialization trees.As a simple example, this would allow us to replace the entire
TreePrinter
class with a loop like:Request attributes
Related issues
No response
Solution description
SourceTree
.Additional notes
If it becomes apparent during the refactoring process that some of our existing "walkers" need a visitor pattern, we should also expose a dedicated
visit(Visitor)
interface that does not require users of the tree to implement their own recursive tree traversal.The text was updated successfully, but these errors were encountered: