mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-11 08:11:50 +08:00
Fix goto tests.
This commit is contained in:
@@ -237,7 +237,8 @@ class Script(object):
|
|||||||
name = self._get_module_node().name_for_position(self._pos)
|
name = self._get_module_node().name_for_position(self._pos)
|
||||||
if name is None:
|
if name is None:
|
||||||
return []
|
return []
|
||||||
return list(self._evaluator.goto(name))
|
context = self._evaluator.create_context(self._get_module(), name)
|
||||||
|
return list(self._evaluator.goto(context, name))
|
||||||
|
|
||||||
def usages(self, additional_module_paths=()):
|
def usages(self, additional_module_paths=()):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -145,10 +145,7 @@ class BaseDefinition(object):
|
|||||||
'function'
|
'function'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
try:
|
return self._name.api_type
|
||||||
return self._name.parent_context.api_type
|
|
||||||
except AttributeError:
|
|
||||||
return ''
|
|
||||||
|
|
||||||
def _path(self):
|
def _path(self):
|
||||||
"""The path to a module/class/function definition."""
|
"""The path to a module/class/function definition."""
|
||||||
@@ -418,7 +415,7 @@ class Completion(BaseDefinition):
|
|||||||
"""
|
"""
|
||||||
Return the rest of the word, e.g. completing ``isinstance``::
|
Return the rest of the word, e.g. completing ``isinstance``::
|
||||||
|
|
||||||
isinstan# <-- Cursor is here
|
# <-- Cursor is here
|
||||||
|
|
||||||
would return the string 'ce'. It also adds additional stuff, depending
|
would return the string 'ce'. It also adds additional stuff, depending
|
||||||
on your `settings.py`.
|
on your `settings.py`.
|
||||||
@@ -561,6 +558,36 @@ class Definition(use_metaclass(CachedMetaClass, BaseDefinition)):
|
|||||||
'class C'
|
'class C'
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
typ = self.type
|
||||||
|
if typ in ('statement', 'param'):
|
||||||
|
definition = self._name.tree_name.get_definition()
|
||||||
|
|
||||||
|
try:
|
||||||
|
first_leaf = definition.first_leaf()
|
||||||
|
except AttributeError:
|
||||||
|
# `d` is already a Leaf (Name).
|
||||||
|
first_leaf = definition
|
||||||
|
# Remove the prefix, because that's not what we want for get_code
|
||||||
|
# here.
|
||||||
|
old, first_leaf.prefix = first_leaf.prefix, ''
|
||||||
|
try:
|
||||||
|
txt = definition.get_code()
|
||||||
|
finally:
|
||||||
|
first_leaf.prefix = old
|
||||||
|
# Delete comments:
|
||||||
|
txt = re.sub('#[^\n]+\n', ' ', txt)
|
||||||
|
# Delete multi spaces/newlines
|
||||||
|
txt = re.sub('\s+', ' ', txt).strip()
|
||||||
|
if typ == 'param':
|
||||||
|
txt = typ + ' ' + txt
|
||||||
|
return txt
|
||||||
|
if typ == 'function':
|
||||||
|
# For the description we want a short and a pythonic way.
|
||||||
|
typ = 'def'
|
||||||
|
return typ + ' ' + self._name.string_name
|
||||||
|
|
||||||
|
# TODO DELETE
|
||||||
|
|
||||||
d = self._definition
|
d = self._definition
|
||||||
|
|
||||||
if isinstance(d, compiled.CompiledObject):
|
if isinstance(d, compiled.CompiledObject):
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class KeywordName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class Keyword(object):
|
class Keyword(object):
|
||||||
type = 'completion_keyword'
|
api_type = 'keyword'
|
||||||
|
|
||||||
def __init__(self, evaluator, name, pos):
|
def __init__(self, evaluator, name, pos):
|
||||||
self.name = KeywordName(evaluator, name)
|
self.name = KeywordName(evaluator, name)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ from itertools import chain
|
|||||||
|
|
||||||
from jedi.parser import tree
|
from jedi.parser import tree
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
|
from jedi.common import unite
|
||||||
from jedi.evaluate import representation as er
|
from jedi.evaluate import representation as er
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate import recursion
|
from jedi.evaluate import recursion
|
||||||
@@ -77,7 +78,7 @@ from jedi.evaluate import compiled
|
|||||||
from jedi.evaluate import precedence
|
from jedi.evaluate import precedence
|
||||||
from jedi.evaluate import param
|
from jedi.evaluate import param
|
||||||
from jedi.evaluate import helpers
|
from jedi.evaluate import helpers
|
||||||
from jedi.evaluate.context import Context
|
from jedi.evaluate.filters import TreeNameDefinition
|
||||||
from jedi.evaluate.instance import AnonymousInstance, AnonymousInstanceFunctionExecution
|
from jedi.evaluate.instance import AnonymousInstance, AnonymousInstanceFunctionExecution
|
||||||
|
|
||||||
|
|
||||||
@@ -461,36 +462,43 @@ class Evaluator(object):
|
|||||||
param_names = []
|
param_names = []
|
||||||
for typ in types:
|
for typ in types:
|
||||||
try:
|
try:
|
||||||
params = typ.params
|
get_param_names = typ.get_param_names
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
param_names += [param.name for param in params
|
for param_name in get_param_names():
|
||||||
if param.name.value == name.value]
|
if param_name.string_name == name.value:
|
||||||
|
param_names.append(param_name)
|
||||||
return param_names
|
return param_names
|
||||||
elif isinstance(par, tree.ExprStmt) and name in par.get_defined_names():
|
elif isinstance(par, tree.ExprStmt) and name in par.get_defined_names():
|
||||||
# Only take the parent, because if it's more complicated than just
|
# Only take the parent, because if it's more complicated than just
|
||||||
# a name it's something you can "goto" again.
|
# a name it's something you can "goto" again.
|
||||||
return [name]
|
return [TreeNameDefinition(context, name)]
|
||||||
elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name:
|
elif isinstance(par, (tree.Param, tree.Function, tree.Class)) and par.name is name:
|
||||||
return [name]
|
return [TreeNameDefinition(context, name)]
|
||||||
elif isinstance(stmt, tree.Import):
|
elif isinstance(stmt, tree.Import):
|
||||||
modules = imports.ImportWrapper(context, name).follow(is_goto=True)
|
module_names = imports.ImportWrapper(context, name).follow(is_goto=True)
|
||||||
return list(resolve_implicit_imports(modules))
|
return module_names
|
||||||
|
return list(resolve_implicit_imports(module_names))
|
||||||
elif par.type == 'dotted_name': # Is a decorator.
|
elif par.type == 'dotted_name': # Is a decorator.
|
||||||
index = par.children.index(name)
|
index = par.children.index(name)
|
||||||
if index > 0:
|
if index > 0:
|
||||||
new_dotted = helpers.deep_ast_copy(par)
|
new_dotted = helpers.deep_ast_copy(par)
|
||||||
new_dotted.children[index - 1:] = []
|
new_dotted.children[index - 1:] = []
|
||||||
types = self.eval_element(context, new_dotted)
|
values = self.eval_element(context, new_dotted)
|
||||||
|
return unite(
|
||||||
|
self.find_types(value, name, is_goto=True) for value in values
|
||||||
|
)
|
||||||
return resolve_implicit_imports(iterable.unite(
|
return resolve_implicit_imports(iterable.unite(
|
||||||
self.find_types(typ, name, is_goto=True) for typ in types
|
self.find_types(typ, name, is_goto=True) for typ in types
|
||||||
))
|
))
|
||||||
|
|
||||||
scope = name.get_parent_scope()
|
|
||||||
if tree.is_node(par, 'trailer') and par.children[0] == '.':
|
if tree.is_node(par, 'trailer') and par.children[0] == '.':
|
||||||
call = helpers.call_of_leaf(name, cut_own_trailer=True)
|
call = helpers.call_of_leaf(name, cut_own_trailer=True)
|
||||||
types = self.eval_element(context, call)
|
values = self.eval_element(context, call)
|
||||||
|
return unite(
|
||||||
|
self.find_types(value, name, is_goto=True) for value in values
|
||||||
|
)
|
||||||
return resolve_implicit_imports(iterable.unite(
|
return resolve_implicit_imports(iterable.unite(
|
||||||
self.find_types(typ, name, is_goto=True) for typ in types
|
self.find_types(typ, name, is_goto=True) for typ in types
|
||||||
))
|
))
|
||||||
@@ -499,7 +507,7 @@ class Evaluator(object):
|
|||||||
# We only need to adjust the start_pos for statements, because
|
# We only need to adjust the start_pos for statements, because
|
||||||
# there the name cannot be used.
|
# there the name cannot be used.
|
||||||
stmt = name
|
stmt = name
|
||||||
return self.find_types(scope, name, stmt.start_pos,
|
return self.find_types(context, name, stmt.start_pos,
|
||||||
search_global=True, is_goto=True)
|
search_global=True, is_goto=True)
|
||||||
|
|
||||||
def wrap(self, element, parent_context):
|
def wrap(self, element, parent_context):
|
||||||
|
|||||||
@@ -85,7 +85,8 @@ class CompiledObject(Context):
|
|||||||
return inspect.getdoc(self.obj) or ''
|
return inspect.getdoc(self.obj) or ''
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def params(self):
|
def get_params(self):
|
||||||
|
return [] # TODO Fix me.
|
||||||
params_str, ret = self._parse_function_doc()
|
params_str, ret = self._parse_function_doc()
|
||||||
tokens = params_str.split(',')
|
tokens = params_str.split(',')
|
||||||
if inspect.ismethoddescriptor(self.obj):
|
if inspect.ismethoddescriptor(self.obj):
|
||||||
@@ -280,6 +281,9 @@ class CompiledName(AbstractNameDefinition):
|
|||||||
name = None
|
name = None
|
||||||
return '<%s: (%s).%s>' % (self.__class__.__name__, name, self.string_name)
|
return '<%s: (%s).%s>' % (self.__class__.__name__, name, self.string_name)
|
||||||
|
|
||||||
|
def api_type(self):
|
||||||
|
return self.infer()[0].api_type
|
||||||
|
|
||||||
@underscore_memoization
|
@underscore_memoization
|
||||||
def infer(self):
|
def infer(self):
|
||||||
module = self.parent_context.get_root_context()
|
module = self.parent_context.get_root_context()
|
||||||
@@ -291,6 +295,10 @@ class CompiledContextName(AbstractNameDefinition):
|
|||||||
self.string_name = name
|
self.string_name = name
|
||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_type(self):
|
||||||
|
return self.parent_context.api_type
|
||||||
|
|
||||||
def infer(self):
|
def infer(self):
|
||||||
return [self.parent_context]
|
return [self.parent_context]
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ class ContextName(AbstractNameDefinition):
|
|||||||
def infer(self):
|
def infer(self):
|
||||||
return [self.parent_context]
|
return [self.parent_context]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_type(self):
|
||||||
|
return self.parent_context.api_type
|
||||||
|
|
||||||
|
|
||||||
class TreeNameDefinition(ContextName):
|
class TreeNameDefinition(ContextName):
|
||||||
def get_parent_flow_context(self):
|
def get_parent_flow_context(self):
|
||||||
@@ -61,8 +65,20 @@ class TreeNameDefinition(ContextName):
|
|||||||
from jedi.evaluate.finder import _name_to_types
|
from jedi.evaluate.finder import _name_to_types
|
||||||
return _name_to_types(self.parent_context.evaluator, self.parent_context, self.tree_name)
|
return _name_to_types(self.parent_context.evaluator, self.parent_context, self.tree_name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def api_type(self):
|
||||||
|
definition = self.tree_name.get_definition()
|
||||||
|
return dict(
|
||||||
|
import_name='import',
|
||||||
|
funcdef='function',
|
||||||
|
param='param',
|
||||||
|
classdef='class',
|
||||||
|
).get(definition.type, 'statement')
|
||||||
|
|
||||||
|
|
||||||
class ParamName(ContextName):
|
class ParamName(ContextName):
|
||||||
|
api_type = 'param'
|
||||||
|
|
||||||
def __init__(self, parent_context, tree_name):
|
def __init__(self, parent_context, tree_name):
|
||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.tree_name = tree_name
|
self.tree_name = tree_name
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ class FakeName(tree.Name):
|
|||||||
In case is_definition is defined (not None), that bool value will be
|
In case is_definition is defined (not None), that bool value will be
|
||||||
returned.
|
returned.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
|
||||||
super(FakeName, self).__init__(name_str, start_pos)
|
super(FakeName, self).__init__(name_str, start_pos)
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self._is_definition = is_definition
|
self._is_definition = is_definition
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ class SpecialMethodFilter(DictFilter):
|
|||||||
classes like Generator (for __next__, etc).
|
classes like Generator (for __next__, etc).
|
||||||
"""
|
"""
|
||||||
class SpecialMethodName(AbstractNameDefinition):
|
class SpecialMethodName(AbstractNameDefinition):
|
||||||
|
api_type = 'function'
|
||||||
|
|
||||||
def __init__(self, parent_context, string_name, callable_, builtin_context):
|
def __init__(self, parent_context, string_name, callable_, builtin_context):
|
||||||
self.parent_context = parent_context
|
self.parent_context = parent_context
|
||||||
self.string_name = string_name
|
self.string_name = string_name
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ from jedi.evaluate import param
|
|||||||
from jedi.evaluate import flow_analysis
|
from jedi.evaluate import flow_analysis
|
||||||
from jedi.evaluate import imports
|
from jedi.evaluate import imports
|
||||||
from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \
|
from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \
|
||||||
GlobalNameFilter, DictFilter, ContextName, AbstractNameDefinition
|
GlobalNameFilter, DictFilter, ContextName, AbstractNameDefinition, \
|
||||||
|
ParamName, AnonymousInstanceParamName
|
||||||
from jedi.evaluate.dynamic import search_params
|
from jedi.evaluate.dynamic import search_params
|
||||||
from jedi.evaluate import context
|
from jedi.evaluate import context
|
||||||
|
|
||||||
@@ -470,12 +471,10 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
|
|||||||
def py__class__(self):
|
def py__class__(self):
|
||||||
return compiled.create(self.evaluator, type)
|
return compiled.create(self.evaluator, type)
|
||||||
|
|
||||||
@property
|
def get_params(self):
|
||||||
def params(self):
|
from jedi.evaluate.instance import AnonymousInstance
|
||||||
try:
|
anon = AnonymousInstance(self.evaluator, self.parent_context, self)
|
||||||
return self.get_subscope_by_name('__init__').params
|
return [AnonymousInstanceParamName(anon, param.name) for param in self.funcdef.params]
|
||||||
except KeyError:
|
|
||||||
return [] # object.__init__
|
|
||||||
|
|
||||||
def names_dicts(self, search_global, is_instance=False):
|
def names_dicts(self, search_global, is_instance=False):
|
||||||
if search_global:
|
if search_global:
|
||||||
@@ -509,6 +508,13 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
|
|||||||
return sub
|
return sub
|
||||||
raise KeyError("Couldn't find subscope.")
|
raise KeyError("Couldn't find subscope.")
|
||||||
|
|
||||||
|
def get_function_slot_names(self, name):
|
||||||
|
for filter in self.get_filters(search_global=False):
|
||||||
|
names = filter.get(name)
|
||||||
|
if names:
|
||||||
|
return names
|
||||||
|
return []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<%s of %s>" % (self.__class__.__name__, self.classdef)
|
return "<%s of %s>" % (self.__class__.__name__, self.classdef)
|
||||||
|
|
||||||
@@ -582,6 +588,14 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
|
|||||||
def name(self):
|
def name(self):
|
||||||
return ContextName(self, self.funcdef.name)
|
return ContextName(self, self.funcdef.name)
|
||||||
|
|
||||||
|
def get_param_names(self):
|
||||||
|
anon = AnonymousFunctionExecution(
|
||||||
|
self.evaluator,
|
||||||
|
self.parent_context,
|
||||||
|
self.funcdef
|
||||||
|
)
|
||||||
|
return [ParamName(anon, param.name) for param in self.funcdef.params]
|
||||||
|
|
||||||
|
|
||||||
class LambdaWrapper(FunctionContext):
|
class LambdaWrapper(FunctionContext):
|
||||||
def get_decorated_func(self):
|
def get_decorated_func(self):
|
||||||
@@ -747,6 +761,8 @@ class ModuleAttributeName(AbstractNameDefinition):
|
|||||||
"""
|
"""
|
||||||
For module attributes like __file__, __str__ and so on.
|
For module attributes like __file__, __str__ and so on.
|
||||||
"""
|
"""
|
||||||
|
api_type = 'instance'
|
||||||
|
|
||||||
def __init__(self, parent_module, string_name):
|
def __init__(self, parent_module, string_name):
|
||||||
self.parent_context = parent_module
|
self.parent_context = parent_module
|
||||||
self.string_name = string_name
|
self.string_name = string_name
|
||||||
@@ -758,8 +774,9 @@ class ModuleAttributeName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class SubModuleName(AbstractNameDefinition):
|
class SubModuleName(AbstractNameDefinition):
|
||||||
"""
|
api_type = 'module'
|
||||||
"""
|
start_pos = (1, 0)
|
||||||
|
|
||||||
def __init__(self, parent_module, string_name):
|
def __init__(self, parent_module, string_name):
|
||||||
self.parent_context = parent_module
|
self.parent_context = parent_module
|
||||||
self.string_name = string_name
|
self.string_name = string_name
|
||||||
@@ -774,6 +791,7 @@ class SubModuleName(AbstractNameDefinition):
|
|||||||
|
|
||||||
|
|
||||||
class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
|
class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
|
||||||
|
api_type = 'module'
|
||||||
parent_context = None
|
parent_context = None
|
||||||
|
|
||||||
def __init__(self, evaluator, module_node):
|
def __init__(self, evaluator, module_node):
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class C(object):
|
|||||||
self.b
|
self.b
|
||||||
#! 14 ['def b']
|
#! 14 ['def b']
|
||||||
self.b()
|
self.b()
|
||||||
#! 11 ['self']
|
#! 11 ['param self']
|
||||||
self.b
|
self.b
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ ClassVar().x = ''
|
|||||||
|
|
||||||
# Recurring use of the same var name, github #315
|
# Recurring use of the same var name, github #315
|
||||||
def f(t=None):
|
def f(t=None):
|
||||||
#! 9 ['t=None']
|
#! 9 ['param t=None']
|
||||||
t = t or 1
|
t = t or 1
|
||||||
|
|
||||||
|
|
||||||
@@ -180,9 +180,9 @@ class ClassDef():
|
|||||||
# -----------------
|
# -----------------
|
||||||
|
|
||||||
param = ClassDef
|
param = ClassDef
|
||||||
#! 8 ['param']
|
#! 8 ['param param']
|
||||||
def ab1(param): pass
|
def ab1(param): pass
|
||||||
#! 9 ['param']
|
#! 9 ['param param']
|
||||||
def ab2(param): pass
|
def ab2(param): pass
|
||||||
#! 11 ['param = ClassDef']
|
#! 11 ['param = ClassDef']
|
||||||
def ab3(a=param): pass
|
def ab3(a=param): pass
|
||||||
@@ -211,7 +211,7 @@ for i in []:
|
|||||||
def dec(dec_param=3):
|
def dec(dec_param=3):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
#! 8 ['dec_param=3']
|
#! 8 ['param dec_param=3']
|
||||||
@dec(dec_param=5)
|
@dec(dec_param=5)
|
||||||
def y():
|
def y():
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user