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.context import ModuleContext
|
||||||
from jedi.evaluate.base_context import ContextSet
|
from jedi.evaluate.base_context import ContextSet
|
||||||
from jedi.evaluate.context.iterable import unpack_tuple_to_dict
|
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, \
|
from jedi.evaluate.gradual.stub_context import try_stubs_to_actual_context_set, \
|
||||||
try_stub_to_actual_names
|
try_stub_to_actual_names
|
||||||
from jedi.evaluate.gradual.utils import load_proper_stub_module
|
from jedi.evaluate.gradual.utils import load_proper_stub_module
|
||||||
|
|||||||
@@ -324,12 +324,8 @@ class BaseDefinition(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def goto_assignments(self):
|
def goto_assignments(self):
|
||||||
if self._name.tree_name is None:
|
return [self if n == self._name else Definition(self._evaluator, n)
|
||||||
return self
|
for n in self._name.goto()]
|
||||||
|
|
||||||
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]
|
|
||||||
|
|
||||||
def infer(self):
|
def infer(self):
|
||||||
tree_name = self._name.tree_name
|
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, \
|
from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \
|
||||||
eval_node, check_tuple_assignments
|
eval_node, check_tuple_assignments
|
||||||
from jedi.evaluate.gradual.stub_context import \
|
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):
|
def _execute(context, arguments):
|
||||||
@@ -322,6 +323,11 @@ class Evaluator(object):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def goto(self, context, name):
|
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)
|
definition = name.get_definition(import_name_always=True)
|
||||||
if definition is not None:
|
if definition is not None:
|
||||||
type_ = definition.type
|
type_ = definition.type
|
||||||
@@ -334,11 +340,8 @@ class Evaluator(object):
|
|||||||
elif type_ == 'param':
|
elif type_ == 'param':
|
||||||
return [ParamName(context, name)]
|
return [ParamName(context, name)]
|
||||||
elif type_ in ('funcdef', 'classdef'):
|
elif type_ in ('funcdef', 'classdef'):
|
||||||
if context.is_stub():
|
n = TreeNameDefinition(context, name)
|
||||||
return goto_non_stub(context, name)
|
return goto_with_stubs_if_possible(n)
|
||||||
else:
|
|
||||||
n = TreeNameDefinition(context, name)
|
|
||||||
return goto_with_stubs_if_possible(n)
|
|
||||||
elif type_ in ('import_from', 'import_name'):
|
elif type_ in ('import_from', 'import_name'):
|
||||||
module_names = imports.infer_import(context, name, is_goto=True)
|
module_names = imports.infer_import(context, name, is_goto=True)
|
||||||
return module_names
|
return module_names
|
||||||
|
|||||||
@@ -113,17 +113,16 @@ def goto_with_stubs_if_possible(name):
|
|||||||
] or [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):
|
def stub_to_actual_context_set(stub_context, ignore_compiled=False):
|
||||||
stub_module = stub_context.get_root_context()
|
stub_module = stub_context.get_root_context()
|
||||||
if not stub_module.is_stub():
|
if not stub_module.is_stub():
|
||||||
return ContextSet([stub_context])
|
return ContextSet([stub_context])
|
||||||
|
|
||||||
qualified_names = stub_context.get_qualified_names()
|
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:
|
if qualified_names is None:
|
||||||
return NO_CONTEXTS
|
return NO_CONTEXTS
|
||||||
|
|
||||||
@@ -147,6 +146,30 @@ def try_stubs_to_actual_context_set(stub_contexts, prefer_stub_to_compiled=False
|
|||||||
@to_list
|
@to_list
|
||||||
def try_stub_to_actual_names(names, prefer_stub_to_compiled=False):
|
def try_stub_to_actual_names(names, prefer_stub_to_compiled=False):
|
||||||
for name in names:
|
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
|
# 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
|
# 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
|
# 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.
|
# name will always result on itself.
|
||||||
return {self}
|
return {self}
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_qualified_names(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
def get_root_context(self):
|
def get_root_context(self):
|
||||||
return self.parent_context.get_root_context()
|
return self.parent_context.get_root_context()
|
||||||
|
|
||||||
@@ -44,6 +48,12 @@ class AbstractTreeName(AbstractNameDefinition):
|
|||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.tree_name = tree_name
|
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):
|
def goto(self):
|
||||||
return self.parent_context.evaluator.goto(self.parent_context, self.tree_name)
|
return self.parent_context.evaluator.goto(self.parent_context, self.tree_name)
|
||||||
|
|
||||||
@@ -64,6 +74,9 @@ class ContextNameMixin(object):
|
|||||||
def infer(self):
|
def infer(self):
|
||||||
return ContextSet([self._context])
|
return ContextSet([self._context])
|
||||||
|
|
||||||
|
def get_qualified_names(self):
|
||||||
|
return self._context.get_qualified_names()
|
||||||
|
|
||||||
def get_root_context(self):
|
def get_root_context(self):
|
||||||
if self.parent_context is None: # A module
|
if self.parent_context is None: # A module
|
||||||
return self._context
|
return self._context
|
||||||
@@ -79,6 +92,10 @@ class ContextName(ContextNameMixin, AbstractTreeName):
|
|||||||
super(ContextName, self).__init__(context.parent_context, tree_name)
|
super(ContextName, self).__init__(context.parent_context, tree_name)
|
||||||
self._context = context
|
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):
|
class TreeNameDefinition(AbstractTreeName):
|
||||||
_API_TYPES = dict(
|
_API_TYPES = dict(
|
||||||
@@ -143,6 +160,9 @@ class ImportName(AbstractNameDefinition):
|
|||||||
self._from_module_context = parent_context
|
self._from_module_context = parent_context
|
||||||
self.string_name = string_name
|
self.string_name = string_name
|
||||||
|
|
||||||
|
def get_qualified_names(self):
|
||||||
|
return []
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def parent_context(self):
|
def parent_context(self):
|
||||||
m = self._from_module_context
|
m = self._from_module_context
|
||||||
|
|||||||
Reference in New Issue
Block a user