1
0
forked from VimPlug/jedi

More instance improvements.

This commit is contained in:
Dave Halter
2016-11-06 23:50:29 +01:00
parent cd4a7a9fc3
commit 7f95495ca5
4 changed files with 46 additions and 37 deletions

View File

@@ -36,17 +36,17 @@ class AbstractNameDefinition(object):
class ContextName(AbstractNameDefinition): class ContextName(AbstractNameDefinition):
def __init__(self, parent_context, name): def __init__(self, parent_context, tree_name):
self.parent_context = parent_context self.parent_context = parent_context
self.name = name self.tree_name = tree_name
@property @property
def string_name(self): def string_name(self):
return self.name.value return self.tree_name.value
@property @property
def start_pos(self): def start_pos(self):
return self.name.start_pos return self.tree_name.start_pos
def infer(self): def infer(self):
return [self.parent_context] return [self.parent_context]
@@ -59,20 +59,20 @@ class TreeNameDefinition(ContextName):
def infer(self): def infer(self):
# Refactor this, should probably be here. # Refactor this, should probably be here.
from jedi.evaluate.finder import _name_to_types from jedi.evaluate.finder import _name_to_types
return _name_to_types(self.parent_context.evaluator, self.parent_context, self.name, None) return _name_to_types(self.parent_context.evaluator, self.parent_context, self.tree_name, None)
class ParamName(ContextName): class ParamName(ContextName):
def __init__(self, parent_context, name): def __init__(self, parent_context, tree_name):
self.parent_context = parent_context self.parent_context = parent_context
self.name = name self.tree_name = tree_name
def infer(self): def infer(self):
return self._get_param().infer() return self._get_param().infer()
def _get_param(self): def _get_param(self):
params = self.parent_context.get_params() params = self.parent_context.get_params()
return params[self.name.parent.position_nr] return params[self.tree_name.parent.position_nr]
class AbstractFilter(object): class AbstractFilter(object):

View File

@@ -325,7 +325,7 @@ class NameFinder(object):
# The name must not be in the dictionary, but part of the class # The name must not be in the dictionary, but part of the class
# definition. __get__ is only called if the descriptor is defined in # definition. __get__ is only called if the descriptor is defined in
# the class dictionary. # the class dictionary.
name_scope = name.get_definition().get_parent_scope() name_scope = name.tree_name.get_definition().get_parent_scope()
if not isinstance(name_scope, (er.Instance, tree.Class)): if not isinstance(name_scope, (er.Instance, tree.Class)):
return types return types

View File

@@ -4,7 +4,7 @@ from jedi.common import unite, to_list
from jedi import debug from jedi import debug
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate.filters import ParserTreeFilter, ContextName, TreeNameDefinition from jedi.evaluate.filters import ParserTreeFilter, ContextName, TreeNameDefinition
from jedi.evaluate.context import Context from jedi.evaluate.context import Context, LazyKnownContext
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import memoize_default
from jedi.evaluate import representation as er from jedi.evaluate import representation as er
@@ -17,7 +17,7 @@ class AbstractInstanceContext(Context):
super(AbstractInstanceContext, self).__init__(evaluator, parent_context) super(AbstractInstanceContext, self).__init__(evaluator, parent_context)
# Generated instances are classes that are just generated by self # Generated instances are classes that are just generated by self
# (No var_args) used. # (No var_args) used.
self._class_context = class_context self.class_context = class_context
self.var_args = var_args self.var_args = var_args
##### #####
@@ -69,33 +69,37 @@ class AbstractInstanceContext(Context):
return names return names
return [] return []
def execute_function_slot(self, name, *args): def execute_function_slots(self, names, *evaluated_args):
raise NotImplementedError return unite(
method = self.get_subscope_by_name(name) self.evaluator.execute_evaluated(method, *evaluated_args)
return self.evaluator.execute_evaluated(method, *args) for name in names
for method in name.infer()
)
def get_descriptor_returns(self, obj): def get_descriptor_returns(self, obj):
""" Throws a KeyError if there's no method. """ """ Throws a KeyError if there's no method. """
raise NotImplementedError
# Arguments in __get__ descriptors are obj, class. # Arguments in __get__ descriptors are obj, class.
# `method` is the new parent of the array, don't know if that's good. # `method` is the new parent of the array, don't know if that's good.
none_obj = compiled.create(self.evaluator, None) names = self._get_function_slot_names('__get__')
args = [obj, obj.base] if isinstance(obj, Instance) else [none_obj, obj] if names:
try: if isinstance(obj, AbstractInstanceContext):
return self.execute_subscope_by_name('__get__', *args) return self.execute_function_slots(names, obj, obj.class_context)
except KeyError: else:
none_obj = compiled.create(self.evaluator, None)
return self.execute_function_slots(names, none_obj, obj)
else:
return set([self]) return set([self])
def get_filters(self, search_global=None, until_position=None, def get_filters(self, search_global=None, until_position=None,
origin_scope=None, include_self_names=True): origin_scope=None, include_self_names=True):
if include_self_names: if include_self_names:
for cls in self._class_context.py__mro__(): for cls in self.class_context.py__mro__():
if isinstance(cls, compiled.CompiledObject): if isinstance(cls, compiled.CompiledObject):
yield SelfNameFilter(self.evaluator, self, cls, origin_scope) yield SelfNameFilter(self.evaluator, self, cls, origin_scope)
else: else:
yield SelfNameFilter(self.evaluator, self, cls, origin_scope) yield SelfNameFilter(self.evaluator, self, cls, origin_scope)
for cls in self._class_context.py__mro__(): for cls in self.class_context.py__mro__():
if isinstance(cls, compiled.CompiledObject): if isinstance(cls, compiled.CompiledObject):
yield CompiledInstanceClassFilter(self.evaluator, self, cls) yield CompiledInstanceClassFilter(self.evaluator, self, cls)
else: else:
@@ -136,20 +140,20 @@ class AbstractInstanceContext(Context):
pass pass
def __repr__(self): def __repr__(self):
return "<%s of %s(%s)>" % (type(self).__name__, self._class_context, return "<%s of %s(%s)>" % (type(self).__name__, self.class_context,
self.var_args) self.var_args)
class CompiledInstance(AbstractInstanceContext): class CompiledInstance(AbstractInstanceContext):
@property @property
def name(self): def name(self):
return compiled.CompiledContextName(self, self._class_context.name.string_name) return compiled.CompiledContextName(self, self.class_context.name.string_name)
class TreeInstance(AbstractInstanceContext): class TreeInstance(AbstractInstanceContext):
@property @property
def name(self): def name(self):
return ContextName(self, self._class_context.name) return ContextName(self, self.class_context.name.tree_name)
@memoize_default() @memoize_default()
def create_instance_context(self, class_context, node): def create_instance_context(self, class_context, node):
@@ -282,14 +286,14 @@ class LazyInstanceName(TreeNameDefinition):
""" """
This name calculates the parent_context lazily. This name calculates the parent_context lazily.
""" """
def __init__(self, instance, class_context, name): def __init__(self, instance, class_context, tree_name):
self._instance = instance self._instance = instance
self._class_context = class_context self._class_context = class_context
self.name = name self.tree_name = tree_name
@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.tree_name)
def infer(self): def infer(self):
values = super(LazyInstanceName, self).infer() values = super(LazyInstanceName, self).infer()
@@ -306,10 +310,13 @@ class InstanceVarArgs(object):
self._var_args = var_args self._var_args = var_args
def unpack(self, func=None): def unpack(self, func=None):
yield None, self._instance yield None, LazyKnownContext(self._instance)
for values in self._var_args.unpack(func): for values in self._var_args.unpack(func):
yield values yield values
def get_calling_var_args(self):
return self._var_args.get_calling_var_args()
class InstanceFunctionExecution(er.FunctionExecutionContext): class InstanceFunctionExecution(er.FunctionExecutionContext):
def __init__(self, instance, parent_context, funcdef, var_args): def __init__(self, instance, parent_context, funcdef, var_args):

View File

@@ -405,12 +405,6 @@ class Wrapper(tree.Base):
""" """
return True return True
@property
@underscore_memoization
def name(self):
name = self.base.name
return ContextName(self, name)
class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)): class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
""" """
@@ -515,6 +509,10 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
def __repr__(self): def __repr__(self):
return "<%s of %s>" % (type(self).__name__, self.classdef) return "<%s of %s>" % (type(self).__name__, self.classdef)
@property
def name(self):
return ContextName(self, self.classdef.name)
class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)): class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
""" """
@@ -558,7 +556,7 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
self.base, self.base,
params params
) )
return self.execute_function_(function_execution) return self.infer_function_execution(function_execution)
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
@@ -572,6 +570,10 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
def __repr__(self): def __repr__(self):
return "<%s of %s>" % (type(self).__name__, self.base_func) return "<%s of %s>" % (type(self).__name__, self.base_func)
@property
def name(self):
return ContextName(self, self.funcdef.name)
class LambdaWrapper(FunctionContext): class LambdaWrapper(FunctionContext):
def get_decorated_func(self): def get_decorated_func(self):