mirror of
https://github.com/davidhalter/jedi.git
synced 2026-02-07 17:10:57 +08:00
Improve a few anonymous function execution context goto issues.
This commit is contained in:
@@ -79,7 +79,7 @@ from jedi.evaluate import precedence
|
||||
from jedi.evaluate import param
|
||||
from jedi.evaluate import helpers
|
||||
from jedi.evaluate.filters import TreeNameDefinition
|
||||
from jedi.evaluate.instance import AnonymousInstance, AnonymousInstanceFunctionExecution
|
||||
from jedi.evaluate.instance import AnonymousInstance, BoundMethod
|
||||
|
||||
|
||||
class Evaluator(object):
|
||||
@@ -489,7 +489,10 @@ class Evaluator(object):
|
||||
return [TreeNameDefinition(context, name)]
|
||||
elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name:
|
||||
if par.type in ('funcdef', 'classdef', 'module'):
|
||||
return [context.name]
|
||||
if par.type == 'funcdef':
|
||||
return [context.function_context.name]
|
||||
else:
|
||||
return [context.name]
|
||||
return [TreeNameDefinition(context, name)]
|
||||
elif isinstance(stmt, tree.Import):
|
||||
module_names = imports.ImportWrapper(context, name).follow(is_goto=True)
|
||||
@@ -567,13 +570,17 @@ class Evaluator(object):
|
||||
|
||||
if is_funcdef:
|
||||
if isinstance(parent_context, AnonymousInstance):
|
||||
return AnonymousInstanceFunctionExecution(
|
||||
parent_context,
|
||||
parent_context.parent_context,
|
||||
scope_node
|
||||
func = BoundMethod(
|
||||
self, parent_context, parent_context.class_context,
|
||||
parent_context.parent_context, scope_node
|
||||
)
|
||||
else:
|
||||
return er.AnonymousFunctionExecution(self, parent_context, scope_node)
|
||||
func = er.FunctionContext(
|
||||
self,
|
||||
parent_context,
|
||||
scope_node
|
||||
)
|
||||
return func.get_function_execution()
|
||||
elif scope_node.type == 'classdef':
|
||||
class_context = er.ClassContext(self, scope_node, parent_context)
|
||||
if child_is_funcdef:
|
||||
|
||||
@@ -143,19 +143,20 @@ def _evaluate_for_statement_string(module_context, string):
|
||||
return []
|
||||
|
||||
from jedi.evaluate.param import ValuesArguments
|
||||
from jedi.evaluate.representation import FunctionExecutionContext
|
||||
func_context = FunctionExecutionContext(
|
||||
from jedi.evaluate.representation import FunctionContext
|
||||
function_context = FunctionContext(
|
||||
module_context.evaluator,
|
||||
module_context,
|
||||
funcdef,
|
||||
funcdef
|
||||
)
|
||||
func_execution_context = function_context.get_function_execution(
|
||||
ValuesArguments([])
|
||||
)
|
||||
|
||||
# Use the module of the param.
|
||||
# TODO this module is not the module of the param in case of a function
|
||||
# call. In that case it's the module of the function call.
|
||||
# stuffed with content from a function call.
|
||||
return list(_execute_types_in_stmt(func_context, stmt))
|
||||
return list(_execute_types_in_stmt(func_execution_context, stmt))
|
||||
|
||||
|
||||
def _execute_types_in_stmt(module_context, stmt):
|
||||
|
||||
@@ -191,6 +191,7 @@ class ImportName(AbstractNameDefinition):
|
||||
def api_type(self):
|
||||
return 'module'
|
||||
|
||||
|
||||
class SubModuleName(ImportName):
|
||||
def infer(self):
|
||||
return Importer(
|
||||
|
||||
@@ -130,10 +130,13 @@ class AbstractInstanceContext(Context):
|
||||
pass
|
||||
|
||||
def _create_init_execution(self, class_context, func_node):
|
||||
bound_method = BoundMethod(
|
||||
self.evaluator, self, class_context, self.parent_context, func_node
|
||||
)
|
||||
return InstanceFunctionExecution(
|
||||
self,
|
||||
class_context.parent_context,
|
||||
func_node,
|
||||
bound_method,
|
||||
self.var_args
|
||||
)
|
||||
|
||||
@@ -155,11 +158,11 @@ class AbstractInstanceContext(Context):
|
||||
if scope.name.value == '__init__' and parent_context == class_context:
|
||||
return self._create_init_execution(class_context, scope)
|
||||
else:
|
||||
return AnonymousInstanceFunctionExecution(
|
||||
self,
|
||||
class_context.parent_context,
|
||||
scope,
|
||||
bound_method = BoundMethod(
|
||||
self.evaluator, self, class_context,
|
||||
self.parent_context, scope
|
||||
)
|
||||
return bound_method.get_function_execution()
|
||||
else:
|
||||
raise NotImplementedError
|
||||
return class_context
|
||||
@@ -251,13 +254,13 @@ class BoundMethod(er.FunctionContext):
|
||||
self._instance = instance
|
||||
self._class_context = class_context
|
||||
|
||||
def get_function_execution(self, arguments):
|
||||
return InstanceFunctionExecution(
|
||||
self._instance,
|
||||
self.parent_context,
|
||||
self.funcdef,
|
||||
arguments
|
||||
)
|
||||
def get_function_execution(self, arguments=None):
|
||||
if arguments is None:
|
||||
return AnonymousInstanceFunctionExecution(
|
||||
self._instance, self.parent_context, self)
|
||||
else:
|
||||
return InstanceFunctionExecution(
|
||||
self._instance, self.parent_context, self, arguments)
|
||||
|
||||
|
||||
class CompiledBoundMethod(compiled.CompiledObject):
|
||||
@@ -428,17 +431,17 @@ class InstanceVarArgs(object):
|
||||
|
||||
|
||||
class InstanceFunctionExecution(er.FunctionExecutionContext):
|
||||
def __init__(self, instance, parent_context, funcdef, var_args):
|
||||
def __init__(self, instance, parent_context, function_context, var_args):
|
||||
self.instance = instance
|
||||
var_args = InstanceVarArgs(instance, funcdef, var_args)
|
||||
var_args = InstanceVarArgs(instance, function_context.funcdef, var_args)
|
||||
|
||||
super(InstanceFunctionExecution, self).__init__(
|
||||
instance.evaluator, parent_context, funcdef, var_args)
|
||||
instance.evaluator, parent_context, function_context, var_args)
|
||||
|
||||
|
||||
class AnonymousInstanceFunctionExecution(InstanceFunctionExecution):
|
||||
function_execution_filter = filters.AnonymousInstanceFunctionExecutionFilter
|
||||
|
||||
def __init__(self, instance, parent_context, funcdef):
|
||||
def __init__(self, instance, parent_context, function_context):
|
||||
super(AnonymousInstanceFunctionExecution, self).__init__(
|
||||
instance, parent_context, funcdef, None)
|
||||
instance, parent_context, function_context, None)
|
||||
|
||||
@@ -252,13 +252,12 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext)):
|
||||
else:
|
||||
return function_execution.get_return_values()
|
||||
|
||||
def get_function_execution(self, arguments):
|
||||
return FunctionExecutionContext(
|
||||
self.evaluator,
|
||||
self.parent_context,
|
||||
self.base,
|
||||
arguments
|
||||
)
|
||||
def get_function_execution(self, arguments=None):
|
||||
e = self.evaluator
|
||||
if arguments is None:
|
||||
return AnonymousFunctionExecution(e, self.parent_context, self)
|
||||
else:
|
||||
return FunctionExecutionContext(e, self.parent_context, self, arguments)
|
||||
|
||||
def py__call__(self, arguments):
|
||||
function_execution = self.get_function_execution(arguments)
|
||||
@@ -281,7 +280,7 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext)):
|
||||
anon = AnonymousFunctionExecution(
|
||||
self.evaluator,
|
||||
self.parent_context,
|
||||
self.funcdef
|
||||
self
|
||||
)
|
||||
return [ParamName(anon, param.name) for param in self.funcdef.params]
|
||||
|
||||
@@ -297,12 +296,14 @@ class FunctionExecutionContext(Executed):
|
||||
"""
|
||||
function_execution_filter = FunctionExecutionFilter
|
||||
|
||||
def __init__(self, evaluator, parent_context, funcdef, var_args):
|
||||
def __init__(self, evaluator, parent_context, function_context, var_args):
|
||||
super(FunctionExecutionContext, self).__init__(evaluator, parent_context, var_args)
|
||||
self.funcdef = funcdef
|
||||
if isinstance(funcdef, mixed.MixedObject):
|
||||
self.function_context = function_context
|
||||
self.funcdef = function_context.funcdef
|
||||
if isinstance(function_context, mixed.MixedObject):
|
||||
# The extra information in mixed is not needed anymore. We can just
|
||||
# unpack it and give it the tree object.
|
||||
raise DeprecationWarning
|
||||
funcdef = funcdef.definition
|
||||
|
||||
# Just overwrite the old version. We don't need it anymore.
|
||||
@@ -316,7 +317,7 @@ class FunctionExecutionContext(Executed):
|
||||
#self._copied_funcdef = funcdef
|
||||
|
||||
def get_node(self):
|
||||
return self.funcdef
|
||||
return self.function_context.funcdef
|
||||
|
||||
@memoize_default(default=set())
|
||||
@recursion.execution_recursion_decorator
|
||||
@@ -426,9 +427,9 @@ class FunctionExecutionContext(Executed):
|
||||
|
||||
|
||||
class AnonymousFunctionExecution(FunctionExecutionContext):
|
||||
def __init__(self, evaluator, parent_context, funcdef):
|
||||
def __init__(self, evaluator, parent_context, function_context):
|
||||
super(AnonymousFunctionExecution, self).__init__(
|
||||
evaluator, parent_context, funcdef, var_args=None)
|
||||
evaluator, parent_context, function_context, var_args=None)
|
||||
|
||||
@memoize_default(default=NO_DEFAULT)
|
||||
def get_params(self):
|
||||
|
||||
Reference in New Issue
Block a user