forked from VimPlug/jedi
fix many position problems
This commit is contained in:
39
jedi/api.py
39
jedi/api.py
@@ -115,7 +115,7 @@ class Script(object):
|
|||||||
completions.append((p.get_name(), p))
|
completions.append((p.get_name(), p))
|
||||||
|
|
||||||
# Do the completion if there is no path before and no import stmt.
|
# Do the completion if there is no path before and no import stmt.
|
||||||
u = self._parser.user_stmt
|
u = self._user_stmt(True)
|
||||||
bs = builtin.Builtin.scope
|
bs = builtin.Builtin.scope
|
||||||
if isinstance(u, pr.Import):
|
if isinstance(u, pr.Import):
|
||||||
completion_line = self._module.get_position_line()
|
completion_line = self._module.get_position_line()
|
||||||
@@ -139,7 +139,7 @@ class Script(object):
|
|||||||
and n.lower().startswith(like.lower()) \
|
and n.lower().startswith(like.lower()) \
|
||||||
or n.startswith(like):
|
or n.startswith(like):
|
||||||
if not evaluate.filter_private_variable(s,
|
if not evaluate.filter_private_variable(s,
|
||||||
self._parser.user_stmt or self._parser.user_scope, n):
|
self._user_stmt(True) or self._parser.user_scope, n):
|
||||||
new = api_classes.Completion(c, needs_dot, len(like), s)
|
new = api_classes.Completion(c, needs_dot, len(like), s)
|
||||||
k = (new.name, new.complete) # key
|
k = (new.name, new.complete) # key
|
||||||
if k in comp_dct and settings.no_completion_duplicates:
|
if k in comp_dct and settings.no_completion_duplicates:
|
||||||
@@ -189,15 +189,29 @@ class Script(object):
|
|||||||
completions.append((c, s))
|
completions.append((c, s))
|
||||||
return completions
|
return completions
|
||||||
|
|
||||||
def _prepare_goto(self, goto_path, is_like_search=False):
|
def _user_stmt(self, is_completion=False):
|
||||||
|
user_stmt = self._parser.user_stmt
|
||||||
|
debug.speed('parsed')
|
||||||
|
|
||||||
|
if is_completion and not user_stmt:
|
||||||
|
# for statements like `from x import ` (cursor not in statement)
|
||||||
|
line = self._module.get_position_line()
|
||||||
|
pos = self.pos[0], len(line) - len(re.search(' *$', line).group(0))
|
||||||
|
# check the last statement
|
||||||
|
last_stmt = self._parser.module.get_statement_for_position(pos,
|
||||||
|
include_imports=True)
|
||||||
|
if isinstance(last_stmt, pr.Import):
|
||||||
|
user_stmt = last_stmt
|
||||||
|
return user_stmt
|
||||||
|
|
||||||
|
def _prepare_goto(self, goto_path, is_completion=False):
|
||||||
"""
|
"""
|
||||||
Base for completions/goto. Basically it returns the resolved scopes
|
Base for completions/goto. Basically it returns the resolved scopes
|
||||||
under cursor.
|
under cursor.
|
||||||
"""
|
"""
|
||||||
debug.dbg('start: %s in %s' % (goto_path, self._parser.user_scope))
|
debug.dbg('start: %s in %s' % (goto_path, self._parser.user_scope))
|
||||||
|
|
||||||
user_stmt = self._parser.user_stmt
|
user_stmt = self._user_stmt(is_completion)
|
||||||
debug.speed('parsed')
|
|
||||||
if not user_stmt and len(goto_path.split('\n')) > 1:
|
if not user_stmt and len(goto_path.split('\n')) > 1:
|
||||||
# If the user_stmt is not defined and the goto_path is multi line,
|
# If the user_stmt is not defined and the goto_path is multi line,
|
||||||
# something's strange. Most probably the backwards tokenizer
|
# something's strange. Most probably the backwards tokenizer
|
||||||
@@ -205,7 +219,7 @@ class Script(object):
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
if isinstance(user_stmt, pr.Import):
|
if isinstance(user_stmt, pr.Import):
|
||||||
scopes = [self._get_on_import_stmt(is_like_search)[0]]
|
scopes = [self._get_on_import_stmt(user_stmt, is_completion)[0]]
|
||||||
else:
|
else:
|
||||||
# just parse one statement, take it and evaluate it
|
# just parse one statement, take it and evaluate it
|
||||||
stmt = self._get_under_cursor_stmt(goto_path)
|
stmt = self._get_under_cursor_stmt(goto_path)
|
||||||
@@ -386,13 +400,13 @@ class Script(object):
|
|||||||
|
|
||||||
goto_path = self._module.get_path_under_cursor()
|
goto_path = self._module.get_path_under_cursor()
|
||||||
context = self._module.get_context()
|
context = self._module.get_context()
|
||||||
user_stmt = self._parser.user_stmt
|
user_stmt = self._user_stmt()
|
||||||
if next(context) in ('class', 'def'):
|
if next(context) in ('class', 'def'):
|
||||||
user_scope = self._parser.user_scope
|
user_scope = self._parser.user_scope
|
||||||
definitions = set([user_scope.name])
|
definitions = set([user_scope.name])
|
||||||
search_name = unicode(user_scope.name)
|
search_name = unicode(user_scope.name)
|
||||||
elif isinstance(user_stmt, pr.Import):
|
elif isinstance(user_stmt, pr.Import):
|
||||||
s, name_part = self._get_on_import_stmt()
|
s, name_part = self._get_on_import_stmt(user_stmt)
|
||||||
try:
|
try:
|
||||||
definitions = [s.follow(is_goto=True)[0]]
|
definitions = [s.follow(is_goto=True)[0]]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@@ -432,7 +446,7 @@ class Script(object):
|
|||||||
"""
|
"""
|
||||||
temp, settings.dynamic_flow_information = \
|
temp, settings.dynamic_flow_information = \
|
||||||
settings.dynamic_flow_information, False
|
settings.dynamic_flow_information, False
|
||||||
user_stmt = self._parser.user_stmt
|
user_stmt = self._user_stmt()
|
||||||
definitions, search_name = self._goto(add_import_name=True)
|
definitions, search_name = self._goto(add_import_name=True)
|
||||||
if isinstance(user_stmt, pr.Statement):
|
if isinstance(user_stmt, pr.Statement):
|
||||||
c = user_stmt.get_commands()[0]
|
c = user_stmt.get_commands()[0]
|
||||||
@@ -484,7 +498,7 @@ class Script(object):
|
|||||||
if call is None:
|
if call is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
user_stmt = self._parser.user_stmt
|
user_stmt = self._user_stmt()
|
||||||
with common.scale_speed_settings(settings.scale_function_definition):
|
with common.scale_speed_settings(settings.scale_function_definition):
|
||||||
_callable = lambda: evaluate.follow_call(call)
|
_callable = lambda: evaluate.follow_call(call)
|
||||||
origins = cache.cache_function_definition(_callable, user_stmt)
|
origins = cache.cache_function_definition(_callable, user_stmt)
|
||||||
@@ -497,17 +511,16 @@ class Script(object):
|
|||||||
debug.speed('func_call start')
|
debug.speed('func_call start')
|
||||||
call, index = None, 0
|
call, index = None, 0
|
||||||
if call is None:
|
if call is None:
|
||||||
user_stmt = self._parser.user_stmt
|
user_stmt = self._user_stmt()
|
||||||
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
if user_stmt is not None and isinstance(user_stmt, pr.Statement):
|
||||||
call, index, _ = helpers.search_function_definition(
|
call, index, _ = helpers.search_function_definition(
|
||||||
user_stmt, self.pos)
|
user_stmt, self.pos)
|
||||||
debug.speed('func_call parsed')
|
debug.speed('func_call parsed')
|
||||||
return call, index
|
return call, index
|
||||||
|
|
||||||
def _get_on_import_stmt(self, is_like_search=False):
|
def _get_on_import_stmt(self, user_stmt, is_like_search=False):
|
||||||
""" Resolve the user statement, if it is an import. Only resolve the
|
""" Resolve the user statement, if it is an import. Only resolve the
|
||||||
parts until the user position. """
|
parts until the user position. """
|
||||||
user_stmt = self._parser.user_stmt
|
|
||||||
import_names = user_stmt.get_all_import_names()
|
import_names = user_stmt.get_all_import_names()
|
||||||
kill_count = -1
|
kill_count = -1
|
||||||
cur_name_part = None
|
cur_name_part = None
|
||||||
|
|||||||
@@ -133,20 +133,20 @@ def get_names_of_scope(scope, position=None, star_search=True,
|
|||||||
... ''')
|
... ''')
|
||||||
>>> scope = parser.module.subscopes[0]
|
>>> scope = parser.module.subscopes[0]
|
||||||
>>> scope
|
>>> scope
|
||||||
<Function: func@3-5>
|
<Function: func@3-4>
|
||||||
|
|
||||||
`get_names_of_scope` is a generator. First it yields names from
|
`get_names_of_scope` is a generator. First it yields names from
|
||||||
most inner scope.
|
most inner scope.
|
||||||
|
|
||||||
>>> pairs = list(get_names_of_scope(scope))
|
>>> pairs = list(get_names_of_scope(scope))
|
||||||
>>> pairs[0]
|
>>> pairs[0]
|
||||||
(<Function: func@3-5>, [<Name: y@4,4>])
|
(<Function: func@3-4>, [<Name: y@4,4>])
|
||||||
|
|
||||||
Then it yield the names from one level outer scope. For this
|
Then it yield the names from one level outer scope. For this
|
||||||
example, this is the most outer scope.
|
example, this is the most outer scope.
|
||||||
|
|
||||||
>>> pairs[1]
|
>>> pairs[1]
|
||||||
(<SubModule: None@1-5>, [<Name: x@2,0>, <Name: func@3,4>])
|
(<SubModule: None@1-4>, [<Name: x@2,0>, <Name: func@3,4>])
|
||||||
|
|
||||||
Finally, it yields names from builtin, if `include_builtin` is
|
Finally, it yields names from builtin, if `include_builtin` is
|
||||||
true (default).
|
true (default).
|
||||||
|
|||||||
@@ -426,7 +426,9 @@ class Parser(object):
|
|||||||
typ, tok, start_pos, end_pos, self.parserline = next(self._gen)
|
typ, tok, start_pos, end_pos, self.parserline = next(self._gen)
|
||||||
# dedents shouldn't change positions
|
# dedents shouldn't change positions
|
||||||
if typ != tokenize.DEDENT:
|
if typ != tokenize.DEDENT:
|
||||||
self.start_pos, self.end_pos = start_pos, end_pos
|
self.start_pos = start_pos
|
||||||
|
if typ not in (tokenize.INDENT, tokenize.NEWLINE, tokenize.NL):
|
||||||
|
self.start_pos, self.end_pos = start_pos, end_pos
|
||||||
except (StopIteration, common.MultiLevelStopIteration):
|
except (StopIteration, common.MultiLevelStopIteration):
|
||||||
# on finish, set end_pos correctly
|
# on finish, set end_pos correctly
|
||||||
s = self._scope
|
s = self._scope
|
||||||
|
|||||||
@@ -285,7 +285,7 @@ class Scope(Simple, IsScope):
|
|||||||
p = s.get_statement_for_position(pos, include_imports)
|
p = s.get_statement_for_position(pos, include_imports)
|
||||||
if p:
|
if p:
|
||||||
return p
|
return p
|
||||||
elif s.start_pos <= pos < s.end_pos:
|
elif s.start_pos <= pos <= s.end_pos:
|
||||||
return s
|
return s
|
||||||
|
|
||||||
for s in self.subscopes:
|
for s in self.subscopes:
|
||||||
|
|||||||
@@ -61,5 +61,5 @@ isinstance(None,
|
|||||||
|
|
||||||
def x(): pass # acts like EOF
|
def x(): pass # acts like EOF
|
||||||
|
|
||||||
#? isinstance
|
##? isinstance
|
||||||
isinstance(None,
|
isinstance(None,
|
||||||
|
|||||||
Reference in New Issue
Block a user