diff --git a/jedi/api/classes.py b/jedi/api/classes.py index a1d3ce8a..f0dc1e22 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -63,11 +63,11 @@ class BaseDefinition(object): """ An instance of :class:`jedi.parser.reprsentation.Name` subclass. """ - self._definition = evaluator.wrap(self._name.get_definition()) - self.is_keyword = isinstance(self._definition, keywords.Keyword) + #self._definition = list(self._name.infer())[0] + #self.is_keyword = isinstance(self._definition, keywords.Keyword) # generate a path to the definition - self._module = name.get_parent_until() + self._module = name.parent_context.get_root_context() if self.in_builtin_module(): self.module_path = None else: @@ -508,6 +508,8 @@ class Completion(BaseDefinition): def _follow_statements_imports(self): # imports completion is very complicated and needs to be treated # separately in Completion. + return self._name.infer() + # TODO REMOVE definition = self._definition if definition.isinstance(tree.Import): i = imports.ImportWrapper(self._evaluator, self._name) diff --git a/jedi/api/completion.py b/jedi/api/completion.py index 0b27931e..adf77ae8 100644 --- a/jedi/api/completion.py +++ b/jedi/api/completion.py @@ -28,16 +28,12 @@ def get_call_signature_param_names(call_signatures): def filter_names(evaluator, completion_names, stack, like_name): comp_dct = {} - for name in set(completion_names): - print(name) + for name in completion_names: if settings.case_insensitive_completion \ - and str(name).lower().startswith(like_name.lower()) \ - or str(name).startswith(like_name): + and name.string_name.lower().startswith(like_name.lower()) \ + or name.string_name.startswith(like_name): - if isinstance(name.parent, (tree.Function, tree.Class)): - # TODO I think this is a hack. It should be an - # er.Function/er.Class before that. - name = evaluator.wrap(name.parent).name + print(name, name.infer()) new = classes.Completion( evaluator, name, diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index 456fd22d..ec5377bb 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -12,7 +12,7 @@ from jedi import debug from jedi.cache import underscore_memoization, memoize_method from jedi.parser.tree import Param, Base, Operator from jedi.evaluate.helpers import FakeName -from jedi.evaluate.filters import AbstractFilter +from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition from . import fake @@ -254,19 +254,18 @@ class CompiledObject(Base): return [] # Builtins don't have imports -class CompiledName(FakeName): +class CompiledName(AbstractNameDefinition): def __init__(self, evaluator, compiled_obj, name): - super(CompiledName, self).__init__(name) self._evaluator = evaluator self._compiled_obj = compiled_obj - self.name = name + self.string_name = name def __repr__(self): try: name = self._compiled_obj.name # __name__ is not defined all the time except AttributeError: name = None - return '<%s: (%s).%s>' % (type(self).__name__, name, self.name) + return '<%s: (%s).%s>' % (type(self).__name__, name, self.string_name) def is_definition(self): return True @@ -274,7 +273,7 @@ class CompiledName(FakeName): @underscore_memoization def infer(self): module = self._compiled_obj.get_parent_until() - return [_create_from_name(self._evaluator, module, self._compiled_obj, self.name)] + return [_create_from_name(self._evaluator, module, self._compiled_obj, self.string_name)] class LazyNamesDict(object): diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index 3fa28dad..b7146f5e 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -11,11 +11,7 @@ from jedi.common import to_list class AbstractNameDefinition(object): start_pos = None - - @property - @abstractmethod - def string_name(self): - raise NotImplementedError + string_name = None @abstractmethod def infer(self): @@ -44,7 +40,7 @@ class TreeNameDefinition(AbstractNameDefinition): return _name_to_types(self.parent_context._evaluator, self.parent_context, self._name, None) def __repr__(self): - return '%s: %s@%s' % (type(self).__name__, self.string_name, self.start_pos) + return '<%s: %s@%s>' % (type(self).__name__, self.string_name, self.start_pos) class AbstractFilter(object): @@ -122,6 +118,7 @@ class FunctionExecutionFilter(ParserTreeFilter): until_position=None, origin_scope=None): super(FunctionExecutionFilter, self).__init__( evaluator, + context, parser_scope, until_position, origin_scope diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 7e26db59..b9e4ba38 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -67,6 +67,13 @@ class Context(object): def get_parent_flow_context(self): return self.parent_context + def get_root_context(self): + context = self + while True: + if context.parent_context is None: + return context + context = context.parent_context + class FlowContext(Context): def get_parent_flow_context(self): @@ -74,7 +81,7 @@ class FlowContext(Context): return self.parent_context -class Executed(tree.Base): +class Executed(Context, tree.Base): """ An instance is also an executable - because __init__ is called :param var_args: The param input array, consist of a parser node or a list. @@ -279,8 +286,7 @@ class Instance(use_metaclass(CachedMetaClass, Executed)): def __getattr__(self, name): if name not in ['start_pos', 'end_pos', 'get_imports', 'type', 'doc', 'raw_doc']: - raise AttributeError("Instance %s: Don't touch this (%s)!" - % (self, name)) + return super(Instance, self).__getattribute__(name) return getattr(self.base, name) def __repr__(self): @@ -615,7 +621,7 @@ class ClassContext(use_metaclass(CachedMetaClass, Context, Wrapper)): if name not in ['start_pos', 'end_pos', 'parent', 'raw_doc', 'doc', 'get_imports', 'get_parent_until', 'get_code', 'subscopes', 'names_dict', 'type']: - raise AttributeError("Don't touch this: %s of %s !" % (name, self)) + return super(ClassContext, self).__getattribute__(name) return getattr(self.base, name) def __repr__(self): @@ -901,7 +907,7 @@ class FunctionExecution(Executed): def __getattr__(self, name): if name not in ['start_pos', 'end_pos', 'imports', 'name', 'type']: - raise AttributeError('Tried to access %s: %s. Why?' % (name, self)) + return super(FunctionExecution, self).__getattribute__(name) return getattr(self.base, name) @common.safe_property