Implement a convenience recursive walk method over a cursor and its descendants.

Before r160106 there was a way to recursively visit all descendants of a cursor
via Cursor_visit, but it was removed. Since then, every user needs to
reimplement the recursive descent into get_children.

Adding a walk_preorder() method to Cursor that conveniently implements recursive
walking in a Pythonic way. This also greatly simplifies get_cursor and
get_cursors in tests/cindex/util.py (walk_preorder is now tested through these
utility functions, since they are used in many tests).

llvm-svn: 209793
This commit is contained in:
Eli Bendersky 2014-05-29 02:35:27 +00:00
parent f74aae2c2d
commit 086e5816b0
2 changed files with 20 additions and 28 deletions

View File

@ -1391,6 +1391,16 @@ class Cursor(Structure):
children) children)
return iter(children) return iter(children)
def walk_preorder(self):
"""Depth-first preorder walk over the cursor and its descendants.
Yields cursors.
"""
yield self
for child in self.get_children():
for descendant in child.walk_preorder():
yield descendant
def get_tokens(self): def get_tokens(self):
"""Obtain Token instances formulating that compose this Cursor. """Obtain Token instances formulating that compose this Cursor.

View File

@ -39,52 +39,34 @@ def get_cursor(source, spelling):
If the cursor is not found, None is returned. If the cursor is not found, None is returned.
""" """
children = [] # Convenience for calling on a TU.
if isinstance(source, Cursor): root_cursor = source if isinstance(source, Cursor) else source.cursor
children = source.get_children()
else:
# Assume TU
children = source.cursor.get_children()
for cursor in children: for cursor in root_cursor.walk_preorder():
if cursor.spelling == spelling: if cursor.spelling == spelling:
return cursor return cursor
# Recurse into children.
result = get_cursor(cursor, spelling)
if result is not None:
return result
return None return None
def get_cursors(source, spelling): def get_cursors(source, spelling):
"""Obtain all cursors from a source object with a specific spelling. """Obtain all cursors from a source object with a specific spelling.
This provides a convenient search mechanism to find all cursors with specific This provides a convenient search mechanism to find all cursors with
spelling within a source. The first argument can be either a specific spelling within a source. The first argument can be either a
TranslationUnit or Cursor instance. TranslationUnit or Cursor instance.
If no cursors are found, an empty list is returned. If no cursors are found, an empty list is returned.
""" """
cursors = [] # Convenience for calling on a TU.
children = [] root_cursor = source if isinstance(source, Cursor) else source.cursor
if isinstance(source, Cursor):
children = source.get_children()
else:
# Assume TU
children = source.cursor.get_children()
for cursor in children: cursors = []
for cursor in root_cursor.walk_preorder():
if cursor.spelling == spelling: if cursor.spelling == spelling:
cursors.append(cursor) cursors.append(cursor)
# Recurse into children.
cursors.extend(get_cursors(cursor, spelling))
return cursors return cursors
__all__ = [ __all__ = [
'get_cursor', 'get_cursor',