1
0
forked from VimPlug/jedi

BoundMethods now have access to the function that they are using

This commit is contained in:
Dave Halter
2018-08-03 00:15:11 +02:00
parent e576457a43
commit f25310e0b9
5 changed files with 72 additions and 66 deletions

View File

@@ -38,19 +38,9 @@ class LambdaName(AbstractNameDefinition):
return ContextSet(self._lambda_context)
class FunctionContext(use_metaclass(CachedMetaClass, TreeContext)):
"""
Needed because of decorators. Decorators are evaluated here.
"""
class AbstractFunction(TreeContext):
api_type = u'function'
@classmethod
def from_context(cls, context, tree_node):
while context.is_class():
context = context.parent_context
return cls(context.evaluator, parent_context=context, tree_node=tree_node)
def get_filters(self, search_global, until_position=None, origin_scope=None):
if search_global:
yield ParserTreeFilter(
@@ -64,6 +54,24 @@ class FunctionContext(use_metaclass(CachedMetaClass, TreeContext)):
for filter in scope.get_filters(search_global=False, origin_scope=origin_scope):
yield filter
def get_param_names(self):
function_execution = self.get_function_execution()
return [ParamName(function_execution, param.name)
for param in self.tree_node.get_params()]
@property
def name(self):
if self.tree_node.type == 'lambdef':
return LambdaName(self)
return ContextName(self, self.tree_node.name)
def get_function_execution(self, arguments=None):
raise NotImplementedError
def py__call__(self, arguments):
function_execution = self.get_function_execution(arguments)
return self.infer_function_execution(function_execution)
def infer_function_execution(self, function_execution):
"""
Created to be used by inheritance.
@@ -86,35 +94,28 @@ class FunctionContext(use_metaclass(CachedMetaClass, TreeContext)):
else:
return function_execution.get_return_values()
class FunctionContext(use_metaclass(CachedMetaClass, AbstractFunction)):
"""
Needed because of decorators. Decorators are evaluated here.
"""
@classmethod
def from_context(cls, context, tree_node):
from jedi.evaluate.context import AbstractInstanceContext
while context.is_class() or isinstance(context, AbstractInstanceContext):
context = context.parent_context
return cls(context.evaluator, parent_context=context, tree_node=tree_node)
def get_function_execution(self, arguments=None):
if arguments is None:
arguments = AnonymousArguments()
return FunctionExecutionContext(self.evaluator, self.parent_context, self, arguments)
def py__call__(self, arguments):
function_execution = self.get_function_execution(arguments)
return self.infer_function_execution(function_execution)
def py__class__(self):
# This differentiation is only necessary for Python2. Python3 does not
# use a different method class.
if isinstance(parser_utils.get_parent_scope(self.tree_node), tree.Class):
name = u'METHOD_CLASS'
else:
name = u'FUNCTION_CLASS'
return compiled.get_special_object(self.evaluator, name)
@property
def name(self):
if self.tree_node.type == 'lambdef':
return LambdaName(self)
return ContextName(self, self.tree_node.name)
def get_param_names(self):
function_execution = self.get_function_execution()
return [ParamName(function_execution, param.name)
for param in self.tree_node.get_params()]
return compiled.get_special_object(self.evaluator, u'FUNCTION_CLASS')
class FunctionExecutionContext(TreeContext):