1
0
forked from VimPlug/jedi

Refactor the dynamic params functionality.

This commit is contained in:
Dave Halter
2016-07-17 19:05:47 +02:00
parent 75c1ebc2fe
commit becbbb2e64

View File

@@ -79,52 +79,29 @@ def search_function_call(evaluator, func):
"""
from jedi.evaluate import representation as er
def get_params_for_module(module):
"""
Returns the values of a param, or an empty array.
"""
@memoize_default([], evaluator_is_first_arg=True)
def get_posibilities(evaluator, module, func_name):
def get_possible_nodes(module, func_name):
try:
names = module.used_names[func_name]
except KeyError:
return []
return
for name in names:
parent = name.parent
if tree.is_node(parent, 'trailer'):
parent = parent.parent
bracket = name.get_next_leaf()
trailer = bracket.parent
if trailer.type == 'trailer' and bracket == '(':
yield name, trailer
trailer = None
if tree.is_node(parent, 'power', 'atom_expr'):
for t in parent.children[1:]:
if t == '**':
break
if t.start_pos > name.start_pos and t.children[0] == '(':
trailer = t
break
if trailer is not None:
types = evaluator.goto_definitions(name)
# We have to remove decorators, because they are not the
# "original" functions, this way we can easily compare.
# At the same time we also have to remove InstanceElements.
undec = []
for escope in types:
if escope.isinstance(er.Function, er.Instance) \
and escope.decorates is not None:
undec.append(escope.decorates)
elif isinstance(escope, er.InstanceElement):
undec.append(escope.var)
else:
undec.append(escope)
if evaluator.wrap(compare) in undec:
# Only if we have the correct function we execute
# it, otherwise just ignore it.
evaluator.eval_trailer(types, trailer)
return listener.param_possibilities
return get_posibilities(evaluator, module, func_name)
def undecorate(typ):
# We have to remove decorators, because they are not the
# "original" functions, this way we can easily compare.
# At the same time we also have to remove InstanceElements.
if typ.isinstance(er.Function, er.Instance) \
and typ.decorates is not None:
return typ.decorates
elif isinstance(typ, er.InstanceElement):
return typ.var
else:
return typ
current_module = func.get_parent_until()
func_name = unicode(func.name)
@@ -141,13 +118,26 @@ def search_function_call(evaluator, func):
try:
result = []
# This is like backtracking: Get the first possible result.
i = 0
for mod in imports.get_modules_containing_name(evaluator, [current_module], func_name):
result = get_params_for_module(mod)
for name, trailer in get_possible_nodes(mod, func_name):
i += 1
for typ in evaluator.goto_definitions(name):
undecorated = undecorate(typ)
if evaluator.wrap(compare) == undecorated:
# Only if we have the correct function we execute
# it, otherwise just ignore it.
evaluator.eval_trailer([typ], trailer)
result = listener.param_possibilities
# If there are results after processing a module, we're probably
# good to process.
if result:
break
return result
finally:
# cleanup: remove the listener; important: should not stick.
func.listeners.remove(listener)
return result
return set()