init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
151
.venv/lib/python3.8/site-packages/rope/base/oi/soa.py
Normal file
151
.venv/lib/python3.8/site-packages/rope/base/oi/soa.py
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
import rope.base.ast
|
||||
import rope.base.oi.soi
|
||||
import rope.base.pynames
|
||||
from rope.base import pyobjects, evaluate, astutils, arguments
|
||||
|
||||
|
||||
def analyze_module(pycore, pymodule, should_analyze, search_subscopes, followed_calls):
|
||||
"""Analyze `pymodule` for static object inference
|
||||
|
||||
Analyzes scopes for collecting object information. The analysis
|
||||
starts from inner scopes.
|
||||
|
||||
"""
|
||||
_analyze_node(pycore, pymodule, should_analyze, search_subscopes, followed_calls)
|
||||
|
||||
|
||||
def _analyze_node(pycore, pydefined, should_analyze, search_subscopes, followed_calls):
|
||||
if search_subscopes(pydefined):
|
||||
for scope in pydefined.get_scope().get_scopes():
|
||||
_analyze_node(
|
||||
pycore, scope.pyobject, should_analyze, search_subscopes, followed_calls
|
||||
)
|
||||
if should_analyze(pydefined):
|
||||
new_followed_calls = max(0, followed_calls - 1)
|
||||
return_true = lambda pydefined: True
|
||||
return_false = lambda pydefined: False
|
||||
|
||||
def _follow(pyfunction):
|
||||
_analyze_node(
|
||||
pycore, pyfunction, return_true, return_false, new_followed_calls
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
class SOAVisitor(object):
|
||||
def __init__(self, pycore, pydefined, follow_callback=None):
|
||||
self.pycore = pycore
|
||||
self.pymodule = pydefined.get_module()
|
||||
self.scope = pydefined.get_scope()
|
||||
self.follow = follow_callback
|
||||
|
||||
def _FunctionDef(self, node):
|
||||
pass
|
||||
|
||||
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)
|
||||
primary, pyname = evaluate.eval_node2(self.scope, node.func)
|
||||
if pyname is None:
|
||||
return
|
||||
pyfunction = pyname.get_object()
|
||||
if isinstance(pyfunction, pyobjects.AbstractFunction):
|
||||
args = arguments.create_arguments(primary, pyfunction, node, self.scope)
|
||||
elif isinstance(pyfunction, pyobjects.PyClass):
|
||||
pyclass = pyfunction
|
||||
if "__init__" in pyfunction:
|
||||
pyfunction = pyfunction["__init__"].get_object()
|
||||
pyname = rope.base.pynames.UnboundName(pyobjects.PyObject(pyclass))
|
||||
args = self._args_with_self(primary, pyname, pyfunction, node)
|
||||
elif "__call__" in pyfunction:
|
||||
pyfunction = pyfunction["__call__"].get_object()
|
||||
args = self._args_with_self(primary, pyname, pyfunction, node)
|
||||
else:
|
||||
return
|
||||
self._call(pyfunction, args)
|
||||
|
||||
def _args_with_self(self, primary, self_pyname, pyfunction, node):
|
||||
base_args = arguments.create_arguments(primary, pyfunction, node, self.scope)
|
||||
return arguments.MixedArguments(self_pyname, base_args, self.scope)
|
||||
|
||||
def _call(self, pyfunction, args):
|
||||
if isinstance(pyfunction, pyobjects.PyFunction):
|
||||
if self.follow is not None:
|
||||
before = self._parameter_objects(pyfunction)
|
||||
self.pycore.object_info.function_called(
|
||||
pyfunction, args.get_arguments(pyfunction.get_param_names())
|
||||
)
|
||||
pyfunction._set_parameter_pyobjects(None)
|
||||
if self.follow is not None:
|
||||
after = self._parameter_objects(pyfunction)
|
||||
if after != before:
|
||||
self.follow(pyfunction)
|
||||
# XXX: Maybe we should not call every builtin function
|
||||
if isinstance(pyfunction, rope.base.builtins.BuiltinFunction):
|
||||
pyfunction.get_returned_object(args)
|
||||
|
||||
def _parameter_objects(self, pyfunction):
|
||||
result = []
|
||||
for i in range(len(pyfunction.get_param_names(False))):
|
||||
result.append(pyfunction.get_parameter(i))
|
||||
return result
|
||||
|
||||
def _AnnAssign(self, node):
|
||||
for child in rope.base.ast.get_child_nodes(node):
|
||||
rope.base.ast.walk(child, self)
|
||||
visitor = _SOAAssignVisitor()
|
||||
nodes = []
|
||||
|
||||
rope.base.ast.walk(node.target, visitor)
|
||||
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)
|
||||
visitor = _SOAAssignVisitor()
|
||||
nodes = []
|
||||
for child in node.targets:
|
||||
rope.base.ast.walk(child, visitor)
|
||||
nodes.extend(visitor.nodes)
|
||||
self._evaluate_assign_value(node, nodes)
|
||||
|
||||
def _evaluate_assign_value(self, node, nodes, type_hint=False):
|
||||
for subscript, levels in nodes:
|
||||
instance = evaluate.eval_node(self.scope, subscript.value)
|
||||
args_pynames = [evaluate.eval_node(self.scope, subscript.slice)]
|
||||
value = rope.base.oi.soi._infer_assignment(
|
||||
rope.base.pynames.AssignmentValue(
|
||||
node.value, levels, type_hint=type_hint
|
||||
),
|
||||
self.pymodule,
|
||||
)
|
||||
args_pynames.append(rope.base.pynames.UnboundName(value))
|
||||
if instance is not None and value is not None:
|
||||
pyobject = instance.get_object()
|
||||
if "__setitem__" in pyobject:
|
||||
pyfunction = pyobject["__setitem__"].get_object()
|
||||
args = arguments.ObjectArguments([instance] + args_pynames)
|
||||
self._call(pyfunction, args)
|
||||
# IDEA: handle `__setslice__`, too
|
||||
|
||||
|
||||
class _SOAAssignVisitor(astutils._NodeNameCollector):
|
||||
def __init__(self):
|
||||
super(_SOAAssignVisitor, self).__init__()
|
||||
self.nodes = []
|
||||
|
||||
def _added(self, node, levels):
|
||||
if isinstance(node, rope.base.ast.Subscript) and isinstance(
|
||||
node.slice, (rope.base.ast.Index, rope.base.ast.expr)
|
||||
):
|
||||
self.nodes.append((node, levels))
|
||||
Loading…
Add table
Add a link
Reference in a new issue