mirror of
https://github.com/davidhalter/jedi.git
synced 2026-01-01 01:33:21 +08:00
named param goto.
This commit is contained in:
@@ -314,6 +314,11 @@ class BaseDefinition(object):
|
|||||||
return '.'.join(path if path[0] else path[1:])
|
return '.'.join(path if path[0] else path[1:])
|
||||||
|
|
||||||
def goto_assignments(self):
|
def goto_assignments(self):
|
||||||
|
defs = self._evaluator.goto(self._name)
|
||||||
|
return [Definition(self._evaluator, d) for d in defs]
|
||||||
|
|
||||||
|
|
||||||
|
# TODO REMOVE!
|
||||||
def call_path_for_name_part(stmt_or_imp, name_part):
|
def call_path_for_name_part(stmt_or_imp, name_part):
|
||||||
if isinstance(stmt_or_imp, pr.Import):
|
if isinstance(stmt_or_imp, pr.Import):
|
||||||
return [name_part]
|
return [name_part]
|
||||||
@@ -636,6 +641,10 @@ class Definition(use_metaclass(CachedMetaClass, BaseDefinition)):
|
|||||||
Returns True, if defined as a name in a statement, function or class.
|
Returns True, if defined as a name in a statement, function or class.
|
||||||
Returns False, if it's a reference to such a definition.
|
Returns False, if it's a reference to such a definition.
|
||||||
"""
|
"""
|
||||||
|
return self._name.is_definition()
|
||||||
|
|
||||||
|
|
||||||
|
# TODO REMOVE this.
|
||||||
_def = self._name.get_parent_until((pr.ExprStmt, pr.Import,
|
_def = self._name.get_parent_until((pr.ExprStmt, pr.Import,
|
||||||
pr.Function, pr.Class, pr.Module))
|
pr.Function, pr.Class, pr.Module))
|
||||||
if isinstance(_def, pr.ExprStmt):
|
if isinstance(_def, pr.ExprStmt):
|
||||||
|
|||||||
@@ -468,10 +468,32 @@ class Evaluator(object):
|
|||||||
yield name
|
yield name
|
||||||
|
|
||||||
stmt = name.get_definition()
|
stmt = name.get_definition()
|
||||||
# Only take the parent, because if it's more complicated than just a
|
|
||||||
# name it's something you can "goto" again.
|
|
||||||
par = name.parent
|
par = name.parent
|
||||||
if isinstance(par, pr.ExprStmt) and name in par.get_defined_names():
|
if par.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':
|
||||||
|
for i, t in enumerate(trailer.parent.children):
|
||||||
|
if t == trailer:
|
||||||
|
to_evaluate = trailer.parent.children[:i]
|
||||||
|
types = self.eval_element(to_evaluate[0])
|
||||||
|
for trailer in to_evaluate[1:]:
|
||||||
|
types = self.eval_trailer(types, trailer)
|
||||||
|
param_names = []
|
||||||
|
for typ in types:
|
||||||
|
try:
|
||||||
|
params = typ.params
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
param_names += [param.name for param in params
|
||||||
|
if param.name.value == name.value]
|
||||||
|
return param_names
|
||||||
|
elif isinstance(par, pr.ExprStmt) and name in par.get_defined_names():
|
||||||
|
# Only take the parent, because if it's more complicated than just
|
||||||
|
# a name it's something you can "goto" again.
|
||||||
return [name]
|
return [name]
|
||||||
elif isinstance(par, (pr.Param, pr.Function, pr.Class)) and par.name is name:
|
elif isinstance(par, (pr.Param, pr.Function, pr.Class)) and par.name is name:
|
||||||
return [name]
|
return [name]
|
||||||
|
|||||||
@@ -290,33 +290,7 @@ def get_module_name_parts(module):
|
|||||||
Returns a dictionary with name parts as keys and their call paths as
|
Returns a dictionary with name parts as keys and their call paths as
|
||||||
values.
|
values.
|
||||||
"""
|
"""
|
||||||
def scope_name_parts(scope):
|
return chain.from_iterable(module.used_names.values())
|
||||||
for s in scope.subscopes:
|
|
||||||
# Yield the name parts, not names.
|
|
||||||
yield s.name
|
|
||||||
for need_yield_from in scope_name_parts(s):
|
|
||||||
yield need_yield_from
|
|
||||||
|
|
||||||
statements_or_imports = set(chain(*module.used_names.values()))
|
|
||||||
name_parts = set(scope_name_parts(module))
|
|
||||||
for stmt_or_import in statements_or_imports:
|
|
||||||
if isinstance(stmt_or_import, pr.Import):
|
|
||||||
for name in stmt_or_import.get_all_import_names():
|
|
||||||
name_parts.add(name)
|
|
||||||
else:
|
|
||||||
# Running this ensures that all the expression lists are generated
|
|
||||||
# and the parents are all set. (Important for Lambdas) Howeer, this
|
|
||||||
# is only necessary because of the weird fault-tolerant structure
|
|
||||||
# of the parser. I hope to get rid of such behavior in the future.
|
|
||||||
stmt_or_import.expression_list()
|
|
||||||
# For now this is ok, but this could change if we don't have a
|
|
||||||
# token_list anymore, but for now this is the easiest way to get
|
|
||||||
# all the name_parts.
|
|
||||||
for tok in stmt_or_import._token_list:
|
|
||||||
if isinstance(tok, pr.Name):
|
|
||||||
name_parts.add(tok)
|
|
||||||
|
|
||||||
return name_parts
|
|
||||||
|
|
||||||
|
|
||||||
def statement_elements_in_statement(stmt):
|
def statement_elements_in_statement(stmt):
|
||||||
|
|||||||
Reference in New Issue
Block a user