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)
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):
"""Obtain Token instances formulating that compose this Cursor.

View File

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