Fix one-line error recovery for all things that are using a suite

Fixes https://github.com/davidhalter/jedi/issues/1138.
This commit is contained in:
Dave Halter
2018-06-12 12:56:27 +02:00
parent 23db71a5f7
commit cef9f1bdbd
3 changed files with 36 additions and 6 deletions

View File

@@ -40,8 +40,8 @@ class Stack(list):
def get_tos_first_tokens(self, grammar):
tos = self[-1]
inv_tokens = {v: k for k, v in grammar.tokens.items()}
inv_keywords = {v: k for k, v in grammar.keywords.items()}
inv_tokens = dict((v, k) for k, v in grammar.tokens.items())
inv_keywords = dict((v, k) for k, v in grammar.keywords.items())
dfa, state, nodes = tos
def check():
@@ -51,7 +51,7 @@ class Stack(list):
except KeyError:
yield tokenize.tok_name[inv_tokens[first]]
return list(check())
return sorted(check())
def token_to_ilabel(grammar, type_, value):

View File

@@ -160,7 +160,6 @@ class Parser(BaseParser):
dfa, state, (type_, nodes) = stack[-1]
states, first = dfa
# In Python statements need to end with a newline. But since it's
# possible (and valid in Python ) that there's no newline at the
# end of a file, we have to recover even if the user doesn't want
@@ -198,12 +197,22 @@ class Parser(BaseParser):
def current_suite(stack):
# For now just discard everything that is not a suite or
# file_input, if we detect an error.
suite_with_newline = False
for index, (symbol, nodes) in reversed(list(enumerate(get_symbol_and_nodes(stack)))):
# `suite` can sometimes be only simple_stmt, not stmt.
if symbol == 'file_input':
break
elif symbol == 'suite' and len(nodes) > 1:
# suites without an indent in them get discarded.
elif symbol == 'suite':
if len(nodes) > 1:
break
elif nodes:
suite_with_newline = True
# `suite` without an indent are error nodes.
continue
elif symbol in ('with_stmt', 'if_stmt', 'while_stmt',
# 'funcdef', 'classdef',
'try_stmt') \
and nodes[-1] == ':' and not suite_with_newline:
break
return index, symbol, nodes