only allow single expression after 'in'; tweak error recovery when waiting for colon (PY-9561)

This commit is contained in:
Dmitry Jemerov
2013-11-06 19:17:41 +01:00
parent 7f8dc3deca
commit 52efcb58c5
5 changed files with 44 additions and 13 deletions
@@ -598,13 +598,17 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
final PsiBuilder.Marker ifStatement = myBuilder.mark();
final PsiBuilder.Marker ifPart = myBuilder.mark();
myBuilder.advanceLexer();
getExpressionParser().parseExpression();
if (!getExpressionParser().parseSingleExpression(false)) {
myBuilder.error("expression expected");
}
parseColonAndSuite(scope);
ifPart.done(PyElementTypes.IF_PART_IF);
PsiBuilder.Marker elifPart = myBuilder.mark();
while (myBuilder.getTokenType() == elifKeyword) {
myBuilder.advanceLexer();
getExpressionParser().parseExpression();
if (!getExpressionParser().parseSingleExpression(false)) {
myBuilder.error("expression expected");
}
parseColonAndSuite(scope);
elifPart.done(PyElementTypes.IF_PART_ELIF);
elifPart = myBuilder.mark();
@@ -628,11 +632,15 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
return true;
}
final PsiBuilder.Marker marker = myBuilder.mark();
if (myBuilder.getTokenType() == PyTokenTypes.STATEMENT_BREAK) {
while (!atAnyOfTokens(null, PyTokenTypes.DEDENT, PyTokenTypes.STATEMENT_BREAK, PyTokenTypes.COLON)) {
myBuilder.advanceLexer();
}
boolean result = matchToken(PyTokenTypes.COLON);
if (!result && atToken(PyTokenTypes.STATEMENT_BREAK)) {
myBuilder.advanceLexer();
}
marker.error("Colon expected");
return false;
return result;
}
private void parseForStatement(ParsingScope scope) {
+2
View File
@@ -0,0 +1,2 @@
if "string" in "string", "string2":
pass
+22
View File
@@ -0,0 +1,22 @@
PyFile:IfInList.py
PyIfStatement
PyIfPartIf
PsiElement(Py:IF_KEYWORD)('if')
PsiWhiteSpace(' ')
PyBinaryExpression
PyStringLiteralExpression: string
PsiElement(Py:SINGLE_QUOTED_STRING)('"string"')
PsiWhiteSpace(' ')
PsiElement(Py:IN_KEYWORD)('in')
PsiWhiteSpace(' ')
PyStringLiteralExpression: string
PsiElement(Py:SINGLE_QUOTED_STRING)('"string"')
PsiErrorElement:Colon expected
PsiElement(Py:COMMA)(',')
PsiWhiteSpace(' ')
PsiElement(Py:SINGLE_QUOTED_STRING)('"string2"')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')
+4 -9
View File
@@ -73,13 +73,8 @@ PyFile:WithStatement2.py
PsiErrorElement:expression expected
<empty list>
PsiErrorElement:Colon expected
<empty list>
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PsiElement(Py:INTEGER_LITERAL)('1')
PyStatementList
<empty list>
PsiElement(Py:EQ)('=')
PsiErrorElement:Statement expected, found Py:EQ
<empty list>
PsiWhiteSpace(' ')
PyExpressionStatement
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('1')
<empty list>
@@ -418,6 +418,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
public void testIfInList() { // PY-9561
doTest();
}
public void doTest(LanguageLevel languageLevel) {
LanguageLevel prev = myLanguageLevel;
myLanguageLevel = languageLevel;