forked from VimPlug/jedi
Implementation of BoundMethod.
This commit is contained in:
@@ -52,7 +52,7 @@ class AbstractLazyContext(object):
|
||||
class LazyKnownContext(AbstractLazyContext):
|
||||
"""data is a context."""
|
||||
def infer(self):
|
||||
return set([self._data])
|
||||
yield self._data
|
||||
|
||||
|
||||
class LazyKnownContexts(AbstractLazyContext):
|
||||
|
||||
@@ -160,16 +160,16 @@ class TreeInstance(AbstractInstanceContext):
|
||||
parent_context = self.create_instance_context(class_context, scope)
|
||||
if scope.type == 'funcdef':
|
||||
if scope.name.value == '__init__' and parent_context == self:
|
||||
return er.FunctionExecutionContext(
|
||||
self.evaluator,
|
||||
self.parent_context,
|
||||
return InstanceFunctionExecution(
|
||||
self,
|
||||
class_context.parent_context,
|
||||
scope,
|
||||
self.var_args
|
||||
)
|
||||
else:
|
||||
return er.AnonymousFunctionExecution(
|
||||
self.evaluator,
|
||||
self.parent_context,
|
||||
class_context.parent_context,
|
||||
scope,
|
||||
)
|
||||
else:
|
||||
@@ -193,25 +193,28 @@ class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
|
||||
|
||||
|
||||
class BoundMethod(object):
|
||||
def __init__(self, function):
|
||||
def __init__(self, instance, class_context, function):
|
||||
self._instance = instance
|
||||
self._class_context = class_context
|
||||
self._function = function
|
||||
|
||||
def __getattr__(self, name):
|
||||
return getattr(self._function, name)
|
||||
|
||||
def py__call__(self, var_args):
|
||||
function_execution = InstanceFunctionExecution(
|
||||
self._instance,
|
||||
self._class_context.parent_context,
|
||||
self._function.funcdef,
|
||||
var_args
|
||||
)
|
||||
return self._function.infer_function_execution(function_execution)
|
||||
|
||||
|
||||
class InstanceNameDefinition(TreeNameDefinition):
|
||||
@to_list
|
||||
def infer(self):
|
||||
contexts = super(InstanceNameDefinition, self).infer()
|
||||
from jedi.evaluate.representation import FunctionContext
|
||||
for context in contexts:
|
||||
"""
|
||||
if isinstance(contexts, FunctionContext):
|
||||
# TODO what about compiled objects?
|
||||
yield BoundMethod(context)
|
||||
else:
|
||||
"""
|
||||
yield context
|
||||
|
||||
class InstanceClassFilter(ParserTreeFilter):
|
||||
@@ -287,3 +290,30 @@ class LazyInstanceName(TreeNameDefinition):
|
||||
@property
|
||||
def parent_context(self):
|
||||
return self._instance.create_instance_context(self._class_context, self.name)
|
||||
|
||||
def infer(self):
|
||||
values = super(LazyInstanceName, self).infer()
|
||||
for v in values:
|
||||
if isinstance(v, er.FunctionContext):
|
||||
yield BoundMethod(self._instance, self._class_context, v)
|
||||
else:
|
||||
yield v
|
||||
|
||||
|
||||
class InstanceVarArgs(object):
|
||||
def __init__(self, instance, var_args):
|
||||
self._instance = instance
|
||||
self._var_args = var_args
|
||||
|
||||
def unpack(self, func=None):
|
||||
yield None, self._instance
|
||||
for values in self._var_args.unpack(func):
|
||||
yield values
|
||||
|
||||
|
||||
class InstanceFunctionExecution(er.FunctionExecutionContext):
|
||||
def __init__(self, instance, parent_context, funcdef, var_args):
|
||||
var_args = InstanceVarArgs(instance, var_args)
|
||||
|
||||
super(InstanceFunctionExecution, self).__init__(
|
||||
instance.evaluator, parent_context, funcdef, var_args)
|
||||
|
||||
@@ -244,10 +244,6 @@ def get_params(evaluator, parent_context, func, var_args):
|
||||
for param in func.params:
|
||||
param_dict[str(param.name)] = param
|
||||
unpacked_va = list(var_args.unpack(func))
|
||||
from jedi.evaluate.instance import TreeInstance
|
||||
if isinstance(parent_context, TreeInstance):
|
||||
# Include the self parameter here.
|
||||
unpacked_va.insert(0, (None, context.LazyKnownContext(parent_context)))
|
||||
var_arg_iterator = common.PushBackIterator(iter(unpacked_va))
|
||||
|
||||
non_matching_keys = defaultdict(lambda: [])
|
||||
|
||||
@@ -541,6 +541,15 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
|
||||
for filter in scope.get_filters(search_global=False, origin_scope=origin_scope):
|
||||
yield filter
|
||||
|
||||
def infer_function_execution(self, function_execution):
|
||||
"""
|
||||
Created to be used by inheritance.
|
||||
"""
|
||||
if self.base.is_generator():
|
||||
return set([iterable.Generator(self.evaluator, function_execution)])
|
||||
else:
|
||||
return function_execution.get_return_values()
|
||||
|
||||
@Python3Method
|
||||
def py__call__(self, params):
|
||||
function_execution = FunctionExecutionContext(
|
||||
@@ -549,10 +558,7 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
|
||||
self.base,
|
||||
params
|
||||
)
|
||||
if self.base.is_generator():
|
||||
return set([iterable.Generator(self.evaluator, function_execution)])
|
||||
else:
|
||||
return function_execution.get_return_values()
|
||||
return self.execute_function_(function_execution)
|
||||
|
||||
def py__class__(self):
|
||||
# This differentiation is only necessary for Python2. Python3 does not
|
||||
|
||||
Reference in New Issue
Block a user