diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index a2fef332..b9e3ce68 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -76,7 +76,6 @@ from jedi.evaluate import compiled from jedi.evaluate import precedence from jedi.evaluate import param from jedi.evaluate import helpers -from jedi.evaluate.helpers import call_of_name class Evaluator(object): @@ -281,7 +280,7 @@ class Evaluator(object): def_ = name.get_definition() if def_.type == 'expr_stmt' and name in def_.get_defined_names(): return self.eval_statement(def_, name) - call = call_of_name(name) + call = helpers.call_of_name(name) return self.eval_element(call) def goto(self, name): @@ -328,10 +327,19 @@ class Evaluator(object): return [name] elif isinstance(stmt, pr.Import): return imports.ImportWrapper(self, name).follow(is_goto=True) + 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(new_dotted) + return resolve_implicit_imports(iterable.unite( + self.find_types(typ, name, is_goto=True) for typ in types + )) scope = name.get_parent_scope() if pr.is_node(name.parent, 'trailer'): - call = call_of_name(name, cut_own_trailer=True) + call = helpers.call_of_name(name, cut_own_trailer=True) types = self.eval_element(call) return resolve_implicit_imports(iterable.unite( self.find_types(typ, name, is_goto=True) for typ in types diff --git a/test/completion/goto.py b/test/completion/goto.py index 1098bed1..84bcc2c8 100644 --- a/test/completion/goto.py +++ b/test/completion/goto.py @@ -202,3 +202,17 @@ def dec(dec_param=3): @dec(dec_param=5) def y(): pass + +class ClassDec(): + def class_func(func): + return func + +#! 14 ['def class_func'] +@ClassDec.class_func +def x(): + pass + +#! 2 ['class ClassDec'] +@ClassDec.class_func +def z(): + pass