1
0
forked from VimPlug/jedi

REPL completion is working again partially. There's some progress at least.

This commit is contained in:
Dave Halter
2016-06-29 08:49:20 +02:00
parent 52c42c3392
commit a3b263a599
7 changed files with 41 additions and 35 deletions

View File

@@ -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'):

View File

@@ -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'

View File

@@ -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:

View File

@@ -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):

View File

@@ -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))

View File

@@ -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

View File

@@ -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'