1
0
forked from VimPlug/jedi

Fix lambda dynamic param searches, fixes #1070

This commit is contained in:
Dave Halter
2018-03-25 23:54:43 +02:00
parent f5ba6de38c
commit 538996d8d3
2 changed files with 45 additions and 11 deletions

View File

@@ -73,14 +73,21 @@ def search_params(evaluator, execution_context, funcdef):
# you will see the slowdown, especially in 3.6. # you will see the slowdown, especially in 3.6.
return create_default_params(execution_context, funcdef) return create_default_params(execution_context, funcdef)
debug.dbg('Dynamic param search in %s.', funcdef.name.value, color='MAGENTA') if funcdef.type == 'lambdef':
string_name = _get_lambda_name(funcdef)
if string_name is None:
return create_default_params(execution_context, funcdef)
else:
string_name = funcdef.name.value
debug.dbg('Dynamic param search in %s.', string_name, color='MAGENTA')
try: try:
module_context = execution_context.get_root_context() module_context = execution_context.get_root_context()
function_executions = _search_function_executions( function_executions = _search_function_executions(
evaluator, evaluator,
module_context, module_context,
funcdef funcdef,
string_name=string_name,
) )
if function_executions: if function_executions:
zipped_params = zip(*list( zipped_params = zip(*list(
@@ -100,25 +107,24 @@ def search_params(evaluator, execution_context, funcdef):
@evaluator_function_cache(default=None) @evaluator_function_cache(default=None)
@to_list @to_list
def _search_function_executions(evaluator, module_context, funcdef): def _search_function_executions(evaluator, module_context, funcdef, string_name):
""" """
Returns a list of param names. Returns a list of param names.
""" """
func_string_name = funcdef.name.value
compare_node = funcdef compare_node = funcdef
if func_string_name == '__init__': if string_name == '__init__':
cls = get_parent_scope(funcdef) cls = get_parent_scope(funcdef)
if isinstance(cls, tree.Class): if isinstance(cls, tree.Class):
func_string_name = cls.name.value string_name = cls.name.value
compare_node = cls compare_node = cls
found_executions = False found_executions = False
i = 0 i = 0
for for_mod_context in imports.get_modules_containing_name( for for_mod_context in imports.get_modules_containing_name(
evaluator, [module_context], func_string_name): evaluator, [module_context], string_name):
if not isinstance(module_context, ModuleContext): if not isinstance(module_context, ModuleContext):
return return
for name, trailer in _get_possible_nodes(for_mod_context, func_string_name): for name, trailer in _get_possible_nodes(for_mod_context, string_name):
i += 1 i += 1
# This is a simple way to stop Jedi's dynamic param recursion # This is a simple way to stop Jedi's dynamic param recursion
@@ -139,6 +145,18 @@ def _search_function_executions(evaluator, module_context, funcdef):
return return
def _get_lambda_name(node):
stmt = node.parent
if stmt.type == 'expr_stmt':
first_operator = next(stmt.yield_operators(), None)
if first_operator == '=':
first = stmt.children[0]
if first.type == 'name':
return first.value
return None
def _get_possible_nodes(module_context, func_string_name): def _get_possible_nodes(module_context, func_string_name):
try: try:
names = module_context.tree_node.get_used_names()[func_string_name] names = module_context.tree_node.get_used_names()[func_string_name]
@@ -160,9 +178,7 @@ def _check_name_for_execution(evaluator, context, compare_node, name, trailer):
if arglist == ')': if arglist == ')':
arglist = None arglist = None
args = TreeArguments(evaluator, context, arglist, trailer) args = TreeArguments(evaluator, context, arglist, trailer)
if value_node.type == 'funcdef': if value_node.type == 'classdef':
yield value.get_function_execution(args)
else:
created_instance = instance.TreeInstance( created_instance = instance.TreeInstance(
evaluator, evaluator,
value.parent_context, value.parent_context,
@@ -171,6 +187,8 @@ def _check_name_for_execution(evaluator, context, compare_node, name, trailer):
) )
for execution in created_instance.create_init_executions(): for execution in created_instance.create_init_executions():
yield execution yield execution
else:
yield value.get_function_execution(args)
for value in evaluator.goto_definitions(context, name): for value in evaluator.goto_definitions(context, name):
value_node = value.tree_node value_node = value.tree_node

View File

@@ -132,3 +132,19 @@ def from_comprehension(foo):
[from_comprehension(1.0) for n in (1,)] [from_comprehension(1.0) for n in (1,)]
[from_comprehension(n) for n in (1,)] [from_comprehension(n) for n in (1,)]
# -----------------
# lambdas
# -----------------
#? int()
x_lambda = lambda x: x
x_lambda(1)
class X():
#? str()
x_method = lambda self, a: a
X().x_method('')