forked from VimPlug/jedi
trying to clean up the goto mess
This commit is contained in:
+34
-6
@@ -241,7 +241,7 @@ class Script(object):
|
|||||||
return scopes
|
return scopes
|
||||||
|
|
||||||
def _get_under_cursor_stmt(self, cursor_txt):
|
def _get_under_cursor_stmt(self, cursor_txt):
|
||||||
tokenizer = source_tokens(cursor_txt, self._pos[0] - 1)
|
tokenizer = source_tokens(cursor_txt, line_offset=self._pos[0] - 1)
|
||||||
r = Parser(cursor_txt, no_docstr=True, tokenizer=tokenizer)
|
r = Parser(cursor_txt, no_docstr=True, tokenizer=tokenizer)
|
||||||
try:
|
try:
|
||||||
# Take the last statement available.
|
# Take the last statement available.
|
||||||
@@ -249,12 +249,12 @@ class Script(object):
|
|||||||
except IndexError:
|
except IndexError:
|
||||||
raise NotFoundError()
|
raise NotFoundError()
|
||||||
user_stmt = self._parser.user_stmt()
|
user_stmt = self._parser.user_stmt()
|
||||||
if user_stmt is None or isinstance(user_stmt, pr.Param):
|
if type(user_stmt) is pr.Statement:
|
||||||
|
stmt.start_pos = user_stmt.start_pos
|
||||||
|
else:
|
||||||
# Set the start_pos to a pseudo position, that doesn't exist but works
|
# Set the start_pos to a pseudo position, that doesn't exist but works
|
||||||
# perfectly well (for both completions in docstrings and statements).
|
# perfectly well (for both completions in docstrings and statements).
|
||||||
stmt.start_pos = self._pos
|
stmt.start_pos = self._pos
|
||||||
else:
|
|
||||||
stmt.start_pos = user_stmt.start_pos[0], user_stmt.start_pos[1] - 1
|
|
||||||
stmt.parent = self._parser.user_scope()
|
stmt.parent = self._parser.user_scope()
|
||||||
return stmt
|
return stmt
|
||||||
|
|
||||||
@@ -427,8 +427,36 @@ class Script(object):
|
|||||||
definitions.append(import_name[0])
|
definitions.append(import_name[0])
|
||||||
else:
|
else:
|
||||||
stmt = self._get_under_cursor_stmt(goto_path)
|
stmt = self._get_under_cursor_stmt(goto_path)
|
||||||
defs, search_name = self._evaluator.goto(stmt)
|
|
||||||
definitions = follow_inexistent_imports(defs)
|
def test_lhs():
|
||||||
|
"""
|
||||||
|
Special rule for goto, left hand side of the statement returns
|
||||||
|
itself, if the name is ``foo``, but not ``foo.bar``.
|
||||||
|
"""
|
||||||
|
if isinstance(user_stmt, pr.Statement):
|
||||||
|
for name in user_stmt.get_set_vars():
|
||||||
|
if name.start_pos <= self._pos <= name.end_pos \
|
||||||
|
and len(name.names) == 1:
|
||||||
|
return user_stmt, name.names[-1]
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
lhs, search_name = test_lhs()
|
||||||
|
if lhs is None:
|
||||||
|
expression_list = stmt.expression_list()
|
||||||
|
if len(expression_list) == 0:
|
||||||
|
return [], ''
|
||||||
|
# Only the first command is important, the rest should basically not
|
||||||
|
# happen except in broken code (e.g. docstrings that aren't code).
|
||||||
|
call = expression_list[0]
|
||||||
|
if isinstance(call, pr.Call):
|
||||||
|
call_path = list(call.generate_call_path())
|
||||||
|
else:
|
||||||
|
call_path = [call]
|
||||||
|
|
||||||
|
defs, search_name = self._evaluator.goto(stmt, call_path)
|
||||||
|
definitions = follow_inexistent_imports(defs)
|
||||||
|
else:
|
||||||
|
definitions = [lhs]
|
||||||
if isinstance(user_stmt, pr.Statement):
|
if isinstance(user_stmt, pr.Statement):
|
||||||
c = user_stmt.expression_list()
|
c = user_stmt.expression_list()
|
||||||
if c and not isinstance(c[0], (str, unicode)) \
|
if c and not isinstance(c[0], (str, unicode)) \
|
||||||
|
|||||||
@@ -328,24 +328,9 @@ class Evaluator(object):
|
|||||||
debug.dbg('execute result: %s in %s', stmts, obj)
|
debug.dbg('execute result: %s in %s', stmts, obj)
|
||||||
return imports.strip_imports(self, stmts)
|
return imports.strip_imports(self, stmts)
|
||||||
|
|
||||||
def goto(self, stmt, call_path=None):
|
def goto(self, stmt, call_path):
|
||||||
if call_path is None:
|
|
||||||
expression_list = stmt.expression_list()
|
|
||||||
if len(expression_list) == 0:
|
|
||||||
return [], ''
|
|
||||||
# Only the first command is important, the rest should basically not
|
|
||||||
# happen except in broken code (e.g. docstrings that aren't code).
|
|
||||||
call = expression_list[0]
|
|
||||||
if isinstance(call, pr.Call):
|
|
||||||
call_path = list(call.generate_call_path())
|
|
||||||
else:
|
|
||||||
call_path = [call]
|
|
||||||
|
|
||||||
scope = stmt.get_parent_until(pr.IsScope)
|
scope = stmt.get_parent_until(pr.IsScope)
|
||||||
pos = stmt.start_pos
|
pos = stmt.start_pos
|
||||||
# Need this to return the params if you're actually doing a goto on the
|
|
||||||
# param.
|
|
||||||
pos = pos[0], pos[1] + 1
|
|
||||||
call_path, search = call_path[:-1], call_path[-1]
|
call_path, search = call_path[:-1], call_path[-1]
|
||||||
|
|
||||||
if call_path:
|
if call_path:
|
||||||
@@ -353,6 +338,7 @@ class Evaluator(object):
|
|||||||
search_global = False
|
search_global = False
|
||||||
pos = None
|
pos = None
|
||||||
else:
|
else:
|
||||||
|
# TODO does this exist? i don't think so
|
||||||
scopes = [scope]
|
scopes = [scope]
|
||||||
search_global = True
|
search_global = True
|
||||||
follow_res = []
|
follow_res = []
|
||||||
|
|||||||
Reference in New Issue
Block a user