Commit 44b5b0d1 authored by Stefan Behnel's avatar Stefan Behnel

Move the option to "exclude" children from the tree traversal from the...

Move the option to "exclude" children from the tree traversal from the "VisitorTransform" class up to its parent "TreeVisitor" class.
parent 36e918fc
...@@ -661,7 +661,7 @@ class AssignmentCollector(TreeVisitor): ...@@ -661,7 +661,7 @@ class AssignmentCollector(TreeVisitor):
self.assignments = [] self.assignments = []
def visit_Node(self): def visit_Node(self):
self._visitchildren(self, None) self._visitchildren(self, None, None)
def visit_SingleAssignmentNode(self, node): def visit_SingleAssignmentNode(self, node):
self.assignments.append((node.lhs, node.rhs)) self.assignments.append((node.lhs, node.rhs))
......
...@@ -10,15 +10,14 @@ cdef class TreeVisitor: ...@@ -10,15 +10,14 @@ cdef class TreeVisitor:
cdef _visit(self, obj) cdef _visit(self, obj)
cdef find_handler(self, obj) cdef find_handler(self, obj)
cdef _visitchild(self, child, parent, attrname, idx) cdef _visitchild(self, child, parent, attrname, idx)
cdef dict _visitchildren(self, parent, attrs) cdef dict _visitchildren(self, parent, attrs, exclude)
cpdef visitchildren(self, parent, attrs=*) cpdef visitchildren(self, parent, attrs=*, exclude=*)
cdef _raise_compiler_error(self, child, e) cdef _raise_compiler_error(self, child, e)
cdef class VisitorTransform(TreeVisitor): cdef class VisitorTransform(TreeVisitor):
cdef dict _process_children(self, parent, attrs=*) cdef dict _process_children(self, parent, attrs=*, exclude=*)
cpdef visitchildren(self, parent, attrs=*, exclude=*) cpdef visitchildren(self, parent, attrs=*, exclude=*)
cdef list _flatten_list(self, list orig_list) cdef list _flatten_list(self, list orig_list)
cdef list _select_attrs(self, attrs, exclude)
cpdef visitchild(self, parent, str attr, idx=*) cpdef visitchild(self, parent, str attr, idx=*)
cdef class CythonTransform(VisitorTransform): cdef class CythonTransform(VisitorTransform):
......
...@@ -167,10 +167,12 @@ class TreeVisitor(object): ...@@ -167,10 +167,12 @@ class TreeVisitor(object):
raise RuntimeError("Visitor %r does not accept object: %s" % (self, obj)) raise RuntimeError("Visitor %r does not accept object: %s" % (self, obj))
def visit(self, obj): def visit(self, obj):
# generic def entry point for calls from Python subclasses
return self._visit(obj) return self._visit(obj)
@cython.final @cython.final
def _visit(self, obj): def _visit(self, obj):
# fast cdef entry point for calls from Cython subclasses
try: try:
try: try:
handler_method = self.dispatch_table[type(obj)] handler_method = self.dispatch_table[type(obj)]
...@@ -189,17 +191,20 @@ class TreeVisitor(object): ...@@ -189,17 +191,20 @@ class TreeVisitor(object):
@cython.final @cython.final
def _visitchild(self, child, parent, attrname, idx): def _visitchild(self, child, parent, attrname, idx):
# fast cdef entry point for calls from Cython subclasses
self.access_path.append((parent, attrname, idx)) self.access_path.append((parent, attrname, idx))
result = self._visit(child) result = self._visit(child)
self.access_path.pop() self.access_path.pop()
return result return result
def visitchildren(self, parent, attrs=None): def visitchildren(self, parent, attrs=None, exclude=None):
return self._visitchildren(parent, attrs) # generic def entry point for calls from Python subclasses
return self._visitchildren(parent, attrs, exclude)
@cython.final @cython.final
@cython.locals(idx=cython.Py_ssize_t) @cython.locals(idx=cython.Py_ssize_t)
def _visitchildren(self, parent, attrs): def _visitchildren(self, parent, attrs, exclude):
# fast cdef entry point for calls from Cython subclasses
""" """
Visits the children of the given parent. If parent is None, returns Visits the children of the given parent. If parent is None, returns
immediately (returning None). immediately (returning None).
...@@ -213,6 +218,7 @@ class TreeVisitor(object): ...@@ -213,6 +218,7 @@ class TreeVisitor(object):
result = {} result = {}
for attr in parent.child_attrs: for attr in parent.child_attrs:
if attrs is not None and attr not in attrs: continue if attrs is not None and attr not in attrs: continue
if exclude is not None and attr in exclude: continue
child = getattr(parent, attr) child = getattr(parent, attr)
if child is not None: if child is not None:
if type(child) is list: if type(child) is list:
...@@ -246,18 +252,12 @@ class VisitorTransform(TreeVisitor): ...@@ -246,18 +252,12 @@ class VisitorTransform(TreeVisitor):
""" """
def visitchildren(self, parent, attrs=None, exclude=None): def visitchildren(self, parent, attrs=None, exclude=None):
# generic def entry point for calls from Python subclasses # generic def entry point for calls from Python subclasses
if exclude is not None: return self._process_children(parent, attrs, exclude)
attrs = self._select_attrs(parent.child_attrs if attrs is None else attrs, exclude)
return self._process_children(parent, attrs)
@cython.final
def _select_attrs(self, attrs, exclude):
return [name for name in attrs if name not in exclude]
@cython.final @cython.final
def _process_children(self, parent, attrs=None): def _process_children(self, parent, attrs=None, exclude=None):
# fast cdef entry point for calls from Cython subclasses # fast cdef entry point for calls from Cython subclasses
result = self._visitchildren(parent, attrs) result = self._visitchildren(parent, attrs, exclude)
for attr, newnode in result.items(): for attr, newnode in result.items():
if type(newnode) is list: if type(newnode) is list:
newnode = self._flatten_list(newnode) newnode = self._flatten_list(newnode)
...@@ -756,7 +756,7 @@ class NodeFinder(TreeVisitor): ...@@ -756,7 +756,7 @@ class NodeFinder(TreeVisitor):
elif node is self.node: elif node is self.node:
self.found = True self.found = True
else: else:
self._visitchildren(node, None) self._visitchildren(node, None, None)
def tree_contains(tree, node): def tree_contains(tree, node):
finder = NodeFinder(node) finder = NodeFinder(node)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment