forked from VimPlug/jedi
First function execution that is working.
This commit is contained in:
@@ -303,7 +303,7 @@ class Evaluator(object):
|
|||||||
right = self.eval_element(context, element.children[2])
|
right = self.eval_element(context, element.children[2])
|
||||||
types = set(precedence.calculate(self, types, trailer, right))
|
types = set(precedence.calculate(self, types, trailer, right))
|
||||||
break
|
break
|
||||||
types = self.eval_trailer(types, trailer)
|
types = self.eval_trailer(context, types, trailer)
|
||||||
elif element.type in ('testlist_star_expr', 'testlist',):
|
elif element.type in ('testlist_star_expr', 'testlist',):
|
||||||
# The implicit tuple in statements.
|
# The implicit tuple in statements.
|
||||||
types = set([iterable.ImplicitTuple(self, element)])
|
types = set([iterable.ImplicitTuple(self, element)])
|
||||||
@@ -388,7 +388,7 @@ class Evaluator(object):
|
|||||||
return set([iterable.Comprehension.from_atom(self, atom)])
|
return set([iterable.Comprehension.from_atom(self, atom)])
|
||||||
return set([iterable.Array(self, atom)])
|
return set([iterable.Array(self, atom)])
|
||||||
|
|
||||||
def eval_trailer(self, types, trailer):
|
def eval_trailer(self, context, types, trailer):
|
||||||
trailer_op, node = trailer.children[:2]
|
trailer_op, node = trailer.children[:2]
|
||||||
if node == ')': # `arglist` is optional.
|
if node == ')': # `arglist` is optional.
|
||||||
node = ()
|
node = ()
|
||||||
@@ -402,7 +402,8 @@ class Evaluator(object):
|
|||||||
if trailer_op == '.':
|
if trailer_op == '.':
|
||||||
new_types |= self.find_types(typ, node)
|
new_types |= self.find_types(typ, node)
|
||||||
elif trailer_op == '(':
|
elif trailer_op == '(':
|
||||||
new_types |= self.execute(typ, node, trailer)
|
arguments = param.Arguments(self, context, node, trailer)
|
||||||
|
new_types |= self.execute(typ, arguments)
|
||||||
return new_types
|
return new_types
|
||||||
|
|
||||||
def execute_evaluated(self, obj, *args):
|
def execute_evaluated(self, obj, *args):
|
||||||
@@ -413,9 +414,9 @@ class Evaluator(object):
|
|||||||
return self.execute(obj, args)
|
return self.execute(obj, args)
|
||||||
|
|
||||||
@debug.increase_indent
|
@debug.increase_indent
|
||||||
def execute(self, obj, arguments=(), trailer=None):
|
def execute(self, obj, arguments=None):
|
||||||
if not isinstance(arguments, param.Arguments):
|
if not isinstance(arguments, param.Arguments):
|
||||||
arguments = param.Arguments(self, arguments, trailer)
|
arguments = param.Arguments(self, arguments)
|
||||||
|
|
||||||
if self.is_analysis:
|
if self.is_analysis:
|
||||||
arguments.eval_all()
|
arguments.eval_all()
|
||||||
|
|||||||
@@ -62,7 +62,11 @@ class ParamName(ContextName):
|
|||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
def infer(self):
|
def infer(self):
|
||||||
return set()
|
return self._get_param().infer(self.parent_context._evaluator)
|
||||||
|
|
||||||
|
def _get_param(self):
|
||||||
|
params = self.parent_context.get_params()
|
||||||
|
return [p for p in params if p.string_name == self.string_name][0]
|
||||||
|
|
||||||
|
|
||||||
class AbstractFilter(object):
|
class AbstractFilter(object):
|
||||||
@@ -136,7 +140,7 @@ class ParserTreeFilter(AbstractUsedNamesFilter):
|
|||||||
|
|
||||||
|
|
||||||
class FunctionExecutionFilter(ParserTreeFilter):
|
class FunctionExecutionFilter(ParserTreeFilter):
|
||||||
def __init__(self, evaluator, context, parser_scope, param_by_name,
|
def __init__(self, evaluator, context, parser_scope,
|
||||||
until_position=None, origin_scope=None):
|
until_position=None, origin_scope=None):
|
||||||
super(FunctionExecutionFilter, self).__init__(
|
super(FunctionExecutionFilter, self).__init__(
|
||||||
evaluator,
|
evaluator,
|
||||||
@@ -150,7 +154,6 @@ class FunctionExecutionFilter(ParserTreeFilter):
|
|||||||
for name in names:
|
for name in names:
|
||||||
param = search_ancestor(name, 'param')
|
param = search_ancestor(name, 'param')
|
||||||
if param:
|
if param:
|
||||||
#yield self.context._param_by_name(str(name))
|
|
||||||
yield ParamName(self._context, name)
|
yield ParamName(self._context, name)
|
||||||
else:
|
else:
|
||||||
yield TreeNameDefinition(self._context, name)
|
yield TreeNameDefinition(self._context, name)
|
||||||
|
|||||||
@@ -8,8 +8,6 @@ from jedi.parser import tree
|
|||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.evaluate import analysis
|
from jedi.evaluate import analysis
|
||||||
from jedi.evaluate import precedence
|
from jedi.evaluate import precedence
|
||||||
from jedi.evaluate.helpers import FakeName
|
|
||||||
from jedi.cache import underscore_memoization
|
|
||||||
|
|
||||||
|
|
||||||
def try_iter_content(types, depth=0):
|
def try_iter_content(types, depth=0):
|
||||||
@@ -30,7 +28,7 @@ def try_iter_content(types, depth=0):
|
|||||||
|
|
||||||
|
|
||||||
class Arguments(tree.Base):
|
class Arguments(tree.Base):
|
||||||
def __init__(self, evaluator, context, argument_node, trailer=None):
|
def __init__(self, evaluator, context, argument_node, trailer):
|
||||||
"""
|
"""
|
||||||
The argument_node is either a parser node or a list of evaluated
|
The argument_node is either a parser node or a list of evaluated
|
||||||
objects. Those evaluated objects may be lists of evaluated objects
|
objects. Those evaluated objects may be lists of evaluated objects
|
||||||
@@ -202,11 +200,14 @@ class ExecutedParam(tree.Param):
|
|||||||
self._original_param = original_param
|
self._original_param = original_param
|
||||||
self.var_args = var_args
|
self.var_args = var_args
|
||||||
self._values = values
|
self._values = values
|
||||||
|
self.string_name = self._original_param.name.value
|
||||||
|
|
||||||
def eval(self, evaluator):
|
def infer(self, evaluator):
|
||||||
types = set()
|
types = set()
|
||||||
for v in self._values:
|
for v in self._values:
|
||||||
types |= evaluator.eval_element(v)
|
# TODO this context selection seems wrong. Fix it once we change
|
||||||
|
# the way executed params work.
|
||||||
|
types |= evaluator.eval_element(self.var_args._context, v)
|
||||||
return types
|
return types
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -214,11 +215,6 @@ class ExecutedParam(tree.Param):
|
|||||||
# Need to use the original logic here, because it uses the parent.
|
# Need to use the original logic here, because it uses the parent.
|
||||||
return self._original_param.position_nr
|
return self._original_param.position_nr
|
||||||
|
|
||||||
@property
|
|
||||||
@underscore_memoization
|
|
||||||
def name(self):
|
|
||||||
return FakeName(str(self._original_param.name), self, self.start_pos)
|
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
return getattr(self._original_param, name)
|
return getattr(self._original_param, name)
|
||||||
|
|
||||||
@@ -249,7 +245,7 @@ def _get_calling_var_args(evaluator, var_args):
|
|||||||
|
|
||||||
|
|
||||||
def get_params(evaluator, func, var_args):
|
def get_params(evaluator, func, var_args):
|
||||||
param_names = []
|
result_params = []
|
||||||
param_dict = {}
|
param_dict = {}
|
||||||
for param in func.params:
|
for param in func.params:
|
||||||
param_dict[str(param.name)] = param
|
param_dict[str(param.name)] = param
|
||||||
@@ -279,7 +275,7 @@ def get_params(evaluator, func, var_args):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
non_matching_keys[key] = va_values
|
non_matching_keys[key] = va_values
|
||||||
else:
|
else:
|
||||||
param_names.append(ExecutedParam(key_param, var_args, va_values).name)
|
result_params.append(ExecutedParam(key_param, var_args, va_values))
|
||||||
|
|
||||||
if k in keys_used:
|
if k in keys_used:
|
||||||
had_multiple_value_error = True
|
had_multiple_value_error = True
|
||||||
@@ -291,7 +287,7 @@ def get_params(evaluator, func, var_args):
|
|||||||
calling_va, message=m)
|
calling_va, message=m)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
keys_used[k] = param_names[-1]
|
keys_used[k] = result_params[-1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# TODO this is wrong stupid and whatever.
|
# TODO this is wrong stupid and whatever.
|
||||||
pass
|
pass
|
||||||
@@ -331,8 +327,8 @@ def get_params(evaluator, func, var_args):
|
|||||||
|
|
||||||
# Now add to result if it's not one of the previously covered cases.
|
# Now add to result if it's not one of the previously covered cases.
|
||||||
if (not keys_only or param.stars == 2):
|
if (not keys_only or param.stars == 2):
|
||||||
param_names.append(ExecutedParam(param, var_args, values).name)
|
result_params.append(ExecutedParam(param, var_args, values))
|
||||||
keys_used[unicode(param.name)] = param_names[-1]
|
keys_used[unicode(param.name)] = result_params[-1]
|
||||||
|
|
||||||
if keys_only:
|
if keys_only:
|
||||||
# All arguments should be handed over to the next function. It's not
|
# All arguments should be handed over to the next function. It's not
|
||||||
@@ -341,10 +337,10 @@ def get_params(evaluator, func, var_args):
|
|||||||
for k in set(param_dict) - set(keys_used):
|
for k in set(param_dict) - set(keys_used):
|
||||||
param = param_dict[k]
|
param = param_dict[k]
|
||||||
values = [] if param.default is None else [param.default]
|
values = [] if param.default is None else [param.default]
|
||||||
param_names.append(ExecutedParam(param, var_args, values).name)
|
result_params.append(ExecutedParam(param, var_args, values))
|
||||||
|
|
||||||
if not (non_matching_keys or had_multiple_value_error
|
if not (non_matching_keys or had_multiple_value_error or
|
||||||
or param.stars or param.default):
|
param.stars or param.default):
|
||||||
# add a warning only if there's not another one.
|
# add a warning only if there's not another one.
|
||||||
calling_va = _get_calling_var_args(evaluator, var_args)
|
calling_va = _get_calling_var_args(evaluator, var_args)
|
||||||
if calling_va is not None:
|
if calling_va is not None:
|
||||||
@@ -382,7 +378,7 @@ def get_params(evaluator, func, var_args):
|
|||||||
continue
|
continue
|
||||||
analysis.add(evaluator, 'type-error-too-many-arguments',
|
analysis.add(evaluator, 'type-error-too-many-arguments',
|
||||||
v, message=m)
|
v, message=m)
|
||||||
return param_names
|
return result_params
|
||||||
|
|
||||||
|
|
||||||
def _iterate_star_args(evaluator, array, input_node, func=None):
|
def _iterate_star_args(evaluator, array, input_node, func=None):
|
||||||
|
|||||||
@@ -835,17 +835,13 @@ class FunctionExecutionContext(Executed):
|
|||||||
|
|
||||||
def get_filters(self, search_global, until_position=None, origin_scope=None):
|
def get_filters(self, search_global, until_position=None, origin_scope=None):
|
||||||
yield FunctionExecutionFilter(self._evaluator, self, self._funcdef,
|
yield FunctionExecutionFilter(self._evaluator, self, self._funcdef,
|
||||||
self.param_by_name,
|
|
||||||
until_position,
|
until_position,
|
||||||
origin_scope=origin_scope)
|
origin_scope=origin_scope)
|
||||||
|
|
||||||
@memoize_default(default=NO_DEFAULT)
|
@memoize_default(default=NO_DEFAULT)
|
||||||
def _get_params(self):
|
def get_params(self):
|
||||||
return param.get_params(self._evaluator, self._funcdef, self.var_args)
|
return param.get_params(self._evaluator, self._funcdef, self.var_args)
|
||||||
|
|
||||||
def param_by_name(self, name):
|
|
||||||
return [n for n in self._get_params() if str(n) == name][0]
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s of %s>" % (type(self).__name__, self._funcdef)
|
return "<%s of %s>" % (type(self).__name__, self._funcdef)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user