Improve a few anonymous function execution context goto issues.

This commit is contained in:
Dave Halter
2016-12-04 22:35:23 +01:00
parent 6f4cd7e6d3
commit 641ecedcd2
7 changed files with 94 additions and 94 deletions

View File

@@ -312,12 +312,10 @@ class BaseDefinition(object):
return '.'.join(path if path[0] else path[1:])
def goto_assignments(self):
try:
tree_name = self._name.tree_name
except AttributeError:
if self._name.tree_name is None:
return self
defs = self._evaluator.goto(self._name.parent_context, tree_name)
defs = self._evaluator.goto(self._name.parent_context, self._name.tree_name)
return [Definition(self._evaluator, d) for d in defs]
@memoize_method
@@ -559,11 +557,13 @@ class Definition(BaseDefinition):
"""
typ = self.type
try:
tree_name = self._name.tree_name
except AttributeError:
pass
else:
if typ in ('function', 'class', 'module') or tree_name is None:
if typ == 'function':
# For the description we want a short and a pythonic way.
typ = 'def'
return typ + ' ' + self._name.string_name
definition = tree_name.get_definition()
try:
@@ -585,10 +585,6 @@ class Definition(BaseDefinition):
if typ == 'param':
txt = typ + ' ' + txt
return txt
if typ == 'function':
# For the description we want a short and a pythonic way.
typ = 'def'
return typ + ' ' + self._name.string_name
# TODO DELETE
@@ -664,12 +660,10 @@ class Definition(BaseDefinition):
Returns True, if defined as a name in a statement, function or class.
Returns False, if it's a reference to such a definition.
"""
try:
tree_name = self._name.tree_name
except AttributeError:
if self._name.tree_name is None:
return True
else:
return tree_name.is_definition()
return self._name.tree_name.is_definition()
def __eq__(self, other):
return self._name.start_pos == other._name.start_pos \
@@ -708,22 +702,15 @@ class CallSignature(Definition):
return i
if self.params:
param_name = self.params[-1]._name
try:
tree_name = param_name.tree_name
except AttributeError:
pass
else:
if tree_name.get_definition().stars == 2:
if param_name.tree_name is not None:
if param_name.tree_name.get_definition().stars == 2:
return i
return None
if self._index >= len(self.params):
for i, param in enumerate(self.params):
try:
tree_name = param._name.tree_name
except AttributeError:
pass
else:
if tree_name is not None:
# *args case
if tree_name.get_definition().stars == 1:
return i

View File

@@ -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,6 +489,9 @@ 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'):
if par.type == 'funcdef':
return [context.function_context.name]
else:
return [context.name]
return [TreeNameDefinition(context, name)]
elif isinstance(stmt, tree.Import):
@@ -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:

View File

@@ -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):

View File

@@ -191,6 +191,7 @@ class ImportName(AbstractNameDefinition):
def api_type(self):
return 'module'
class SubModuleName(ImportName):
def infer(self):
return Importer(

View File

@@ -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):
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.funcdef,
arguments
)
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)

View File

@@ -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):

View File

@@ -22,10 +22,10 @@ cd = e
#! ['module math']
import math
#! ['import math']
#! ['module math']
math
#! ['import math']
#! ['module math']
b = math
#! ['b = math']
b
@@ -148,7 +148,7 @@ mod1.a
#! ['a = 1.0']
from import_tree.pkg.mod1 import a
#! ['import os']
#! ['module os']
from .imports import os
#! ['some_variable = 1']