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

Remove functions in rope.base.ast that has functionally identical implementation in stdlib's ast #581

Merged
merged 8 commits into from Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,7 @@

- #533 Refactoring to Remove usage of unicode type
- #559 Improve handling of whitespace in import and from-import statements
- #581 Remove functions in rope.base.ast that has functionally identical implementation in stdlib's ast

# Release 1.5.1

Expand Down
44 changes: 7 additions & 37 deletions rope/base/ast.py
Expand Up @@ -22,47 +22,17 @@ def parse(source, filename="<string>"):
raise error


def walk(node, walker) -> None:
"""Walk the syntax tree"""
method_name = "_" + node.__class__.__name__
method = getattr(walker, method_name, None)
if method is not None:
method(node)
return
for child in get_child_nodes(node):
walk(child, walker)


def get_child_nodes(node):
if isinstance(node, ast.Module):
return node.body
result = []
if node._fields is not None:
for name in node._fields:
child = getattr(node, name)
if isinstance(child, list):
for entry in child:
if isinstance(entry, ast.AST):
result.append(entry)
if isinstance(child, ast.AST):
result.append(child)
return result


def call_for_nodes(node, callback, recursive=False):
"""If callback returns `True` the child nodes are skipped"""
result = callback(node)
if recursive and not result:
for child in get_child_nodes(node):
for child in ast.iter_child_nodes(node):
call_for_nodes(child, callback, recursive)


def get_children(node):
result = []
if node._fields is not None:
for name in node._fields:
if name in ["lineno", "col_offset"]:
continue
child = getattr(node, name)
result.append(child)
return result
class RopeNodeVisitor(ast.NodeVisitor):
def visit(self, node):
"""Modified from ast.NodeVisitor to match rope's existing Visitor implementation"""
method = "_" + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
8 changes: 4 additions & 4 deletions rope/base/astutils.py
Expand Up @@ -14,11 +14,11 @@ def get_name_levels(node):

"""
visitor = _NodeNameCollector()
ast.walk(node, visitor)
visitor.visit(node)
return visitor.names


class _NodeNameCollector:
class _NodeNameCollector(ast.RopeNodeVisitor):
def __init__(self, levels=None):
self.names = []
self.levels = levels
Expand Down Expand Up @@ -49,8 +49,8 @@ def _Tuple(self, node):
new_levels.append(self.index)
self.index += 1
visitor = _NodeNameCollector(new_levels)
for child in ast.get_child_nodes(node):
ast.walk(child, visitor)
for child in ast.iter_child_nodes(node):
visitor.visit(child)
self.names.extend(visitor.names)

def _Subscript(self, node):
Expand Down
4 changes: 2 additions & 2 deletions rope/base/evaluate.py
Expand Up @@ -39,7 +39,7 @@ def eval_node(scope, node):

def eval_node2(scope, node):
evaluator = StatementEvaluator(scope)
ast.walk(node, evaluator)
evaluator.visit(node)
return evaluator.old_result, evaluator.result


Expand Down Expand Up @@ -158,7 +158,7 @@ def _find_module(self, module_name):
)


class StatementEvaluator:
class StatementEvaluator(ast.RopeNodeVisitor):
def __init__(self, scope):
self.scope = scope
self.result = None
Expand Down
22 changes: 11 additions & 11 deletions rope/base/oi/soa.py
Expand Up @@ -33,11 +33,11 @@ def _follow(pyfunction):
if not followed_calls:
_follow = None
visitor = SOAVisitor(pycore, pydefined, _follow)
for child in rope.base.ast.get_child_nodes(pydefined.get_ast()):
rope.base.ast.walk(child, visitor)
for child in rope.base.ast.iter_child_nodes(pydefined.get_ast()):
visitor.visit(child)


class SOAVisitor:
class SOAVisitor(rope.base.ast.RopeNodeVisitor):
def __init__(self, pycore, pydefined, follow_callback=None):
self.pycore = pycore
self.pymodule = pydefined.get_module()
Expand All @@ -51,8 +51,8 @@ def _ClassDef(self, node):
pass

def _Call(self, node):
for child in rope.base.ast.get_child_nodes(node):
rope.base.ast.walk(child, self)
for child in rope.base.ast.iter_child_nodes(node):
self.visit(child)
primary, pyname = evaluate.eval_node2(self.scope, node.func)
if pyname is None:
return
Expand Down Expand Up @@ -99,23 +99,23 @@ def _parameter_objects(self, pyfunction):
]

def _AnnAssign(self, node):
for child in rope.base.ast.get_child_nodes(node):
rope.base.ast.walk(child, self)
for child in rope.base.ast.iter_child_nodes(node):
self.visit(child)
visitor = _SOAAssignVisitor()
nodes = []

rope.base.ast.walk(node.target, visitor)
visitor.visit(node.target)
nodes.extend(visitor.nodes)

self._evaluate_assign_value(node, nodes, type_hint=node.annotation)

def _Assign(self, node):
for child in rope.base.ast.get_child_nodes(node):
rope.base.ast.walk(child, self)
for child in rope.base.ast.iter_child_nodes(node):
self.visit(child)
visitor = _SOAAssignVisitor()
nodes = []
for child in node.targets:
rope.base.ast.walk(child, visitor)
visitor.visit(child)
nodes.extend(visitor.nodes)
self._evaluate_assign_value(node, nodes)

Expand Down
4 changes: 2 additions & 2 deletions rope/base/pyobjects.py
Expand Up @@ -243,8 +243,8 @@ def _create_structural_attributes(self):
if self.visitor_class is None:
return {}
new_visitor = self.visitor_class(self.pycore, self)
for child in ast.get_child_nodes(self.ast_node):
ast.walk(child, new_visitor)
for child in ast.iter_child_nodes(self.ast_node):
new_visitor.visit(child)
self.defineds = new_visitor.defineds
return new_visitor.names

Expand Down
38 changes: 19 additions & 19 deletions rope/base/pyobjectsdef.py
Expand Up @@ -291,7 +291,7 @@ def get_name(self):
return rope.base.libutils.modname(self.resource) if self.resource else ""


class _AnnAssignVisitor:
class _AnnAssignVisitor(ast.RopeNodeVisitor):
def __init__(self, scope_visitor):
self.scope_visitor = scope_visitor
self.assigned_ast = None
Expand All @@ -301,7 +301,7 @@ def _AnnAssign(self, node):
self.assigned_ast = node.value
self.type_hint = node.annotation

ast.walk(node.target, self)
self.visit(node.target)

def _assigned(self, name, assignment=None):
self.scope_visitor._assigned(name, assignment)
Expand Down Expand Up @@ -333,7 +333,7 @@ def _Slice(self, node):
pass


class _ExpressionVisitor:
class _ExpressionVisitor(ast.RopeNodeVisitor):
def __init__(self, scope_visitor):
self.scope_visitor = scope_visitor

Expand All @@ -356,20 +356,20 @@ def _DictComp(self, node):
self._GeneratorExp(node)

def _NamedExpr(self, node):
ast.walk(node.target, _AssignVisitor(self))
ast.walk(node.value, self)
_AssignVisitor(self).visit(node.target)
self.visit(node.value)


class _AssignVisitor:
class _AssignVisitor(ast.RopeNodeVisitor):
def __init__(self, scope_visitor):
self.scope_visitor = scope_visitor
self.assigned_ast = None

def _Assign(self, node):
self.assigned_ast = node.value
for child_node in node.targets:
ast.walk(child_node, self)
ast.walk(node.value, _ExpressionVisitor(self.scope_visitor))
self.visit(child_node)
_ExpressionVisitor(self.scope_visitor).visit(node.value)

def _assigned(self, name, assignment=None):
self.scope_visitor._assigned(name, assignment)
Expand Down Expand Up @@ -446,18 +446,18 @@ def _AsyncFunctionDef(self, node):
return self._FunctionDef(node)

def _Assign(self, node):
ast.walk(node, _AssignVisitor(self))
_AssignVisitor(self).visit(node)

def _AnnAssign(self, node):
ast.walk(node, _AnnAssignVisitor(self))
_AnnAssignVisitor(self).visit(node)

def _AugAssign(self, node):
pass

def _For(self, node):
self._update_evaluated(node.target, node.iter, ".__iter__().next()")
for child in node.body + node.orelse:
ast.walk(child, self)
self.visit(child)

def _AsyncFor(self, node):
return self._For(node)
Expand Down Expand Up @@ -494,7 +494,7 @@ def _With(self, node):
item.optional_vars, item.context_expr, ".__enter__()"
)
for child in node.body:
ast.walk(child, self)
self.visit(child)

def _AsyncWith(self, node):
return self._With(node)
Expand All @@ -508,7 +508,7 @@ def _excepthandler(self, node):
self._update_evaluated(node.name, type_node, eval_type=True)

for child in node.body:
ast.walk(child, self)
self.visit(child)

def _ExceptHandler(self, node):
self._excepthandler(node)
Expand Down Expand Up @@ -571,8 +571,8 @@ def _Global(self, node):

class _ComprehensionVisitor(_ScopeVisitor):
def _comprehension(self, node):
ast.walk(node.target, self)
ast.walk(node.iter, self)
self.visit(node.target)
self.visit(node.iter)

def _Name(self, node):
if isinstance(node.ctx, ast.Store):
Expand All @@ -599,8 +599,8 @@ def _FunctionDef(self, node):
if isinstance(first, ast.arg):
new_visitor = _ClassInitVisitor(self, first.arg)
if new_visitor is not None:
for child in ast.get_child_nodes(node):
ast.walk(child, new_visitor)
for child in ast.iter_child_nodes(node):
new_visitor.visit(child)


class _FunctionVisitor(_ScopeVisitor):
Expand Down Expand Up @@ -642,8 +642,8 @@ def _Attribute(self, node):
def _Tuple(self, node):
if not isinstance(node.ctx, ast.Store):
return
for child in ast.get_child_nodes(node):
ast.walk(child, self)
for child in ast.iter_child_nodes(node):
self.visit(child)

def _Name(self, node):
pass
Expand Down
8 changes: 4 additions & 4 deletions rope/base/pyscopes.py
Expand Up @@ -186,8 +186,8 @@ def get_names(self):
def _visit_comprehension(self):
if self.names is None:
new_visitor = self.visitor(self.pycore, self.pyobject)
for node in ast.get_child_nodes(self.pyobject.get_ast()):
ast.walk(node, new_visitor)
for node in ast.iter_child_nodes(self.pyobject.get_ast()):
new_visitor.visit(node)
self.names = dict(self.parent.get_names())
self.names.update(new_visitor.names)
self.defineds = new_visitor.defineds
Expand Down Expand Up @@ -218,8 +218,8 @@ def _get_names(self):
def _visit_function(self):
if self.names is None:
new_visitor = self.visitor(self.pycore, self.pyobject)
for n in ast.get_child_nodes(self.pyobject.get_ast()):
ast.walk(n, new_visitor)
for n in ast.iter_child_nodes(self.pyobject.get_ast()):
new_visitor.visit(n)
self.names = new_visitor.names
self.names.update(self.pyobject.get_parameters())
self.returned_asts = new_visitor.returned_asts
Expand Down
6 changes: 3 additions & 3 deletions rope/contrib/finderrors.py
Expand Up @@ -33,11 +33,11 @@ def find_errors(project, resource):
"""
pymodule = project.get_pymodule(resource)
finder = _BadAccessFinder(pymodule)
ast.walk(pymodule.get_ast(), finder)
finder.visit(pymodule.get_ast())
return finder.errors


class _BadAccessFinder:
class _BadAccessFinder(ast.RopeNodeVisitor):
def __init__(self, pymodule):
self.pymodule = pymodule
self.scope = pymodule.get_scope()
Expand All @@ -60,7 +60,7 @@ def _Attribute(self, node):
if pyname is not None and pyname.get_object() != pyobjects.get_unknown():
if node.attr not in pyname.get_object():
self._add_error(node, "Unresolved attribute")
ast.walk(node.value, self)
self.visit(node.value)

def _add_error(self, node, msg):
if isinstance(node, ast.Attribute):
Expand Down