diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index a9a0f835..b04e947b 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -132,14 +132,14 @@ class Script(object): """ def get_completions(user_stmt, bs): module = self._parser.module() - importer, only_modules = helpers.check_error_statements( - self._evaluator, module, self._pos - ) + names, level, only_modules = helpers.check_error_statements(module, self._pos) completions = [] #print(importer.completion_names(self._evaluator, True)) - if importer is not None: - names = importer.completion_names(self._evaluator, only_modules) - completions = [(name, module) for name in names] + if names: + imp_names = [n for n in names if n.end_pos < self._pos] + i = imports.get_importer(self._evaluator, imp_names, module, level) + c_names = i.completion_names(self._evaluator, only_modules) + completions = [(name, module) for name in c_names] if isinstance(user_stmt, pr.Import): # TODO this paragraph is necessary, but not sure it works. context = self._user_context.get_context() @@ -154,7 +154,7 @@ class Script(object): imp = imports.ImportWrapper(self._evaluator, name) completions += [(n, module) for n in imp.completion_names()] - if importer or isinstance(user_stmt, pr.Import): + if names or isinstance(user_stmt, pr.Import): return completions return self._simple_complete(path, dot, like) @@ -284,6 +284,13 @@ class Script(object): if eval_stmt is None: return [] + module = self._parser.module() + names, level, _ = helpers.check_error_statements(module, self._pos) + if names: + i = imports.get_importer(self._evaluator, names, module, level) + return i.follow(self._evaluator) + + if not is_completion: # goto_definition returns definitions of its statements if the # cursor is on the assignee. By changing the start_pos of our diff --git a/jedi/api/helpers.py b/jedi/api/helpers.py index c69e0af3..5b292c4c 100644 --- a/jedi/api/helpers.py +++ b/jedi/api/helpers.py @@ -34,18 +34,18 @@ def get_on_import_stmt(evaluator, user_context, user_stmt, is_like_search=False) return i, name -def check_error_statements(evaluator, module, pos): +def check_error_statements(module, pos): for error_statement in module.error_statement_stacks: if error_statement.first_type in ('import_from', 'import_name') \ and error_statement.first_pos < pos <= error_statement.next_start_pos: - return importer_from_error_statement(evaluator, module, error_statement, pos) - return None, False + return importer_from_error_statement(error_statement, pos) + return [], 0, False -def importer_from_error_statement(evaluator, module, error_statement, pos): +def importer_from_error_statement(error_statement, pos): def check_dotted(children): for name in children[::2]: - if name.end_pos < pos: + if name.start_pos <= pos: yield name names = [] @@ -60,9 +60,9 @@ def importer_from_error_statement(evaluator, module, error_statement, pos): names += check_dotted(node.children) elif node in ('.', '...'): level += len(node.value) - elif isinstance(node, pt.Name) and node.end_pos < pos: + elif isinstance(node, pt.Name) and node.start_pos <= pos: names.append(node) - elif node == 'import' and node.end_pos < pos: + elif node == 'import' and node.start_pos <= pos: only_modules = False - return imports.get_importer(evaluator, names, module, level), only_modules + return names, level, only_modules