init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
231
.venv/lib/python3.8/site-packages/rope/base/oi/soi.py
Normal file
231
.venv/lib/python3.8/site-packages/rope/base/oi/soi.py
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
"""A module for inferring objects
|
||||
|
||||
For more information see the documentation in `rope.base.oi`
|
||||
package.
|
||||
|
||||
"""
|
||||
import rope.base.builtins
|
||||
import rope.base.pynames
|
||||
import rope.base.pyobjects
|
||||
from rope.base import evaluate, utils, arguments
|
||||
from rope.base.oi.type_hinting.factory import get_type_hinting_factory
|
||||
|
||||
|
||||
_ignore_inferred = utils.ignore_exception(rope.base.pyobjects.IsBeingInferredError)
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def infer_returned_object(pyfunction, args):
|
||||
"""Infer the `PyObject` this `PyFunction` returns after calling"""
|
||||
object_info = pyfunction.pycore.object_info
|
||||
result = object_info.get_exact_returned(pyfunction, args)
|
||||
if result is not None:
|
||||
return result
|
||||
result = _infer_returned(pyfunction, args)
|
||||
if result is not None:
|
||||
if args and pyfunction.get_module().get_resource() is not None:
|
||||
params = args.get_arguments(pyfunction.get_param_names(special_args=False))
|
||||
object_info.function_called(pyfunction, params, result)
|
||||
return result
|
||||
result = object_info.get_returned(pyfunction, args)
|
||||
if result is not None:
|
||||
return result
|
||||
hint_return = get_type_hinting_factory(
|
||||
pyfunction.pycore.project
|
||||
).make_return_provider()
|
||||
type_ = hint_return(pyfunction)
|
||||
if type_ is not None:
|
||||
return rope.base.pyobjects.PyObject(type_)
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def infer_parameter_objects(pyfunction):
|
||||
"""Infer the `PyObject` of parameters of this `PyFunction`"""
|
||||
object_info = pyfunction.pycore.object_info
|
||||
result = object_info.get_parameter_objects(pyfunction)
|
||||
if result is None:
|
||||
result = _parameter_objects(pyfunction)
|
||||
_handle_first_parameter(pyfunction, result)
|
||||
return result
|
||||
|
||||
|
||||
def _handle_first_parameter(pyobject, parameters):
|
||||
kind = pyobject.get_kind()
|
||||
if parameters is None or kind not in ["method", "classmethod"]:
|
||||
pass
|
||||
if not parameters:
|
||||
if not pyobject.get_param_names(special_args=False):
|
||||
return
|
||||
parameters.append(rope.base.pyobjects.get_unknown())
|
||||
if kind == "method":
|
||||
parameters[0] = rope.base.pyobjects.PyObject(pyobject.parent)
|
||||
if kind == "classmethod":
|
||||
parameters[0] = pyobject.parent
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def infer_assigned_object(pyname):
|
||||
if not pyname.assignments:
|
||||
return
|
||||
for assignment in reversed(pyname.assignments):
|
||||
result = _infer_assignment(assignment, pyname.module)
|
||||
if (
|
||||
isinstance(result, rope.base.builtins.BuiltinUnknown)
|
||||
and result.get_name() == "NotImplementedType"
|
||||
):
|
||||
break
|
||||
elif result == rope.base.pyobjects.get_unknown():
|
||||
break
|
||||
elif result is not None:
|
||||
return result
|
||||
|
||||
hint_assignment = get_type_hinting_factory(
|
||||
pyname.module.pycore.project
|
||||
).make_assignment_provider()
|
||||
hinting_result = hint_assignment(pyname)
|
||||
if hinting_result is not None:
|
||||
return rope.base.pyobjects.PyObject(hinting_result)
|
||||
return result
|
||||
|
||||
|
||||
def get_passed_objects(pyfunction, parameter_index):
|
||||
object_info = pyfunction.pycore.object_info
|
||||
result = object_info.get_passed_objects(pyfunction, parameter_index)
|
||||
if not result:
|
||||
statically_inferred = _parameter_objects(pyfunction)
|
||||
if len(statically_inferred) > parameter_index:
|
||||
result.append(statically_inferred[parameter_index])
|
||||
return result
|
||||
|
||||
|
||||
def _infer_returned(pyobject, args):
|
||||
if args:
|
||||
# HACK: Setting parameter objects manually
|
||||
# This is not thread safe and might cause problems if `args`
|
||||
# does not come from a good call site
|
||||
pyobject.get_scope().invalidate_data()
|
||||
pyobject._set_parameter_pyobjects(
|
||||
args.get_arguments(pyobject.get_param_names(special_args=False))
|
||||
)
|
||||
scope = pyobject.get_scope()
|
||||
if not scope._get_returned_asts():
|
||||
return
|
||||
maxtries = 3
|
||||
for returned_node in reversed(scope._get_returned_asts()[-maxtries:]):
|
||||
try:
|
||||
resulting_pyname = evaluate.eval_node(scope, returned_node)
|
||||
if resulting_pyname is None:
|
||||
continue
|
||||
pyobject = resulting_pyname.get_object()
|
||||
if pyobject == rope.base.pyobjects.get_unknown():
|
||||
continue
|
||||
if not scope._is_generator():
|
||||
return pyobject
|
||||
else:
|
||||
return rope.base.builtins.get_generator(pyobject)
|
||||
except rope.base.pyobjects.IsBeingInferredError:
|
||||
pass
|
||||
|
||||
|
||||
def _parameter_objects(pyobject):
|
||||
result = []
|
||||
params = pyobject.get_param_names(special_args=False)
|
||||
hint_param = get_type_hinting_factory(pyobject.pycore.project).make_param_provider()
|
||||
for name in params:
|
||||
type_ = hint_param(pyobject, name)
|
||||
if type_ is not None:
|
||||
result.append(rope.base.pyobjects.PyObject(type_))
|
||||
else:
|
||||
result.append(rope.base.pyobjects.get_unknown())
|
||||
return result
|
||||
|
||||
|
||||
# handling `rope.base.pynames.AssignmentValue`
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def _infer_assignment(assignment, pymodule):
|
||||
result = _follow_pyname(assignment, pymodule)
|
||||
if result is None:
|
||||
return None
|
||||
pyname, pyobject = result
|
||||
pyobject = _follow_evaluations(assignment, pyname, pyobject)
|
||||
if pyobject is None:
|
||||
return None
|
||||
return _follow_levels(assignment, pyobject)
|
||||
|
||||
|
||||
def _follow_levels(assignment, pyobject):
|
||||
for index in assignment.levels:
|
||||
if isinstance(pyobject.get_type(), rope.base.builtins.Tuple):
|
||||
holdings = pyobject.get_type().get_holding_objects()
|
||||
if holdings:
|
||||
pyobject = holdings[min(len(holdings) - 1, index)]
|
||||
else:
|
||||
pyobject = None
|
||||
elif isinstance(pyobject.get_type(), rope.base.builtins.List):
|
||||
pyobject = pyobject.get_type().holding
|
||||
else:
|
||||
pyobject = None
|
||||
if pyobject is None:
|
||||
break
|
||||
return pyobject
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def _follow_pyname(assignment, pymodule, lineno=None):
|
||||
assign_node = assignment.type_hint or assignment.ast_node
|
||||
if lineno is None:
|
||||
lineno = _get_lineno_for_node(assign_node)
|
||||
holding_scope = pymodule.get_scope().get_inner_scope_for_line(lineno)
|
||||
pyname = evaluate.eval_node(holding_scope, assign_node)
|
||||
if pyname is not None:
|
||||
result = pyname.get_object()
|
||||
if (
|
||||
isinstance(result.get_type(), rope.base.builtins.Property)
|
||||
and holding_scope.get_kind() == "Class"
|
||||
):
|
||||
arg = rope.base.pynames.UnboundName(
|
||||
rope.base.pyobjects.PyObject(holding_scope.pyobject)
|
||||
)
|
||||
return pyname, result.get_type().get_property_object(
|
||||
arguments.ObjectArguments([arg])
|
||||
)
|
||||
return pyname, result
|
||||
|
||||
|
||||
@_ignore_inferred
|
||||
def _follow_evaluations(assignment, pyname, pyobject):
|
||||
new_pyname = pyname
|
||||
tokens = assignment.evaluation.split(".")
|
||||
for token in tokens:
|
||||
call = token.endswith("()")
|
||||
if call:
|
||||
token = token[:-2]
|
||||
if token:
|
||||
pyname = new_pyname
|
||||
new_pyname = _get_attribute(pyobject, token)
|
||||
if new_pyname is not None:
|
||||
pyobject = new_pyname.get_object()
|
||||
if pyobject is not None and call:
|
||||
if isinstance(pyobject, rope.base.pyobjects.AbstractFunction):
|
||||
args = arguments.ObjectArguments([pyname])
|
||||
pyobject = pyobject.get_returned_object(args)
|
||||
else:
|
||||
pyobject = None
|
||||
if pyobject is None:
|
||||
break
|
||||
if pyobject is not None and assignment.assign_type:
|
||||
return rope.base.pyobjects.PyObject(pyobject)
|
||||
return pyobject
|
||||
|
||||
|
||||
def _get_lineno_for_node(assign_node):
|
||||
if hasattr(assign_node, "lineno") and assign_node.lineno is not None:
|
||||
return assign_node.lineno
|
||||
return 1
|
||||
|
||||
|
||||
def _get_attribute(pyobject, name):
|
||||
if pyobject is not None and name in pyobject:
|
||||
return pyobject[name]
|
||||
Loading…
Add table
Add a link
Reference in a new issue