forked from VimPlug/jedi
as_context caching
This commit is contained in:
@@ -222,7 +222,11 @@ class Value(HelperValueMixin, BaseValue):
|
|||||||
# The root value knows if it's a stub or not.
|
# The root value knows if it's a stub or not.
|
||||||
return self.parent_context.is_stub()
|
return self.parent_context.is_stub()
|
||||||
|
|
||||||
|
@memoize_method
|
||||||
def as_context(self):
|
def as_context(self):
|
||||||
|
return self._as_context()
|
||||||
|
|
||||||
|
def _as_context(self):
|
||||||
raise NotImplementedError('Not all values need to be converted to contexts')
|
raise NotImplementedError('Not all values need to be converted to contexts')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ class CompiledObject(Value):
|
|||||||
def get_metaclasses(self):
|
def get_metaclasses(self):
|
||||||
return NO_VALUES
|
return NO_VALUES
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return AbstractContext(self)
|
return AbstractContext(self)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class TypingModuleWrapper(StubModuleValue):
|
|||||||
for f in filters:
|
for f in filters:
|
||||||
yield f
|
yield f
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return TypingModuleContext(self)
|
return TypingModuleContext(self)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -626,7 +626,7 @@ class AbstractAnnotatedClass(ClassMixin, ValueWrapper):
|
|||||||
generics=tuple(new_generics)
|
generics=tuple(new_generics)
|
||||||
)])
|
)])
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return AnnotatedClassContext(self)
|
return AnnotatedClassContext(self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
@@ -37,14 +37,17 @@ def _find_names(module_context, tree_name):
|
|||||||
def usages(module_context, tree_name):
|
def usages(module_context, tree_name):
|
||||||
search_name = tree_name.value
|
search_name = tree_name.value
|
||||||
found_names = _find_names(module_context, tree_name)
|
found_names = _find_names(module_context, tree_name)
|
||||||
modules = set(d.get_root_context() for d in found_names.values())
|
module_contexts = set(d.get_root_context() for d in found_names.values())
|
||||||
modules = set(m for m in modules if m.is_module() and not m.is_compiled())
|
module_contexts = set(m for m in module_contexts if not m.is_compiled())
|
||||||
|
|
||||||
non_matching_usage_maps = {}
|
non_matching_usage_maps = {}
|
||||||
inf = module_context.inference_state
|
inf = module_context.inference_state
|
||||||
for m in imports.get_modules_containing_name(inf, modules, search_name):
|
potential_modules = imports.get_module_contexts_containing_name(
|
||||||
for name_leaf in m.tree_node.get_used_names().get(search_name, []):
|
inf, module_contexts, search_name
|
||||||
new = _find_names(m, name_leaf)
|
)
|
||||||
|
for module_context in potential_modules:
|
||||||
|
for name_leaf in module_context.tree_node.get_used_names().get(search_name, []):
|
||||||
|
new = _find_names(module_context, name_leaf)
|
||||||
if any(tree_name in found_names for tree_name in new):
|
if any(tree_name in found_names for tree_name in new):
|
||||||
found_names.update(new)
|
found_names.update(new)
|
||||||
for tree_name in new:
|
for tree_name in new:
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class FunctionMixin(object):
|
|||||||
|
|
||||||
return FunctionExecutionContext(self, arguments)
|
return FunctionExecutionContext(self, arguments)
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return self.get_function_execution()
|
return self.get_function_execution()
|
||||||
|
|
||||||
def get_signatures(self):
|
def get_signatures(self):
|
||||||
@@ -110,7 +110,7 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla
|
|||||||
if context.is_class():
|
if context.is_class():
|
||||||
return MethodValue(
|
return MethodValue(
|
||||||
context.inference_state,
|
context.inference_state,
|
||||||
context,
|
context._value, # TODO private access!
|
||||||
parent_context=parent_context,
|
parent_context=parent_context,
|
||||||
tree_node=tree_node
|
tree_node=tree_node
|
||||||
)
|
)
|
||||||
@@ -148,17 +148,17 @@ class FunctionValue(use_metaclass(CachedMetaClass, FunctionMixin, FunctionAndCla
|
|||||||
|
|
||||||
|
|
||||||
class MethodValue(FunctionValue):
|
class MethodValue(FunctionValue):
|
||||||
def __init__(self, inference_state, class_context, *args, **kwargs):
|
def __init__(self, inference_state, class_value, *args, **kwargs):
|
||||||
super(MethodValue, self).__init__(inference_state, *args, **kwargs)
|
super(MethodValue, self).__init__(inference_state, *args, **kwargs)
|
||||||
self.class_context = class_context
|
self.class_value = class_value
|
||||||
|
|
||||||
def get_default_param_context(self):
|
def get_default_param_context(self):
|
||||||
return self.class_context
|
return self.class_value
|
||||||
|
|
||||||
def get_qualified_names(self):
|
def get_qualified_names(self):
|
||||||
# Need to implement this, because the parent value of a method
|
# Need to implement this, because the parent value of a method
|
||||||
# value is not the class value but the module.
|
# value is not the class value but the module.
|
||||||
names = self.class_context.get_qualified_names()
|
names = self.class_value.get_qualified_names()
|
||||||
if names is None:
|
if names is None:
|
||||||
return None
|
return None
|
||||||
return names + (self.py__name__(),)
|
return names + (self.py__name__(),)
|
||||||
|
|||||||
@@ -198,33 +198,33 @@ class AbstractInstanceValue(Value):
|
|||||||
yield bound_method.get_function_execution(self.var_args)
|
yield bound_method.get_function_execution(self.var_args)
|
||||||
|
|
||||||
@inference_state_method_cache()
|
@inference_state_method_cache()
|
||||||
def create_instance_value(self, class_value, node):
|
def create_instance_context(self, class_context, node):
|
||||||
if node.parent.type in ('funcdef', 'classdef'):
|
if node.parent.type in ('funcdef', 'classdef'):
|
||||||
node = node.parent
|
node = node.parent
|
||||||
scope = get_parent_scope(node)
|
scope = get_parent_scope(node)
|
||||||
if scope == class_value.tree_node:
|
if scope == class_context.tree_node:
|
||||||
return class_value
|
return class_context
|
||||||
else:
|
else:
|
||||||
parent_context = self.create_instance_value(class_value, scope)
|
parent_context = self.create_instance_context(class_context, scope)
|
||||||
if scope.type == 'funcdef':
|
if scope.type == 'funcdef':
|
||||||
func = FunctionValue.from_context(
|
func = FunctionValue.from_context(
|
||||||
parent_context,
|
parent_context,
|
||||||
scope,
|
scope,
|
||||||
)
|
)
|
||||||
bound_method = BoundMethod(self, func)
|
bound_method = BoundMethod(self, func)
|
||||||
if scope.name.value == '__init__' and parent_context == class_value:
|
if scope.name.value == '__init__' and parent_context == class_context:
|
||||||
return bound_method.get_function_execution(self.var_args)
|
return bound_method.get_function_execution(self.var_args)
|
||||||
else:
|
else:
|
||||||
return bound_method.get_function_execution()
|
return bound_method.get_function_execution()
|
||||||
elif scope.type == 'classdef':
|
elif scope.type == 'classdef':
|
||||||
class_value = ClassValue(self.inference_state, parent_context, scope)
|
class_context = ClassValue(self.inference_state, parent_context, scope)
|
||||||
return class_value
|
return class_context.as_context()
|
||||||
elif scope.type in ('comp_for', 'sync_comp_for'):
|
elif scope.type in ('comp_for', 'sync_comp_for'):
|
||||||
# Comprehensions currently don't have a special scope in Jedi.
|
# Comprehensions currently don't have a special scope in Jedi.
|
||||||
return self.create_instance_value(class_value, scope)
|
return self.create_instance_context(class_context, scope)
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
return class_value
|
return class_context
|
||||||
|
|
||||||
def get_signatures(self):
|
def get_signatures(self):
|
||||||
call_funcs = self.py__getattribute__('__call__').py__get__(self, self.class_value)
|
call_funcs = self.py__getattribute__('__call__').py__get__(self, self.class_value)
|
||||||
@@ -425,7 +425,10 @@ class SelfName(TreeNameDefinition):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def parent_context(self):
|
def parent_context(self):
|
||||||
return self._instance.create_instance_value(self.class_value, self.tree_name)
|
return self._instance.create_instance_context(
|
||||||
|
self.class_value.as_context(),
|
||||||
|
self.tree_name
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LazyInstanceClassName(object):
|
class LazyInstanceClassName(object):
|
||||||
|
|||||||
@@ -674,8 +674,8 @@ def _check_array_additions(context, sequence):
|
|||||||
debug.dbg('Dynamic array search aborted.', color='MAGENTA')
|
debug.dbg('Dynamic array search aborted.', color='MAGENTA')
|
||||||
return NO_VALUES
|
return NO_VALUES
|
||||||
|
|
||||||
def find_additions(value, arglist, add_name):
|
def find_additions(context, arglist, add_name):
|
||||||
params = list(arguments.TreeArguments(value.inference_state, value, arglist).unpack())
|
params = list(arguments.TreeArguments(context.inference_state, context, arglist).unpack())
|
||||||
result = set()
|
result = set()
|
||||||
if add_name in ['insert']:
|
if add_name in ['insert']:
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
@@ -717,7 +717,6 @@ def _check_array_additions(context, sequence):
|
|||||||
or execution_trailer.children[1] == ')':
|
or execution_trailer.children[1] == ')':
|
||||||
continue
|
continue
|
||||||
|
|
||||||
raise NotImplementedError
|
|
||||||
random_context = context.create_context(name)
|
random_context = context.create_context(name)
|
||||||
|
|
||||||
with recursion.execution_allowed(context.inference_state, power) as allowed:
|
with recursion.execution_allowed(context.inference_state, power) as allowed:
|
||||||
@@ -783,8 +782,8 @@ class _ArrayInstance(HelperValueMixin):
|
|||||||
|
|
||||||
|
|
||||||
class Slice(object):
|
class Slice(object):
|
||||||
def __init__(self, value, start, stop, step):
|
def __init__(self, python_value, start, stop, step):
|
||||||
self._value = value
|
self._python_value = python_value
|
||||||
self._slice_object = None
|
self._slice_object = None
|
||||||
# All of them are either a Precedence or None.
|
# All of them are either a Precedence or None.
|
||||||
self._start = start
|
self._start = start
|
||||||
@@ -793,7 +792,7 @@ class Slice(object):
|
|||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
if self._slice_object is None:
|
if self._slice_object is None:
|
||||||
value = compiled.builtin_from_name(self._value.inference_state, 'slice')
|
value = compiled.builtin_from_name(self._python_value.inference_state, 'slice')
|
||||||
self._slice_object, = value.execute_with_values()
|
self._slice_object, = value.execute_with_values()
|
||||||
return getattr(self._slice_object, name)
|
return getattr(self._slice_object, name)
|
||||||
|
|
||||||
@@ -807,7 +806,7 @@ class Slice(object):
|
|||||||
if element is None:
|
if element is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
result = self._value.infer_node(element)
|
result = self._python_value.infer_node(element)
|
||||||
if len(result) != 1:
|
if len(result) != 1:
|
||||||
# For simplicity, we want slices to be clear defined with just
|
# For simplicity, we want slices to be clear defined with just
|
||||||
# one type. Otherwise we will return an empty slice object.
|
# one type. Otherwise we will return an empty slice object.
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ class ClassMixin(object):
|
|||||||
init_funcs = self.py__call__().py__getattribute__('__init__')
|
init_funcs = self.py__call__().py__getattribute__('__init__')
|
||||||
return [sig.bind(self) for sig in init_funcs.get_signatures()]
|
return [sig.bind(self) for sig in init_funcs.get_signatures()]
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return ClassContext(self)
|
return ClassContext(self)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ class ModuleValue(ModuleMixin, TreeValue):
|
|||||||
else:
|
else:
|
||||||
raise AttributeError('Only packages have __path__ attributes.')
|
raise AttributeError('Only packages have __path__ attributes.')
|
||||||
|
|
||||||
def as_context(self):
|
def _as_context(self):
|
||||||
return ModuleContext(self)
|
return ModuleContext(self)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user