forked from VimPlug/jedi
Introduce get_qualified_names for names, it's easier to implement goto like this
This commit is contained in:
@@ -38,7 +38,6 @@ from jedi.evaluate.syntax_tree import tree_name_to_contexts
|
||||
from jedi.evaluate.context import ModuleContext
|
||||
from jedi.evaluate.base_context import ContextSet
|
||||
from jedi.evaluate.context.iterable import unpack_tuple_to_dict
|
||||
#from jedi.evaluate.gradual.typeshed import try_to_merge_with_stub
|
||||
from jedi.evaluate.gradual.stub_context import try_stubs_to_actual_context_set, \
|
||||
try_stub_to_actual_names
|
||||
from jedi.evaluate.gradual.utils import load_proper_stub_module
|
||||
|
||||
@@ -324,12 +324,8 @@ class BaseDefinition(object):
|
||||
]
|
||||
|
||||
def goto_assignments(self):
|
||||
if self._name.tree_name is None:
|
||||
return self
|
||||
|
||||
names = self._name.goto()
|
||||
names = try_stub_to_actual_names(names, prefer_stub_to_compiled=True)
|
||||
return [Definition(self._evaluator, n) for n in names]
|
||||
return [self if n == self._name else Definition(self._evaluator, n)
|
||||
for n in self._name.goto()]
|
||||
|
||||
def infer(self):
|
||||
tree_name = self._name.tree_name
|
||||
|
||||
@@ -85,7 +85,8 @@ from jedi.evaluate.context.iterable import CompForContext
|
||||
from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \
|
||||
eval_node, check_tuple_assignments
|
||||
from jedi.evaluate.gradual.stub_context import \
|
||||
stub_to_actual_context_set, goto_with_stubs_if_possible, goto_non_stub
|
||||
stub_to_actual_context_set, goto_with_stubs_if_possible, \
|
||||
try_stub_to_actual_names
|
||||
|
||||
|
||||
def _execute(context, arguments):
|
||||
@@ -322,6 +323,11 @@ class Evaluator(object):
|
||||
return None
|
||||
|
||||
def goto(self, context, name):
|
||||
names = self._goto(context, name)
|
||||
names = try_stub_to_actual_names(names, prefer_stub_to_compiled=True)
|
||||
return names
|
||||
|
||||
def _goto(self, context, name):
|
||||
definition = name.get_definition(import_name_always=True)
|
||||
if definition is not None:
|
||||
type_ = definition.type
|
||||
@@ -334,9 +340,6 @@ class Evaluator(object):
|
||||
elif type_ == 'param':
|
||||
return [ParamName(context, name)]
|
||||
elif type_ in ('funcdef', 'classdef'):
|
||||
if context.is_stub():
|
||||
return goto_non_stub(context, name)
|
||||
else:
|
||||
n = TreeNameDefinition(context, name)
|
||||
return goto_with_stubs_if_possible(n)
|
||||
elif type_ in ('import_from', 'import_name'):
|
||||
|
||||
@@ -113,17 +113,16 @@ def goto_with_stubs_if_possible(name):
|
||||
] or [name]
|
||||
|
||||
|
||||
def goto_non_stub(parent_context, tree_name):
|
||||
contexts = stub_to_actual_context_set(parent_context)
|
||||
return contexts.py__getattribute__(tree_name, is_goto=True)
|
||||
|
||||
|
||||
def stub_to_actual_context_set(stub_context, ignore_compiled=False):
|
||||
stub_module = stub_context.get_root_context()
|
||||
if not stub_module.is_stub():
|
||||
return ContextSet([stub_context])
|
||||
|
||||
qualified_names = stub_context.get_qualified_names()
|
||||
return _infer_from_stub(stub_module, qualified_names, ignore_compiled)
|
||||
|
||||
|
||||
def _infer_from_stub(stub_module, qualified_names, ignore_compiled):
|
||||
if qualified_names is None:
|
||||
return NO_CONTEXTS
|
||||
|
||||
@@ -147,6 +146,30 @@ def try_stubs_to_actual_context_set(stub_contexts, prefer_stub_to_compiled=False
|
||||
@to_list
|
||||
def try_stub_to_actual_names(names, prefer_stub_to_compiled=False):
|
||||
for name in names:
|
||||
module = name.get_root_context()
|
||||
if not module.is_stub():
|
||||
yield name
|
||||
continue
|
||||
|
||||
name_list = name.get_qualified_names()
|
||||
if name_list is None:
|
||||
contexts = NO_CONTEXTS
|
||||
else:
|
||||
contexts = _infer_from_stub(
|
||||
module,
|
||||
name_list[:-1],
|
||||
ignore_compiled=prefer_stub_to_compiled,
|
||||
)
|
||||
if contexts:
|
||||
if name_list:
|
||||
for new_name in contexts.py__getattribute__(name_list[-1], is_goto=True):
|
||||
yield new_name
|
||||
else:
|
||||
for c in contexts:
|
||||
yield c.name
|
||||
else:
|
||||
yield name
|
||||
continue # XXX
|
||||
# Using the tree_name is better, if it's available, becuase no
|
||||
# information is lost. If the name given is defineda as `foo: int` we
|
||||
# would otherwise land on int, which is not what we want. We want foo
|
||||
|
||||
@@ -23,6 +23,10 @@ class AbstractNameDefinition(object):
|
||||
# name will always result on itself.
|
||||
return {self}
|
||||
|
||||
@abstractmethod
|
||||
def get_qualified_names(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_root_context(self):
|
||||
return self.parent_context.get_root_context()
|
||||
|
||||
@@ -44,6 +48,12 @@ class AbstractTreeName(AbstractNameDefinition):
|
||||
self.parent_context = parent_context
|
||||
self.tree_name = tree_name
|
||||
|
||||
def get_qualified_names(self):
|
||||
parent_names = self.parent_context.get_qualified_names()
|
||||
if parent_names is None:
|
||||
return None
|
||||
return parent_names + [self.tree_name.value]
|
||||
|
||||
def goto(self):
|
||||
return self.parent_context.evaluator.goto(self.parent_context, self.tree_name)
|
||||
|
||||
@@ -64,6 +74,9 @@ class ContextNameMixin(object):
|
||||
def infer(self):
|
||||
return ContextSet([self._context])
|
||||
|
||||
def get_qualified_names(self):
|
||||
return self._context.get_qualified_names()
|
||||
|
||||
def get_root_context(self):
|
||||
if self.parent_context is None: # A module
|
||||
return self._context
|
||||
@@ -79,6 +92,10 @@ class ContextName(ContextNameMixin, AbstractTreeName):
|
||||
super(ContextName, self).__init__(context.parent_context, tree_name)
|
||||
self._context = context
|
||||
|
||||
def goto(self):
|
||||
from jedi.evaluate.gradual.stub_context import try_stub_to_actual_names
|
||||
return try_stub_to_actual_names([self._context.name])
|
||||
|
||||
|
||||
class TreeNameDefinition(AbstractTreeName):
|
||||
_API_TYPES = dict(
|
||||
@@ -143,6 +160,9 @@ class ImportName(AbstractNameDefinition):
|
||||
self._from_module_context = parent_context
|
||||
self.string_name = string_name
|
||||
|
||||
def get_qualified_names(self):
|
||||
return []
|
||||
|
||||
@property
|
||||
def parent_context(self):
|
||||
m = self._from_module_context
|
||||
|
||||
Reference in New Issue
Block a user