forked from VimPlug/jedi
Refactor the dynamic params functionality.
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user