forked from VimPlug/jedi
Working on __init__.
This commit is contained in:
@@ -515,15 +515,24 @@ class Evaluator(object):
|
||||
return element
|
||||
|
||||
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_scope = scope_node.get_parent_scope()
|
||||
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:
|
||||
return module_context
|
||||
elif scope_node.type == 'funcdef':
|
||||
elif is_funcdef:
|
||||
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
|
||||
return self.wrap(scope, parent_context=parent_context)
|
||||
|
||||
|
||||
@@ -258,6 +258,13 @@ class CompiledObject(Context):
|
||||
def get_imports(self):
|
||||
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):
|
||||
def __init__(self, evaluator, parent_context, name):
|
||||
|
||||
@@ -5,6 +5,8 @@ from jedi import debug
|
||||
from jedi.evaluate import compiled
|
||||
from jedi.evaluate.filters import ParserTreeFilter, ContextName, TreeNameDefinition
|
||||
from jedi.evaluate.context import Context
|
||||
from jedi.evaluate.cache import memoize_default
|
||||
from jedi.evaluate import representation as er
|
||||
|
||||
|
||||
class AbstractInstanceContext(Context):
|
||||
@@ -91,13 +93,13 @@ class AbstractInstanceContext(Context):
|
||||
if isinstance(cls, compiled.CompiledObject):
|
||||
yield SelfNameFilter(self.evaluator, self, cls, origin_scope)
|
||||
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__():
|
||||
if isinstance(cls, compiled.CompiledObject):
|
||||
yield CompiledInstanceClassFilter(self.evaluator, self, cls)
|
||||
else:
|
||||
yield InstanceClassFilter(self.evaluator, self, cls.classdef, origin_scope)
|
||||
yield InstanceClassFilter(self.evaluator, self, cls, origin_scope)
|
||||
|
||||
def py__getitem__(self, index):
|
||||
try:
|
||||
@@ -149,6 +151,31 @@ class TreeInstance(AbstractInstanceContext):
|
||||
def name(self):
|
||||
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):
|
||||
def __init__(self, evaluator, instance, compiled_object):
|
||||
@@ -190,13 +217,14 @@ class InstanceNameDefinition(TreeNameDefinition):
|
||||
class InstanceClassFilter(ParserTreeFilter):
|
||||
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__(
|
||||
evaluator=evaluator,
|
||||
context=context,
|
||||
parser_scope=parser_scope,
|
||||
parser_scope=class_context.classdef,
|
||||
origin_scope=origin_scope
|
||||
)
|
||||
self._class_context = class_context
|
||||
|
||||
def _equals_origin_scope(self):
|
||||
node = self._origin_scope
|
||||
@@ -217,6 +245,9 @@ class InstanceClassFilter(ParserTreeFilter):
|
||||
def _check_flows(self, names):
|
||||
return names
|
||||
|
||||
def _convert_names(self, names):
|
||||
return [LazyInstanceName(self._context, self._class_context, name) for name in names]
|
||||
|
||||
|
||||
class SelfNameFilter(InstanceClassFilter):
|
||||
def _filter(self, names):
|
||||
@@ -234,9 +265,25 @@ class SelfNameFilter(InstanceClassFilter):
|
||||
and len(trailer.children) == 2 \
|
||||
and trailer.children[0] == '.':
|
||||
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.
|
||||
if init_execution is not None and \
|
||||
init_execution.start_pos < name.start_pos < init_execution.end_pos:
|
||||
name = init_execution.name_for_position(name.start_pos)
|
||||
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
|
||||
from jedi.evaluate.dynamic import search_params
|
||||
from jedi.evaluate import context
|
||||
from jedi.evaluate.instance import TreeInstance
|
||||
|
||||
|
||||
class Executed(context.TreeContext):
|
||||
@@ -468,6 +467,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
|
||||
return [context.LazyKnownContext(compiled.create(self.evaluator, object))]
|
||||
|
||||
def py__call__(self, params):
|
||||
from jedi.evaluate.instance import TreeInstance
|
||||
return set([TreeInstance(self.evaluator, self.parent_context, self, params)])
|
||||
|
||||
def py__class__(self):
|
||||
|
||||
Reference in New Issue
Block a user