1
0
forked from VimPlug/jedi

Arguments move to params.

This commit is contained in:
Dave Halter
2014-10-20 15:43:56 +02:00
parent b2c95cb02f
commit 1a639bd118
4 changed files with 67 additions and 40 deletions

View File

@@ -86,6 +86,7 @@ from jedi.evaluate import stdlib
from jedi.evaluate import finder from jedi.evaluate import finder
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import precedence from jedi.evaluate import precedence
from jedi.evaluate import param
from jedi.evaluate.helpers import FakeStatement, deep_ast_copy from jedi.evaluate.helpers import FakeStatement, deep_ast_copy
@@ -183,7 +184,7 @@ class Evaluator(object):
""" """
if isinstance(atom, pr.Name): if isinstance(atom, pr.Name):
# This is the first global lookup. # This is the first global lookup.
stmt = atom.get_parent_until(pr.ExprStmt) stmt = atom.get_parent_until((pr.ExprStmt, pr.ReturnStmt))
return self.find_types(stmt.parent, atom, stmt.start_pos, return self.find_types(stmt.parent, atom, stmt.start_pos,
search_global=True) search_global=True)
elif isinstance(atom, pr.Literal): elif isinstance(atom, pr.Literal):
@@ -194,7 +195,7 @@ class Evaluator(object):
def eval_trailer(self, types, trailer): def eval_trailer(self, 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 = None node = ()
new_types = [] new_types = []
for typ in types: for typ in types:
if trailer_op == '.': if trailer_op == '.':
@@ -207,7 +208,7 @@ class Evaluator(object):
@debug.increase_indent @debug.increase_indent
def execute(self, obj, arguments=()): def execute(self, obj, arguments=()):
arguments = er.Arguments(self, arguments) arguments = param.Arguments(self, arguments)
if obj.isinstance(er.Function): if obj.isinstance(er.Function):
obj = obj.get_decorated_func() obj = obj.get_decorated_func()

View File

@@ -9,6 +9,56 @@ from jedi.evaluate import helpers
from jedi.evaluate import analysis from jedi.evaluate import analysis
class Arguments(object):
def __init__(self, evaluator, argument_node):
"""
The argument_node is either a parser node or a list of evaluated
objects.
"""
self._argument_node = argument_node
self._evaluator = evaluator
def _split(self):
if isinstance(self._argument_node, (tuple, list)):
for el in self._argument_node:
yield 0
else:
iterator = iter(self._argument_node.children)
for child in iterator:
if child == ',':
continue
elif child in ('*', '**'):
yield len(child), next(iterator)
else:
yield 0, child
def iterate(self):
"""Returns key/value tuples, as statements."""
for stars, el in self._split():
if stars == 1:
arrays = self._evaluator.eval_element(el)
iterators = [_iterate_star_args(self._evaluator, a, expression_list[1:], func)
for a in arrays]
for values in list(zip_longest(*iterators)):
yield None, [v for v in values if v is not None]
elif stars == 2:
raise NotImplementedError
else:
yield None, [el]
def kwargs(self):
return []
def args(self):
return []
def eval_args(self):
return [self._evaluator.eval_element(el) for stars, el in self._split()]
def __repr__(self):
return '<%s: %s>' % (type(self).__name__, self._argument_node)
class ExecutedParam(pr.Param): class ExecutedParam(pr.Param):
def __init__(self): def __init__(self):
"""Don't use this method, it's just here to overwrite the old one.""" """Don't use this method, it's just here to overwrite the old one."""
@@ -198,7 +248,7 @@ def _unpack_var_args(evaluator, var_args, func):
argument_list.append((None, [helpers.FakeStatement([func.instance])])) argument_list.append((None, [helpers.FakeStatement([func.instance])]))
# `var_args` is typically an Array, and not a list. # `var_args` is typically an Array, and not a list.
for stmt in _reorder_var_args(var_args): for stmt in _reorder_var_args(var_args.iterate()):
if not isinstance(stmt, pr.Statement): if not isinstance(stmt, pr.Statement):
if stmt is None: if stmt is None:
argument_list.append((None, [])) argument_list.append((None, []))
@@ -214,7 +264,7 @@ def _unpack_var_args(evaluator, var_args, func):
# *args # *args
if expression_list[0] == '*': if expression_list[0] == '*':
arrays = evaluator.eval_expression_list(expression_list[1:]) arrays = evaluator.eval_expression_list(expression_list[1:])
iterators = [_iterate_star_args(evaluator, a, expression_list[1:], func) iterators = [_iterate_star_args(evaluator, arr, func)
for a in arrays] for a in arrays]
for values in list(zip_longest(*iterators)): for values in list(zip_longest(*iterators)):
argument_list.append((None, [v for v in values if v is not None])) argument_list.append((None, [v for v in values if v is not None]))

View File

@@ -335,31 +335,6 @@ class InstanceElement(use_metaclass(CachedMetaClass, pr.Base)):
return "<%s of %s>" % (type(self).__name__, self.var) return "<%s of %s>" % (type(self).__name__, self.var)
class Arguments(object):
def __init__(self, evaluator, argument_node):
self._argument_node = argument_node
self._evaluator = evaluator
def _split(self):
iterator = iter(self._argument_node.children)
for child in iterator:
if child == ',':
continue
elif child in ('*', '**'):
yield len(child), next(iterator)
else:
yield 0, child
def kwargs(self):
return []
def args(self):
return []
def eval_args(self):
return [self._evaluator.eval_element(el) for stars, el in self._split()]
class Wrapper(pr.Base): class Wrapper(pr.Base):
def is_scope(self): def is_scope(self):
return True return True
@@ -599,19 +574,11 @@ class FunctionExecution(Executed):
types = list(docstrings.find_return_types(self._evaluator, func)) types = list(docstrings.find_return_types(self._evaluator, func))
for r in self.returns: for r in self.returns:
if isinstance(r, pr.KeywordStatement):
stmt = r.stmt
else:
stmt = r # Lambdas
if stmt is None:
continue
check = flow_analysis.break_check(self._evaluator, self, r.parent) check = flow_analysis.break_check(self._evaluator, self, r.parent)
if check is flow_analysis.UNREACHABLE: if check is flow_analysis.UNREACHABLE:
debug.dbg('Return unreachable: %s', r) debug.dbg('Return unreachable: %s', r)
else: else:
types += self._evaluator.eval_statement(stmt) types += self._evaluator.eval_element(r.children[1])
if check is flow_analysis.REACHABLE: if check is flow_analysis.REACHABLE:
debug.dbg('Return reachable: %s', r) debug.dbg('Return reachable: %s', r)
break break
@@ -673,6 +640,11 @@ class FunctionExecution(Executed):
def returns(self): def returns(self):
return self._copy_list(self.base.returns) return self._copy_list(self.base.returns)
@common.safe_property
@memoize_default([])
def children(self):
return self._copy_list(self.base.children)
@common.safe_property @common.safe_property
@memoize_default([]) @memoize_default([])
def asserts(self): def asserts(self):

View File

@@ -696,8 +696,12 @@ class Function(Scope):
def name(self): def name(self):
return self.children[1] # First token after `def` return self.children[1] # First token after `def`
@property
def params(self): def params(self):
return self.children[3].children # After def foo( third = self.children[3] # After def foo(
if isinstance(third, Operator):
return []
return self.children[3].children
def annotation(self): def annotation(self):
try: try: