forked from VimPlug/jedi
Working on __init__.
This commit is contained in:
@@ -515,15 +515,24 @@ class Evaluator(object):
|
|||||||
return element
|
return element
|
||||||
|
|
||||||
def create_context(self, module_context, node):
|
def create_context(self, module_context, node):
|
||||||
def from_scope_node(scope_node):
|
def from_scope_node(scope_node, child_is_funcdef=None):
|
||||||
|
is_funcdef = scope_node.type == 'funcdef'
|
||||||
parent_context = None
|
parent_context = None
|
||||||
parent_scope = scope_node.get_parent_scope()
|
parent_scope = scope_node.get_parent_scope()
|
||||||
if parent_scope is not None:
|
if parent_scope is not None:
|
||||||
parent_context = from_scope_node(parent_scope)
|
parent_context = from_scope_node(parent_scope, child_is_funcdef=is_funcdef)
|
||||||
|
|
||||||
|
# TODO this whole procedure just ignores decorators
|
||||||
if scope_node == module_context.module_node:
|
if scope_node == module_context.module_node:
|
||||||
return module_context
|
return module_context
|
||||||
elif scope_node.type == 'funcdef':
|
elif is_funcdef:
|
||||||
return er.AnonymousFunctionExecution(self, parent_context, scope_node)
|
return er.AnonymousFunctionExecution(self, parent_context, scope_node)
|
||||||
|
elif scope_node.type == 'classdef':
|
||||||
|
if child_is_funcdef:
|
||||||
|
# anonymous instance
|
||||||
|
raise NotImplementedError
|
||||||
|
else:
|
||||||
|
return er.ClassContext(self, scope_node, parent_context)
|
||||||
raise DeprecationWarning
|
raise DeprecationWarning
|
||||||
return self.wrap(scope, parent_context=parent_context)
|
return self.wrap(scope, parent_context=parent_context)
|
||||||
|
|
||||||
|
|||||||
@@ -258,6 +258,13 @@ class CompiledObject(Context):
|
|||||||
def get_imports(self):
|
def get_imports(self):
|
||||||
return [] # Builtins don't have imports
|
return [] # Builtins don't have imports
|
||||||
|
|
||||||
|
@property
|
||||||
|
def classdef(self):
|
||||||
|
"""
|
||||||
|
This is used to be able to work with compiled fakes.
|
||||||
|
"""
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
class CompiledName(AbstractNameDefinition):
|
class CompiledName(AbstractNameDefinition):
|
||||||
def __init__(self, evaluator, parent_context, name):
|
def __init__(self, evaluator, parent_context, name):
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ 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
|
||||||
|
from jedi.evaluate.cache import memoize_default
|
||||||
|
from jedi.evaluate import representation as er
|
||||||
|
|
||||||
|
|
||||||
class AbstractInstanceContext(Context):
|
class AbstractInstanceContext(Context):
|
||||||
@@ -91,13 +93,13 @@ class AbstractInstanceContext(Context):
|
|||||||
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.classdef, 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:
|
||||||
yield InstanceClassFilter(self.evaluator, self, cls.classdef, origin_scope)
|
yield InstanceClassFilter(self.evaluator, self, cls, origin_scope)
|
||||||
|
|
||||||
def py__getitem__(self, index):
|
def py__getitem__(self, index):
|
||||||
try:
|
try:
|
||||||
@@ -149,6 +151,31 @@ class TreeInstance(AbstractInstanceContext):
|
|||||||
def name(self):
|
def name(self):
|
||||||
return ContextName(self, self._class_context.name)
|
return ContextName(self, self._class_context.name)
|
||||||
|
|
||||||
|
@memoize_default()
|
||||||
|
def create_instance_context(self, class_context, node):
|
||||||
|
scope = node.get_parent_scope()
|
||||||
|
if scope == class_context.classdef:
|
||||||
|
return self
|
||||||
|
else:
|
||||||
|
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,
|
||||||
|
scope,
|
||||||
|
self.var_args
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return er.AnonymousFunctionExecution(
|
||||||
|
self.evaluator,
|
||||||
|
self.parent_context,
|
||||||
|
scope,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError
|
||||||
|
return class_context
|
||||||
|
|
||||||
|
|
||||||
class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
|
class CompiledInstanceClassFilter(compiled.CompiledObjectFilter):
|
||||||
def __init__(self, evaluator, instance, compiled_object):
|
def __init__(self, evaluator, instance, compiled_object):
|
||||||
@@ -190,13 +217,14 @@ class InstanceNameDefinition(TreeNameDefinition):
|
|||||||
class InstanceClassFilter(ParserTreeFilter):
|
class InstanceClassFilter(ParserTreeFilter):
|
||||||
name_class = InstanceNameDefinition
|
name_class = InstanceNameDefinition
|
||||||
|
|
||||||
def __init__(self, evaluator, context, parser_scope, origin_scope):
|
def __init__(self, evaluator, context, class_context, origin_scope):
|
||||||
super(InstanceClassFilter, self).__init__(
|
super(InstanceClassFilter, self).__init__(
|
||||||
evaluator=evaluator,
|
evaluator=evaluator,
|
||||||
context=context,
|
context=context,
|
||||||
parser_scope=parser_scope,
|
parser_scope=class_context.classdef,
|
||||||
origin_scope=origin_scope
|
origin_scope=origin_scope
|
||||||
)
|
)
|
||||||
|
self._class_context = class_context
|
||||||
|
|
||||||
def _equals_origin_scope(self):
|
def _equals_origin_scope(self):
|
||||||
node = self._origin_scope
|
node = self._origin_scope
|
||||||
@@ -217,6 +245,9 @@ class InstanceClassFilter(ParserTreeFilter):
|
|||||||
def _check_flows(self, names):
|
def _check_flows(self, names):
|
||||||
return names
|
return names
|
||||||
|
|
||||||
|
def _convert_names(self, names):
|
||||||
|
return [LazyInstanceName(self._context, self._class_context, name) for name in names]
|
||||||
|
|
||||||
|
|
||||||
class SelfNameFilter(InstanceClassFilter):
|
class SelfNameFilter(InstanceClassFilter):
|
||||||
def _filter(self, names):
|
def _filter(self, names):
|
||||||
@@ -234,9 +265,25 @@ class SelfNameFilter(InstanceClassFilter):
|
|||||||
and len(trailer.children) == 2 \
|
and len(trailer.children) == 2 \
|
||||||
and trailer.children[0] == '.':
|
and trailer.children[0] == '.':
|
||||||
if name.is_definition() and self._access_possible(name):
|
if name.is_definition() and self._access_possible(name):
|
||||||
init_execution = self._context._get_init_execution()
|
yield name
|
||||||
|
continue
|
||||||
|
init_execution = self._context.get_init_function()
|
||||||
# Hopefully we can somehow change this.
|
# Hopefully we can somehow change this.
|
||||||
if init_execution is not None and \
|
if init_execution is not None and \
|
||||||
init_execution.start_pos < name.start_pos < init_execution.end_pos:
|
init_execution.start_pos < name.start_pos < init_execution.end_pos:
|
||||||
name = init_execution.name_for_position(name.start_pos)
|
name = init_execution.name_for_position(name.start_pos)
|
||||||
yield name
|
yield name
|
||||||
|
|
||||||
|
|
||||||
|
class LazyInstanceName(TreeNameDefinition):
|
||||||
|
"""
|
||||||
|
This name calculates the parent_context lazily.
|
||||||
|
"""
|
||||||
|
def __init__(self, instance, class_context, name):
|
||||||
|
self._instance = instance
|
||||||
|
self._class_context = class_context
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_context(self):
|
||||||
|
return self._instance.create_instance_context(self._class_context, self.name)
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \
|
|||||||
GlobalNameFilter, DictFilter, ContextName
|
GlobalNameFilter, DictFilter, ContextName
|
||||||
from jedi.evaluate.dynamic import search_params
|
from jedi.evaluate.dynamic import search_params
|
||||||
from jedi.evaluate import context
|
from jedi.evaluate import context
|
||||||
from jedi.evaluate.instance import TreeInstance
|
|
||||||
|
|
||||||
|
|
||||||
class Executed(context.TreeContext):
|
class Executed(context.TreeContext):
|
||||||
@@ -468,6 +467,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
|
|||||||
return [context.LazyKnownContext(compiled.create(self.evaluator, object))]
|
return [context.LazyKnownContext(compiled.create(self.evaluator, object))]
|
||||||
|
|
||||||
def py__call__(self, params):
|
def py__call__(self, params):
|
||||||
|
from jedi.evaluate.instance import TreeInstance
|
||||||
return set([TreeInstance(self.evaluator, self.parent_context, self, params)])
|
return set([TreeInstance(self.evaluator, self.parent_context, self, params)])
|
||||||
|
|
||||||
def py__class__(self):
|
def py__class__(self):
|
||||||
|
|||||||
Reference in New Issue
Block a user