forked from VimPlug/jedi
refactor ModuleWithCursor to UserContext
This commit is contained in:
34
jedi/api.py
34
jedi/api.py
@@ -88,8 +88,7 @@ class Script(object):
|
|||||||
api_classes.clear_caches()
|
api_classes.clear_caches()
|
||||||
debug.reset_time()
|
debug.reset_time()
|
||||||
self.source = common.source_to_unicode(source, encoding)
|
self.source = common.source_to_unicode(source, encoding)
|
||||||
self._module = modules.ModuleWithCursor(
|
self._user_context = modules.UserContext(self.source, self._pos)
|
||||||
path, source=self.source, position=self._pos)
|
|
||||||
self._evaluator = Evaluator()
|
self._evaluator = Evaluator()
|
||||||
debug.speed('init')
|
debug.speed('init')
|
||||||
|
|
||||||
@@ -127,7 +126,7 @@ class Script(object):
|
|||||||
"""
|
"""
|
||||||
def get_completions(user_stmt, bs):
|
def get_completions(user_stmt, bs):
|
||||||
if isinstance(user_stmt, pr.Import):
|
if isinstance(user_stmt, pr.Import):
|
||||||
context = self._module.get_context()
|
context = self._user_context.get_context()
|
||||||
next(context) # skip the path
|
next(context) # skip the path
|
||||||
if next(context) == 'from':
|
if next(context) == 'from':
|
||||||
# completion is just "import" if before stands from ..
|
# completion is just "import" if before stands from ..
|
||||||
@@ -135,7 +134,7 @@ class Script(object):
|
|||||||
return self._simple_complete(path, like)
|
return self._simple_complete(path, like)
|
||||||
|
|
||||||
debug.speed('completions start')
|
debug.speed('completions start')
|
||||||
path = self._module.get_path_until_cursor()
|
path = self._user_context.get_path_until_cursor()
|
||||||
if re.search('^\.|\.\.$', path):
|
if re.search('^\.|\.\.$', path):
|
||||||
return []
|
return []
|
||||||
path, dot, like = self._get_completion_parts()
|
path, dot, like = self._get_completion_parts()
|
||||||
@@ -200,9 +199,9 @@ class Script(object):
|
|||||||
names = s.get_magic_method_names()
|
names = s.get_magic_method_names()
|
||||||
else:
|
else:
|
||||||
if isinstance(s, imports.ImportPath):
|
if isinstance(s, imports.ImportPath):
|
||||||
under = like + self._module.get_path_after_cursor()
|
under = like + self._user_context.get_path_after_cursor()
|
||||||
if under == 'import':
|
if under == 'import':
|
||||||
current_line = self._module.get_position_line()
|
current_line = self._user_context.get_position_line()
|
||||||
if not current_line.endswith('import import'):
|
if not current_line.endswith('import import'):
|
||||||
continue
|
continue
|
||||||
a = s.import_stmt.alias
|
a = s.import_stmt.alias
|
||||||
@@ -222,7 +221,7 @@ class Script(object):
|
|||||||
|
|
||||||
if is_completion and not user_stmt:
|
if is_completion and not user_stmt:
|
||||||
# for statements like `from x import ` (cursor not in statement)
|
# for statements like `from x import ` (cursor not in statement)
|
||||||
pos = next(self._module.get_context(yield_positions=True))
|
pos = next(self._user_context.get_context(yield_positions=True))
|
||||||
last_stmt = pos and self._parser.module.get_statement_for_position(
|
last_stmt = pos and self._parser.module.get_statement_for_position(
|
||||||
pos, include_imports=True)
|
pos, include_imports=True)
|
||||||
if isinstance(last_stmt, pr.Import):
|
if isinstance(last_stmt, pr.Import):
|
||||||
@@ -343,16 +342,16 @@ class Script(object):
|
|||||||
scopes.update(resolve_import_paths(set(s.follow())))
|
scopes.update(resolve_import_paths(set(s.follow())))
|
||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
goto_path = self._module.get_path_under_cursor()
|
goto_path = self._user_context.get_path_under_cursor()
|
||||||
|
|
||||||
context = self._module.get_context()
|
context = self._user_context.get_context()
|
||||||
scopes = set()
|
scopes = set()
|
||||||
lower_priority_operators = ('()', '(', ',')
|
lower_priority_operators = ('()', '(', ',')
|
||||||
"""Operators that could hide callee."""
|
"""Operators that could hide callee."""
|
||||||
if next(context) in ('class', 'def'):
|
if next(context) in ('class', 'def'):
|
||||||
scopes = set([self._parser.user_scope])
|
scopes = set([self._parser.user_scope])
|
||||||
elif not goto_path:
|
elif not goto_path:
|
||||||
op = self._module.get_operator_under_cursor()
|
op = self._user_context.get_operator_under_cursor()
|
||||||
if op and op not in lower_priority_operators:
|
if op and op not in lower_priority_operators:
|
||||||
scopes = set([keywords.get_operator(op, self._pos)])
|
scopes = set([keywords.get_operator(op, self._pos)])
|
||||||
|
|
||||||
@@ -365,12 +364,9 @@ class Script(object):
|
|||||||
# reset cursor position:
|
# reset cursor position:
|
||||||
(row, col) = call.name.end_pos
|
(row, col) = call.name.end_pos
|
||||||
pos = (row, max(col - 1, 0))
|
pos = (row, max(col - 1, 0))
|
||||||
self._module = modules.ModuleWithCursor(
|
self._user_context = modules.UserContext(self.source, pos)
|
||||||
self._source_path,
|
|
||||||
source=self.source,
|
|
||||||
position=pos)
|
|
||||||
# then try to find the path again
|
# then try to find the path again
|
||||||
goto_path = self._module.get_path_under_cursor()
|
goto_path = self._user_context.get_path_under_cursor()
|
||||||
|
|
||||||
if not scopes:
|
if not scopes:
|
||||||
if goto_path:
|
if goto_path:
|
||||||
@@ -421,8 +417,8 @@ class Script(object):
|
|||||||
definitions |= follow_inexistent_imports(i)
|
definitions |= follow_inexistent_imports(i)
|
||||||
return definitions
|
return definitions
|
||||||
|
|
||||||
goto_path = self._module.get_path_under_cursor()
|
goto_path = self._user_context.get_path_under_cursor()
|
||||||
context = self._module.get_context()
|
context = self._user_context.get_context()
|
||||||
user_stmt = self._user_stmt()
|
user_stmt = self._user_stmt()
|
||||||
if next(context) in ('class', 'def'):
|
if next(context) in ('class', 'def'):
|
||||||
user_scope = self._parser.user_scope
|
user_scope = self._parser.user_scope
|
||||||
@@ -553,7 +549,7 @@ class Script(object):
|
|||||||
cur_name_part = name_part
|
cur_name_part = name_part
|
||||||
kill_count += 1
|
kill_count += 1
|
||||||
|
|
||||||
context = self._module.get_context()
|
context = self._user_context.get_context()
|
||||||
just_from = next(context) == 'from'
|
just_from = next(context) == 'from'
|
||||||
|
|
||||||
i = imports.ImportPath(self._evaluator, user_stmt, is_like_search,
|
i = imports.ImportPath(self._evaluator, user_stmt, is_like_search,
|
||||||
@@ -566,7 +562,7 @@ class Script(object):
|
|||||||
Returns the parts for the completion
|
Returns the parts for the completion
|
||||||
:return: tuple - (path, dot, like)
|
:return: tuple - (path, dot, like)
|
||||||
"""
|
"""
|
||||||
path = self._module.get_path_until_cursor()
|
path = self._user_context.get_path_until_cursor()
|
||||||
match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S)
|
match = re.match(r'^(.*?)(\.|)(\w?[\w\d]*)$', path, flags=re.S)
|
||||||
return match.groups()
|
return match.groups()
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +1,18 @@
|
|||||||
"""
|
|
||||||
Don't confuse these classes with :mod:`parsing_representation` modules, the
|
|
||||||
modules here can access these representation with ``module.parser.module``.
|
|
||||||
``Module`` exists mainly for caching purposes.
|
|
||||||
|
|
||||||
Basically :mod:`modules` offers the classes:
|
|
||||||
|
|
||||||
- ``CachedModule``, a base class for Cachedmodule.
|
|
||||||
- ``Module`` the class for all normal Python modules (not builtins, they are at
|
|
||||||
home at :mod:`builtin`).
|
|
||||||
- ``ModuleWithCursor``, holds the module information for :class:`api.Script`.
|
|
||||||
|
|
||||||
Apart from those classes there's a ``sys.path`` fetching function, as well as
|
|
||||||
`Virtual Env` and `Django` detection.
|
|
||||||
"""
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
|
|
||||||
from jedi import cache
|
|
||||||
from jedi.parser import tokenize
|
from jedi.parser import tokenize
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
|
|
||||||
|
|
||||||
class ModuleWithCursor(object):
|
class UserContext(object):
|
||||||
"""
|
"""
|
||||||
Manages all files, that are parsed and caches them.
|
|
||||||
Important are the params source and path, one of them has to
|
|
||||||
be there.
|
|
||||||
|
|
||||||
:param source: The source code of the file.
|
:param source: The source code of the file.
|
||||||
:param path: The module path of the file or None.
|
|
||||||
:param position: The position, the user is currently in. Only important \
|
:param position: The position, the user is currently in. Only important \
|
||||||
for the main file.
|
for the main file.
|
||||||
"""
|
"""
|
||||||
def __init__(self, path, source, position):
|
def __init__(self, source, position):
|
||||||
super(ModuleWithCursor, self).__init__()
|
|
||||||
self.path = path and os.path.abspath(path)
|
|
||||||
self.name = None
|
self.name = None
|
||||||
self.source = source
|
self.source = source
|
||||||
self.position = position
|
self.position = position
|
||||||
|
|||||||
Reference in New Issue
Block a user