mirror of
https://github.com/davidhalter/jedi.git
synced 2026-05-17 13:59:37 +08:00
Refactor the dynamic params functionality.
This commit is contained in:
+34
-44
@@ -79,52 +79,29 @@ def search_function_call(evaluator, func):
|
|||||||
"""
|
"""
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
|
|
||||||
def get_params_for_module(module):
|
def get_possible_nodes(module, func_name):
|
||||||
"""
|
|
||||||
Returns the values of a param, or an empty array.
|
|
||||||
"""
|
|
||||||
@memoize_default([], evaluator_is_first_arg=True)
|
|
||||||
def get_posibilities(evaluator, module, func_name):
|
|
||||||
try:
|
try:
|
||||||
names = module.used_names[func_name]
|
names = module.used_names[func_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
parent = name.parent
|
bracket = name.get_next_leaf()
|
||||||
if tree.is_node(parent, 'trailer'):
|
trailer = bracket.parent
|
||||||
parent = parent.parent
|
if trailer.type == 'trailer' and bracket == '(':
|
||||||
|
yield name, trailer
|
||||||
|
|
||||||
trailer = None
|
def undecorate(typ):
|
||||||
if tree.is_node(parent, 'power', 'atom_expr'):
|
# We have to remove decorators, because they are not the
|
||||||
for t in parent.children[1:]:
|
# "original" functions, this way we can easily compare.
|
||||||
if t == '**':
|
# At the same time we also have to remove InstanceElements.
|
||||||
break
|
if typ.isinstance(er.Function, er.Instance) \
|
||||||
if t.start_pos > name.start_pos and t.children[0] == '(':
|
and typ.decorates is not None:
|
||||||
trailer = t
|
return typ.decorates
|
||||||
break
|
elif isinstance(typ, er.InstanceElement):
|
||||||
if trailer is not None:
|
return typ.var
|
||||||
types = evaluator.goto_definitions(name)
|
else:
|
||||||
|
return 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.
|
|
||||||
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)
|
|
||||||
|
|
||||||
current_module = func.get_parent_until()
|
current_module = func.get_parent_until()
|
||||||
func_name = unicode(func.name)
|
func_name = unicode(func.name)
|
||||||
@@ -141,13 +118,26 @@ def search_function_call(evaluator, func):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
result = []
|
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):
|
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:
|
if result:
|
||||||
break
|
return result
|
||||||
finally:
|
finally:
|
||||||
# cleanup: remove the listener; important: should not stick.
|
# cleanup: remove the listener; important: should not stick.
|
||||||
func.listeners.remove(listener)
|
func.listeners.remove(listener)
|
||||||
|
|
||||||
return result
|
return set()
|
||||||
|
|||||||
Reference in New Issue
Block a user