1
0
forked from VimPlug/jedi

Implementation of BoundMethod.

This commit is contained in:
Dave Halter
2016-11-06 22:33:22 +01:00
parent afac66d82c
commit cd4a7a9fc3
4 changed files with 55 additions and 23 deletions

View File

@@ -52,7 +52,7 @@ class AbstractLazyContext(object):
class LazyKnownContext(AbstractLazyContext): class LazyKnownContext(AbstractLazyContext):
"""data is a context.""" """data is a context."""
def infer(self): def infer(self):
return set([self._data]) yield self._data
class LazyKnownContexts(AbstractLazyContext): class LazyKnownContexts(AbstractLazyContext):

View File

@@ -160,16 +160,16 @@ class TreeInstance(AbstractInstanceContext):
parent_context = self.create_instance_context(class_context, scope) parent_context = self.create_instance_context(class_context, scope)
if scope.type == 'funcdef': if scope.type == 'funcdef':
if scope.name.value == '__init__' and parent_context == self: if scope.name.value == '__init__' and parent_context == self:
return er.FunctionExecutionContext( return InstanceFunctionExecution(
self.evaluator, self,
self.parent_context, class_context.parent_context,
scope, scope,
self.var_args self.var_args
) )
else: else:
return er.AnonymousFunctionExecution( return er.AnonymousFunctionExecution(
self.evaluator, self.evaluator,
self.parent_context, class_context.parent_context,
scope, scope,
) )
else: else:
@@ -193,26 +193,29 @@ class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
class BoundMethod(object): 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 self._function = function
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self._function, 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): class InstanceNameDefinition(TreeNameDefinition):
@to_list
def infer(self): def infer(self):
contexts = super(InstanceNameDefinition, self).infer() contexts = super(InstanceNameDefinition, self).infer()
from jedi.evaluate.representation import FunctionContext
for context in contexts: for context in contexts:
""" yield context
if isinstance(contexts, FunctionContext):
# TODO what about compiled objects?
yield BoundMethod(context)
else:
"""
yield context
class InstanceClassFilter(ParserTreeFilter): class InstanceClassFilter(ParserTreeFilter):
name_class = InstanceNameDefinition name_class = InstanceNameDefinition
@@ -287,3 +290,30 @@ class LazyInstanceName(TreeNameDefinition):
@property @property
def parent_context(self): def parent_context(self):
return self._instance.create_instance_context(self._class_context, self.name) 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)

View File

@@ -244,10 +244,6 @@ def get_params(evaluator, parent_context, func, var_args):
for param in func.params: for param in func.params:
param_dict[str(param.name)] = param param_dict[str(param.name)] = param
unpacked_va = list(var_args.unpack(func)) 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)) var_arg_iterator = common.PushBackIterator(iter(unpacked_va))
non_matching_keys = defaultdict(lambda: []) non_matching_keys = defaultdict(lambda: [])

View File

@@ -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): for filter in scope.get_filters(search_global=False, origin_scope=origin_scope):
yield filter 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 @Python3Method
def py__call__(self, params): def py__call__(self, params):
function_execution = FunctionExecutionContext( function_execution = FunctionExecutionContext(
@@ -549,10 +558,7 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
self.base, self.base,
params params
) )
if self.base.is_generator(): return self.execute_function_(function_execution)
return set([iterable.Generator(self.evaluator, function_execution)])
else:
return function_execution.get_return_values()
def py__class__(self): def py__class__(self):
# This differentiation is only necessary for Python2. Python3 does not # This differentiation is only necessary for Python2. Python3 does not