1
0
forked from VimPlug/jedi

Fix goto tests.

This commit is contained in:
Dave Halter
2016-11-17 23:28:47 +01:00
parent d15016c5c1
commit 05581714d9
10 changed files with 114 additions and 35 deletions
+20 -12
View File
@@ -66,6 +66,7 @@ from itertools import chain
from jedi.parser import tree
from jedi import debug
from jedi.common import unite
from jedi.evaluate import representation as er
from jedi.evaluate import imports
from jedi.evaluate import recursion
@@ -77,7 +78,7 @@ from jedi.evaluate import compiled
from jedi.evaluate import precedence
from jedi.evaluate import param
from jedi.evaluate import helpers
from jedi.evaluate.context import Context
from jedi.evaluate.filters import TreeNameDefinition
from jedi.evaluate.instance import AnonymousInstance, AnonymousInstanceFunctionExecution
@@ -461,36 +462,43 @@ class Evaluator(object):
param_names = []
for typ in types:
try:
params = typ.params
get_param_names = typ.get_param_names
except AttributeError:
pass
else:
param_names += [param.name for param in params
if param.name.value == name.value]
for param_name in get_param_names():
if param_name.string_name == name.value:
param_names.append(param_name)
return param_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
# 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:
return [name]
return [TreeNameDefinition(context, name)]
elif isinstance(stmt, tree.Import):
modules = imports.ImportWrapper(context, name).follow(is_goto=True)
return list(resolve_implicit_imports(modules))
module_names = imports.ImportWrapper(context, name).follow(is_goto=True)
return module_names
return list(resolve_implicit_imports(module_names))
elif par.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:] = []
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(
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] == '.':
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(
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
# there the name cannot be used.
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)
def wrap(self, element, parent_context):
+9 -1
View File
@@ -85,7 +85,8 @@ class CompiledObject(Context):
return inspect.getdoc(self.obj) or ''
@property
def params(self):
def get_params(self):
return [] # TODO Fix me.
params_str, ret = self._parse_function_doc()
tokens = params_str.split(',')
if inspect.ismethoddescriptor(self.obj):
@@ -280,6 +281,9 @@ class CompiledName(AbstractNameDefinition):
name = None
return '<%s: (%s).%s>' % (self.__class__.__name__, name, self.string_name)
def api_type(self):
return self.infer()[0].api_type
@underscore_memoization
def infer(self):
module = self.parent_context.get_root_context()
@@ -291,6 +295,10 @@ class CompiledContextName(AbstractNameDefinition):
self.string_name = name
self.parent_context = parent_context
@property
def api_type(self):
return self.parent_context.api_type
def infer(self):
return [self.parent_context]
+16
View File
@@ -51,6 +51,10 @@ class ContextName(AbstractNameDefinition):
def infer(self):
return [self.parent_context]
@property
def api_type(self):
return self.parent_context.api_type
class TreeNameDefinition(ContextName):
def get_parent_flow_context(self):
@@ -61,8 +65,20 @@ class TreeNameDefinition(ContextName):
from jedi.evaluate.finder import _name_to_types
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):
api_type = 'param'
def __init__(self, parent_context, tree_name):
self.parent_context = parent_context
self.tree_name = tree_name
-1
View File
@@ -144,7 +144,6 @@ class FakeName(tree.Name):
In case is_definition is defined (not None), that bool value will be
returned.
"""
raise NotImplementedError
super(FakeName, self).__init__(name_str, start_pos)
self.parent = parent
self._is_definition = is_definition
+2
View File
@@ -68,6 +68,8 @@ class SpecialMethodFilter(DictFilter):
classes like Generator (for __next__, etc).
"""
class SpecialMethodName(AbstractNameDefinition):
api_type = 'function'
def __init__(self, parent_context, string_name, callable_, builtin_context):
self.parent_context = parent_context
self.string_name = string_name
+27 -9
View File
@@ -54,7 +54,8 @@ from jedi.evaluate import param
from jedi.evaluate import flow_analysis
from jedi.evaluate import imports
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 import context
@@ -470,12 +471,10 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
def py__class__(self):
return compiled.create(self.evaluator, type)
@property
def params(self):
try:
return self.get_subscope_by_name('__init__').params
except KeyError:
return [] # object.__init__
def get_params(self):
from jedi.evaluate.instance import AnonymousInstance
anon = AnonymousInstance(self.evaluator, self.parent_context, self)
return [AnonymousInstanceParamName(anon, param.name) for param in self.funcdef.params]
def names_dicts(self, search_global, is_instance=False):
if search_global:
@@ -509,6 +508,13 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper))
return sub
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):
return "<%s of %s>" % (self.__class__.__name__, self.classdef)
@@ -582,6 +588,14 @@ class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrappe
def name(self):
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):
def get_decorated_func(self):
@@ -747,6 +761,8 @@ class ModuleAttributeName(AbstractNameDefinition):
"""
For module attributes like __file__, __str__ and so on.
"""
api_type = 'instance'
def __init__(self, parent_module, string_name):
self.parent_context = parent_module
self.string_name = string_name
@@ -758,8 +774,9 @@ class ModuleAttributeName(AbstractNameDefinition):
class SubModuleName(AbstractNameDefinition):
"""
"""
api_type = 'module'
start_pos = (1, 0)
def __init__(self, parent_module, string_name):
self.parent_context = parent_module
self.string_name = string_name
@@ -774,6 +791,7 @@ class SubModuleName(AbstractNameDefinition):
class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext, Wrapper)):
api_type = 'module'
parent_context = None
def __init__(self, evaluator, module_node):