Skip to content

Commit

Permalink
Merge pull request #581 from python-rope/lieryan-rope-base-ast-2
Browse files Browse the repository at this point in the history
Remove functions in rope.base.ast that has functionally identical implementation in stdlib's ast
  • Loading branch information
lieryan committed Dec 9, 2022
2 parents 74a937d + 722eaea commit c0bec17
Show file tree
Hide file tree
Showing 16 changed files with 102 additions and 129 deletions.
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

0 comments on commit c0bec17

Please sign in to comment.