1
0
forked from VimPlug/jedi

Move inference_state.goto to the name and _follow_error_node_imports_if_possible away from inference_state

This commit is contained in:
Dave Halter
2019-09-05 00:34:13 +02:00
parent 67c007338a
commit 8cd5932fed
3 changed files with 107 additions and 101 deletions

View File

@@ -69,7 +69,6 @@ from jedi.file_io import FileIO
from jedi import debug
from jedi import parser_utils
from jedi.inference.utils import unite
from jedi.inference import imports
from jedi.inference import recursion
from jedi.inference.cache import inference_state_function_cache
@@ -79,8 +78,9 @@ from jedi.inference.base_value import ContextualizedNode, \
ValueSet, NO_VALUES, iterate_values
from jedi.inference.value import ClassValue, FunctionValue
from jedi.inference.context import CompForContext
from jedi.inference.syntax_tree import infer_trailer, infer_expr_stmt, \
from jedi.inference.syntax_tree import infer_expr_stmt, \
infer_node, check_tuple_assignments
from jedi.inference.imports import follow_error_node_imports_if_possible
from jedi.plugins import plugin_manager
@@ -261,106 +261,12 @@ class InferenceState(object):
if type_ in ('import_from', 'import_name'):
return imports.infer_import(context, name)
else:
result = self._follow_error_node_imports_if_possible(context, name)
result = follow_error_node_imports_if_possible(context, name)
if result is not None:
return result
return helpers.infer_call_of_leaf(context, name)
def _follow_error_node_imports_if_possible(self, context, name):
error_node = tree.search_ancestor(name, 'error_node')
if error_node is not None:
# Get the first command start of a started simple_stmt. The error
# node is sometimes a small_stmt and sometimes a simple_stmt. Check
# for ; leaves that start a new statements.
start_index = 0
for index, n in enumerate(error_node.children):
if n.start_pos > name.start_pos:
break
if n == ';':
start_index = index + 1
nodes = error_node.children[start_index:]
first_name = nodes[0].get_first_leaf().value
# Make it possible to infer stuff like `import foo.` or
# `from foo.bar`.
if first_name in ('from', 'import'):
is_import_from = first_name == 'from'
level, names = helpers.parse_dotted_names(
nodes,
is_import_from=is_import_from,
until_node=name,
)
return imports.Importer(self, names, context.get_root_context(), level).follow()
return None
def goto(self, context, name):
definition = name.get_definition(import_name_always=True)
if definition is not None:
type_ = definition.type
if type_ == 'expr_stmt':
# Only take the parent, because if it's more complicated than just
# a name it's something you can "goto" again.
is_simple_name = name.parent.type not in ('power', 'trailer')
if is_simple_name:
return [TreeNameDefinition(context, name)]
elif type_ in ('import_from', 'import_name'):
module_names = imports.goto_import(context, name)
return module_names
else:
return [TreeNameDefinition(context, name)]
else:
values = self._follow_error_node_imports_if_possible(context, name)
if values is not None:
return [value.name for value in values]
par = name.parent
node_type = par.type
if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name:
# Named param goto.
trailer = par.parent
if trailer.type == 'arglist':
trailer = trailer.parent
if trailer.type != 'classdef':
if trailer.type == 'decorator':
value_set = context.infer_node(trailer.children[1])
else:
i = trailer.parent.children.index(trailer)
to_infer = trailer.parent.children[:i]
if to_infer[0] == 'await':
to_infer.pop(0)
value_set = context.infer_node(to_infer[0])
for trailer in to_infer[1:]:
value_set = infer_trailer(context, value_set, trailer)
param_names = []
for value in value_set:
for signature in value.get_signatures():
for param_name in signature.get_param_names():
if param_name.string_name == name.value:
param_names.append(param_name)
return param_names
elif node_type == 'dotted_name': # Is a decorator.
index = par.children.index(name)
if index > 0:
new_dotted = helpers.deep_ast_copy(par)
new_dotted.children[index - 1:] = []
values = context.infer_node(new_dotted)
return unite(
value.goto(name, name_context=value.as_context())
for value in values
)
if node_type == 'trailer' and par.children[0] == '.':
values = helpers.infer_call_of_leaf(context, name, cut_own_trailer=True)
return values.goto(name, name_context=context)
else:
stmt = tree.search_ancestor(
name, 'expr_stmt', 'lambdef'
) or name
if stmt.type == 'lambdef':
stmt = name
return context.goto(name, position=stmt.start_pos)
def parse_and_get_code(self, code=None, path=None, encoding='utf-8',
use_latest_grammar=False, file_io=None, **kwargs):
if self.allow_different_encoding: