Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Add comments & docstrings related to call_for_nodes #642

Merged
merged 11 commits into from
Jan 4, 2023
7 changes: 6 additions & 1 deletion rope/base/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ def parse(source, filename="<string>", *args, **kwargs): # type: ignore


def call_for_nodes(node, callback):
"""If callback returns `True` the child nodes are skipped"""
"""
A full preorder traversal when `bool(callback(node))` is *always* `False`.

A limited preorder traversal when `bool(callback(node)` is sometimes `True`.
See _ResultChecker._find_node for an example.
"""
lieryan marked this conversation as resolved.
Show resolved Hide resolved
result = callback(node)
if not result:
for child in ast.iter_child_nodes(node):
Expand Down
2 changes: 2 additions & 0 deletions rope/refactor/similarfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ def __init__(self, body, pattern, does_match):
def find_matches(self):
if self.matches is None:
self.matches = []
# _check_nodes always returns None, so
# call_for_nodes traverses self.body's entire tree.
ast.call_for_nodes(self.body, self._check_node)
return self.matches

Expand Down
15 changes: 15 additions & 0 deletions ropetest/refactor/patchedasttest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,21 @@ def check_region(self, text, start, end):
self.test_case.assertEqual((start, end), node.region)

def _find_node(self, text):
"""Find the **outer-most last match** in self.ast.

For example, given the goal:

${var1} + ${var2}

and given the text:

(a + b) + (c + (d + e))

the outermost last match would be:

(c + (d + e))

"""
lieryan marked this conversation as resolved.
Show resolved Hide resolved
goal = text
if not isinstance(text, (tuple, list)):
goal = [text]
Expand Down