forked from VimPlug/jedi
REPL completion is working again partially. There's some progress at least.
This commit is contained in:
@@ -367,19 +367,11 @@ class Interpreter(Script):
|
|||||||
super(Interpreter, self).__init__(source, **kwds)
|
super(Interpreter, self).__init__(source, **kwds)
|
||||||
self.namespaces = namespaces
|
self.namespaces = namespaces
|
||||||
|
|
||||||
# Don't use the fast parser, because it does crazy stuff that we don't
|
parser_module = super(Interpreter, self)._get_module()
|
||||||
# need in our very simple and small code here (that is always
|
self._module = interpreter.MixedModule(self._evaluator, parser_module, self.namespaces)
|
||||||
# changing).
|
|
||||||
self._parser = UserContextParser(self._grammar, self._source,
|
|
||||||
self._orig_path, self._pos,
|
|
||||||
self._parsed_callback,
|
|
||||||
use_fast_parser=False)
|
|
||||||
#interpreter.add_namespaces_to_parser(self._evaluator, namespaces,
|
|
||||||
#self._get_module())
|
|
||||||
|
|
||||||
def _get_module(self):
|
def _get_module(self):
|
||||||
parser_module = super(Interpreter, self)._get_module()
|
return self._module
|
||||||
return interpreter.MixedModule(parser_module, self.namespaces)
|
|
||||||
|
|
||||||
|
|
||||||
def defined_names(source, path=None, encoding='utf-8'):
|
def defined_names(source, path=None, encoding='utf-8'):
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ from jedi.evaluate import representation as er
|
|||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
|
from jedi.evaluate.compiled import mixed
|
||||||
from jedi.api import keywords
|
from jedi.api import keywords
|
||||||
from jedi.evaluate.finder import filter_definition_names
|
from jedi.evaluate.finder import filter_definition_names
|
||||||
|
|
||||||
@@ -148,7 +149,7 @@ class BaseDefinition(object):
|
|||||||
if isinstance(stripped, er.InstanceElement):
|
if isinstance(stripped, er.InstanceElement):
|
||||||
stripped = stripped.var
|
stripped = stripped.var
|
||||||
|
|
||||||
if isinstance(stripped, compiled.CompiledObject):
|
if isinstance(stripped, (compiled.CompiledObject, mixed.MixedObject)):
|
||||||
return stripped.api_type()
|
return stripped.api_type()
|
||||||
elif isinstance(stripped, iterable.Array):
|
elif isinstance(stripped, iterable.Array):
|
||||||
return 'instance'
|
return 'instance'
|
||||||
|
|||||||
@@ -15,37 +15,38 @@ from jedi.parser import load_grammar
|
|||||||
from jedi.parser.fast import FastParser
|
from jedi.parser.fast import FastParser
|
||||||
from jedi.evaluate import helpers
|
from jedi.evaluate import helpers
|
||||||
from jedi.evaluate import iterable
|
from jedi.evaluate import iterable
|
||||||
|
from jedi.evaluate.representation import ModuleWrapper
|
||||||
from jedi.evaluate.compiled import mixed
|
from jedi.evaluate.compiled import mixed
|
||||||
|
|
||||||
|
|
||||||
def add_namespaces_to_parser(evaluator, namespace_dicts, parser_module):
|
class MixedModule(object):
|
||||||
for dct in namespace_dicts:
|
resets_positions = True
|
||||||
namespace = compiled.CompiledObject(evaluator, type('namespace', (), dct))
|
|
||||||
|
|
||||||
for key, value in dct.items():
|
|
||||||
# Name lookups in an ast tree work by checking names_dict.
|
|
||||||
# Therefore we just add fake names to that and we're done.
|
|
||||||
arr = parser_module.names_dict.setdefault(key, [])
|
|
||||||
name = mixed.MixedName(evaluator, namespace, key)
|
|
||||||
arr.append(name)
|
|
||||||
#arr.append(LazyName(evaluator, parser_module, key, value))
|
|
||||||
|
|
||||||
|
|
||||||
class MixedModule():
|
|
||||||
def __init__(self, evaluator, parser_module, namespaces):
|
def __init__(self, evaluator, parser_module, namespaces):
|
||||||
self._evaluator = evaluator
|
self._evaluator = evaluator
|
||||||
self._parser_module = parser_module
|
|
||||||
self._namespaces = namespaces
|
self._namespaces = namespaces
|
||||||
|
|
||||||
def names_dicts(self):
|
self._namespace_objects = [type('jedi_namespace', (), n) for n in namespaces]
|
||||||
for names_dict in self._parser_module.names_dicts():
|
self._wrapped_module = ModuleWrapper(evaluator, parser_module)
|
||||||
|
# Usually we are dealing with very small code sizes when it comes to
|
||||||
|
# interpreter modules. In this case we just copy the whole syntax tree
|
||||||
|
# to be able to modify it.
|
||||||
|
self._parser_module = helpers.deep_ast_copy(parser_module)
|
||||||
|
|
||||||
|
for child in self._parser_module.children:
|
||||||
|
child.parent = self
|
||||||
|
|
||||||
|
def names_dicts(self, search_global):
|
||||||
|
for names_dict in self._wrapped_module.names_dicts(search_global):
|
||||||
yield names_dict
|
yield names_dict
|
||||||
|
|
||||||
for namespace in self._namespaces:
|
for namespace_obj in self._namespace_objects:
|
||||||
print('ole')
|
m = mixed.MixedObject(self._evaluator, namespace_obj, self._parser_module.name)
|
||||||
yield mixed.MixedObject(self._evaluator, namespace, self._parser_module.name)
|
for names_dict in m.names_dicts(False):
|
||||||
|
yield names_dict
|
||||||
|
|
||||||
yield namespace
|
def __getattr__(self, name):
|
||||||
|
return getattr(self._parser_module, name)
|
||||||
|
|
||||||
|
|
||||||
class LazyName(helpers.FakeName):
|
class LazyName(helpers.FakeName):
|
||||||
@@ -125,7 +126,7 @@ class LazyName(helpers.FakeName):
|
|||||||
'should be part of sys.modules.')
|
'should be part of sys.modules.')
|
||||||
|
|
||||||
if parser_path:
|
if parser_path:
|
||||||
#assert len(parser_path) == 1
|
assert len(parser_path) == 1
|
||||||
found = list(self._evaluator.find_types(mod, parser_path[0],
|
found = list(self._evaluator.find_types(mod, parser_path[0],
|
||||||
search_global=True))
|
search_global=True))
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ class CompiledObject(Base):
|
|||||||
elif inspect.isbuiltin(cls) or inspect.ismethod(cls) \
|
elif inspect.isbuiltin(cls) or inspect.ismethod(cls) \
|
||||||
or inspect.ismethoddescriptor(cls) or inspect.isfunction(cls):
|
or inspect.ismethoddescriptor(cls) or inspect.isfunction(cls):
|
||||||
return 'function'
|
return 'function'
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import inspect
|
|||||||
from jedi import common
|
from jedi import common
|
||||||
from jedi.parser.fast import FastParser
|
from jedi.parser.fast import FastParser
|
||||||
from jedi.evaluate import compiled
|
from jedi.evaluate import compiled
|
||||||
from jedi.cache import underscore_memoization, memoize_method
|
from jedi.cache import underscore_memoization
|
||||||
from jedi.evaluate.cache import memoize_default
|
|
||||||
|
|
||||||
|
|
||||||
class MixedObject(object):
|
class MixedObject(object):
|
||||||
@@ -38,6 +37,15 @@ class MixedObject(object):
|
|||||||
assert search_global is False
|
assert search_global is False
|
||||||
return [LazyMixedNamesDict(self._evaluator, self, is_instance=False)]
|
return [LazyMixedNamesDict(self._evaluator, self, is_instance=False)]
|
||||||
|
|
||||||
|
def api_type(self):
|
||||||
|
mappings = {
|
||||||
|
'expr_stmt': 'statement',
|
||||||
|
'classdef': 'class',
|
||||||
|
'funcdef': 'function',
|
||||||
|
'file_input': 'module',
|
||||||
|
}
|
||||||
|
return mappings[self._definition.type]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<%s: %s>' % (type(self).__name__, repr(self.obj))
|
return '<%s: %s>' % (type(self).__name__, repr(self.obj))
|
||||||
|
|
||||||
|
|||||||
@@ -559,6 +559,8 @@ def global_names_dict_generator(evaluator, scope, position):
|
|||||||
|
|
||||||
for names_dict in scope.names_dicts(True):
|
for names_dict in scope.names_dicts(True):
|
||||||
yield names_dict, position
|
yield names_dict, position
|
||||||
|
if hasattr(scope, 'resets_positions'):
|
||||||
|
position = None
|
||||||
if scope.type == 'funcdef':
|
if scope.type == 'funcdef':
|
||||||
# The position should be reset if the current scope is a function.
|
# The position should be reset if the current scope is a function.
|
||||||
in_func = True
|
in_func = True
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ def test_builtin_details():
|
|||||||
var = get_completion('variable', locals())
|
var = get_completion('variable', locals())
|
||||||
f = get_completion('func', locals())
|
f = get_completion('func', locals())
|
||||||
m = get_completion('keyword', locals())
|
m = get_completion('keyword', locals())
|
||||||
|
print(cls._definition.type)
|
||||||
assert cls.type == 'class'
|
assert cls.type == 'class'
|
||||||
assert var.type == 'instance'
|
assert var.type == 'instance'
|
||||||
assert f.type == 'function'
|
assert f.type == 'function'
|
||||||
|
|||||||
Reference in New Issue
Block a user