diff --git a/jedi/api.py b/jedi/api.py index 605ea61c..7ff6c020 100644 --- a/jedi/api.py +++ b/jedi/api.py @@ -283,11 +283,12 @@ class Script(object): goto_path = self._module.get_path_under_cursor() context = self._module.get_context() + user_stmt = self._parser.user_stmt if next(context) in ('class', 'def'): user_scope = self._parser.user_scope definitions = set([user_scope.name]) search_name = unicode(user_scope.name) - elif isinstance(self._parser.user_stmt, parsing.Import): + elif isinstance(user_stmt, parsing.Import): s, name_part = self._get_on_import_stmt() try: definitions = [s.follow(is_goto=True)[0]] @@ -296,7 +297,7 @@ class Script(object): search_name = unicode(name_part) if add_import_name: - import_name = self._parser.user_stmt.get_defined_names() + import_name = user_stmt.get_defined_names() # imports have only one name if name_part == import_name[0].names[-1]: definitions.append(import_name[0]) @@ -304,6 +305,11 @@ class Script(object): stmt = self._get_under_cursor_stmt(goto_path) defs, search_name = evaluate.goto(stmt) definitions = follow_inexistent_imports(defs) + if isinstance(user_stmt, parsing.Statement): + if user_stmt.get_assignment_calls().start_pos > self.pos: + # The cursor must be after the start, otherwise the + # statement is just an assignee. + definitions = [user_stmt] return definitions, search_name def related_names(self, additional_module_paths=[]): diff --git a/jedi/evaluate.py b/jedi/evaluate.py index 725f5512..567f7d4d 100644 --- a/jedi/evaluate.py +++ b/jedi/evaluate.py @@ -1537,6 +1537,8 @@ def goto(stmt, call_path=None): scope = stmt.parent pos = stmt.start_pos call_path, search = call_path[:-1], call_path[-1] + pos = pos[0], pos[1]+1 + if call_path: scopes = follow_call_path(iter(call_path), scope, pos) search_global = False diff --git a/jedi/parsing.py b/jedi/parsing.py index 11da5c93..5022b31c 100644 --- a/jedi/parsing.py +++ b/jedi/parsing.py @@ -1262,12 +1262,11 @@ class PyFuzzyParser(object): def _check_user_stmt(self, simple): # this is not user checking, just update the used_names - if not isinstance(simple, Param): - for tok_name in self.module.temp_used_names: - try: - self.module.used_names[tok_name].add(simple) - except KeyError: - self.module.used_names[tok_name] = set([simple]) + for tok_name in self.module.temp_used_names: + try: + self.module.used_names[tok_name].add(simple) + except KeyError: + self.module.used_names[tok_name] = set([simple]) self.module.temp_used_names = [] if not self.user_position: @@ -1379,7 +1378,7 @@ class PyFuzzyParser(object): breaks = [',', ':'] while tok not in [')', ':']: param, tok = self._parse_statement(added_breaks=breaks, - stmt_class=Param) + stmt_class=Param) if param and tok == ':': # parse annotations annotation, tok = self._parse_statement(added_breaks=breaks) @@ -1656,6 +1655,7 @@ class PyFuzzyParser(object): else: stmt = stmt_class(self.module, string, set_vars, used_funcs, used_vars, tok_list, first_pos, self.end_pos) + self._check_user_stmt(stmt) if tok in always_break + not_first_break: diff --git a/test/completion/goto.py b/test/completion/goto.py index 942b1136..a231eb00 100644 --- a/test/completion/goto.py +++ b/test/completion/goto.py @@ -14,6 +14,12 @@ c = b #! ['c=b'] c +cd = 1 +#! 1 ['cd=c'] +cd = c +#! 0 ['cd=e'] +cd = e + #! ['module math'] import math #! ['import math'] @@ -135,7 +141,7 @@ class ClassDef(): # ----------------- param = ClassDef -#! 9 ['param'] +#! 8 ['param'] def ab1(param): pass #! 9 ['param'] def ab2(param): pass diff --git a/test/completion/renaming.py b/test/completion/renaming.py index 77856de2..c6e2c45b 100644 --- a/test/completion/renaming.py +++ b/test/completion/renaming.py @@ -82,12 +82,15 @@ response.write(pdf) response -class Inheritance(object): pass +class Super(object): + base_class = 1 + def base_method(self): + self.base_var -#< 20 (0,17), (-3,6) -class TestClass(Inheritance): - def a(): +#< 20 (0,16), (-6,6) +class TestClass(Super): + def a(self): pass - def b(): + def b(self): pass