Fixed error recovery after empty blocks with no indent

This commit is contained in:
Andrey Vlasovskikh
2014-02-26 16:26:12 +04:00
parent 841e5c66d8
commit 09bd5b323a
4 changed files with 57 additions and 5 deletions
@@ -809,10 +809,8 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
myBuilder.advanceLexer();
final PsiBuilder.Marker marker = myBuilder.mark();
if (myBuilder.getTokenType() != PyTokenTypes.INDENT) {
myBuilder.error("Indent expected");
}
else {
final boolean indentFound = myBuilder.getTokenType() == PyTokenTypes.INDENT;
if (indentFound) {
myBuilder.advanceLexer();
if (myBuilder.eof()) {
myBuilder.error("Indented block expected");
@@ -823,13 +821,16 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
}
}
}
else {
myBuilder.error("Indent expected");
}
marker.done(PyElementTypes.STATEMENT_LIST);
marker.setCustomEdgeTokenBinders(LeadingCommentsBinder.INSTANCE, FollowingCommentBinder.INSTANCE);
if (endMarker != null) {
endMarker.done(elType);
}
if (!myBuilder.eof()) {
if (indentFound && !myBuilder.eof()) {
checkMatches(PyTokenTypes.DEDENT, "Dedent expected");
}
// NOTE: the following line advances the PsiBuilder lexer and thus
@@ -0,0 +1,6 @@
def foo(xs):
for x in xs:
def bar():
pass
@@ -0,0 +1,41 @@
PyFile:EmptyBlockInFunctionBeforeFunction.py
PyFunction('foo')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('foo')
PyParameterList
PsiElement(Py:LPAR)('(')
PyNamedParameter('xs')
PsiElement(Py:IDENTIFIER)('xs')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyForStatement
PyForPart
PsiElement(Py:FOR_KEYWORD)('for')
PsiWhiteSpace(' ')
PyTargetExpression: x
PsiElement(Py:IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(Py:IN_KEYWORD)('in')
PsiWhiteSpace(' ')
PyReferenceExpression: xs
PsiElement(Py:IDENTIFIER)('xs')
PsiElement(Py:COLON)(':')
PyStatementList
PsiErrorElement:Indent expected
<empty list>
PsiWhiteSpace('\n\n\n')
PyFunction('bar')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('bar')
PyParameterList
PsiElement(Py:LPAR)('(')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')
@@ -447,6 +447,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest(LanguageLevel.PYTHON33);
}
public void testEmptyBlockInFunctionBeforeFunction() {
doTest();
}
public void doTest(LanguageLevel languageLevel) {
LanguageLevel prev = myLanguageLevel;
myLanguageLevel = languageLevel;