1
0
forked from VimPlug/jedi

First function execution that is working.

This commit is contained in:
Dave Halter
2016-10-23 03:02:57 +02:00
parent 75b67af000
commit 0475bb5fd0
4 changed files with 28 additions and 32 deletions

View File

@@ -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()

View File

@@ -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)

View File

@@ -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):

View File

@@ -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)