111 lines
3.2 KiB
Python
111 lines
3.2 KiB
Python
import rope.base.evaluate
|
|
from rope.base import ast
|
|
|
|
|
|
class Arguments(object):
|
|
"""A class for evaluating parameters passed to a function
|
|
|
|
You can use the `create_arguments` factory. It handles implicit
|
|
first arguments.
|
|
|
|
"""
|
|
|
|
def __init__(self, args, scope):
|
|
self.args = args
|
|
self.scope = scope
|
|
self.instance = None
|
|
|
|
def get_arguments(self, parameters):
|
|
result = []
|
|
for pyname in self.get_pynames(parameters):
|
|
if pyname is None:
|
|
result.append(None)
|
|
else:
|
|
result.append(pyname.get_object())
|
|
return result
|
|
|
|
def get_pynames(self, parameters):
|
|
result = [None] * max(len(parameters), len(self.args))
|
|
for index, arg in enumerate(self.args):
|
|
if isinstance(arg, ast.keyword) and arg.arg in parameters:
|
|
result[parameters.index(arg.arg)] = self._evaluate(arg.value)
|
|
else:
|
|
result[index] = self._evaluate(arg)
|
|
return result
|
|
|
|
def get_instance_pyname(self):
|
|
if self.args:
|
|
return self._evaluate(self.args[0])
|
|
|
|
def _evaluate(self, ast_node):
|
|
return rope.base.evaluate.eval_node(self.scope, ast_node)
|
|
|
|
|
|
def create_arguments(primary, pyfunction, call_node, scope):
|
|
"""A factory for creating `Arguments`"""
|
|
args = list(call_node.args)
|
|
args.extend(call_node.keywords)
|
|
called = call_node.func
|
|
# XXX: Handle constructors
|
|
if _is_method_call(primary, pyfunction) and isinstance(called, ast.Attribute):
|
|
args.insert(0, called.value)
|
|
return Arguments(args, scope)
|
|
|
|
|
|
class ObjectArguments(object):
|
|
def __init__(self, pynames):
|
|
self.pynames = pynames
|
|
|
|
def get_arguments(self, parameters):
|
|
result = []
|
|
for pyname in self.pynames:
|
|
if pyname is None:
|
|
result.append(None)
|
|
else:
|
|
result.append(pyname.get_object())
|
|
return result
|
|
|
|
def get_pynames(self, parameters):
|
|
return self.pynames
|
|
|
|
def get_instance_pyname(self):
|
|
return self.pynames[0]
|
|
|
|
|
|
class MixedArguments(object):
|
|
def __init__(self, pyname, arguments, scope):
|
|
"""`argumens` is an instance of `Arguments`"""
|
|
self.pyname = pyname
|
|
self.args = arguments
|
|
|
|
def get_pynames(self, parameters):
|
|
return [self.pyname] + self.args.get_pynames(parameters[1:])
|
|
|
|
def get_arguments(self, parameters):
|
|
result = []
|
|
for pyname in self.get_pynames(parameters):
|
|
if pyname is None:
|
|
result.append(None)
|
|
else:
|
|
result.append(pyname.get_object())
|
|
return result
|
|
|
|
def get_instance_pyname(self):
|
|
return self.pyname
|
|
|
|
|
|
def _is_method_call(primary, pyfunction):
|
|
if primary is None:
|
|
return False
|
|
pyobject = primary.get_object()
|
|
if (
|
|
isinstance(pyobject.get_type(), rope.base.pyobjects.PyClass)
|
|
and isinstance(pyfunction, rope.base.pyobjects.PyFunction)
|
|
and isinstance(pyfunction.parent, rope.base.pyobjects.PyClass)
|
|
):
|
|
return True
|
|
if isinstance(
|
|
pyobject.get_type(), rope.base.pyobjects.AbstractClass
|
|
) and isinstance(pyfunction, rope.base.builtins.BuiltinFunction):
|
|
return True
|
|
return False
|