From 60d0628886bfc24b5dc70c3969b7c9d8fef0a598 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Thu, 21 Feb 2013 18:44:46 +0400 Subject: [PATCH] fixed PY-8948 Not closed quote in subscription breaks parsing for the whole file --- .../python/parsing/ExpressionParsing.java | 11 +++++++- python/testData/psi/NotClosedSlice.py | 3 +++ python/testData/psi/NotClosedSlice.txt | 25 +++++++++++++++++++ .../jetbrains/python/PythonParsingTest.java | 5 ++++ 4 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 python/testData/psi/NotClosedSlice.py create mode 100644 python/testData/psi/NotClosedSlice.txt diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java index 74ee45358b63..39455a491a2c 100644 --- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java +++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java @@ -606,13 +606,21 @@ public class ExpressionParsing extends Parsing { return false; } if (myBuilder.getTokenType() == PyTokenTypes.IF_KEYWORD) { + PsiBuilder.Marker conditionMarker = myBuilder.mark(); myBuilder.advanceLexer(); if (!parseORTestExpression(stopOnIn, isTargetExpression)) { myBuilder.error(message("PARSE.expected.expression")); } else { if (myBuilder.getTokenType() != PyTokenTypes.ELSE_KEYWORD) { - myBuilder.error(message("PARSE.expected.else")); + if (atToken(PyTokenTypes.COLON)) { // it's regular if statement. Bracket wasn't closed or new line was lost + conditionMarker.rollbackTo(); + condExpr.drop(); + return true; + } + else { + myBuilder.error(message("PARSE.expected.else")); + } } else { myBuilder.advanceLexer(); @@ -621,6 +629,7 @@ public class ExpressionParsing extends Parsing { } } } + conditionMarker.drop(); condExpr.done(PyElementTypes.CONDITIONAL_EXPRESSION); } else { diff --git a/python/testData/psi/NotClosedSlice.py b/python/testData/psi/NotClosedSlice.py new file mode 100644 index 000000000000..0bf7006a87c6 --- /dev/null +++ b/python/testData/psi/NotClosedSlice.py @@ -0,0 +1,3 @@ +a["key""]" +if True: + pass \ No newline at end of file diff --git a/python/testData/psi/NotClosedSlice.txt b/python/testData/psi/NotClosedSlice.txt new file mode 100644 index 000000000000..1e9c15c5f502 --- /dev/null +++ b/python/testData/psi/NotClosedSlice.txt @@ -0,0 +1,25 @@ +PyFile:NotClosedSlice.py + PyExpressionStatement + PyConditionalExpression + PySubscriptionExpression + PyReferenceExpression: a + PsiElement(Py:IDENTIFIER)('a') + PsiElement(Py:LBRACKET)('[') + PyConditionalExpression + PyStringLiteralExpression: key] + PsiElement(Py:SINGLE_QUOTED_STRING)('"key"') + PsiElement(Py:SINGLE_QUOTED_STRING)('"]"') + PsiErrorElement:']' expected + + PsiWhiteSpace('\n') + PyIfStatement + PyIfPartIf + PsiElement(Py:IF_KEYWORD)('if') + PsiWhiteSpace(' ') + PyReferenceExpression: True + PsiElement(Py:IDENTIFIER)('True') + PsiElement(Py:COLON)(':') + PsiWhiteSpace('\n ') + PyStatementList + PyPassStatement + PsiElement(Py:PASS_KEYWORD)('pass') \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonParsingTest.java b/python/testSrc/com/jetbrains/python/PythonParsingTest.java index f338c203a2c8..53687856cf7a 100644 --- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java @@ -375,6 +375,11 @@ public class PythonParsingTest extends ParsingTestCase { doTest(LanguageLevel.PYTHON33); } + // PY-8948 + public void testNotClosedSlice() { + doTest(); + } + public void doTest(LanguageLevel languageLevel) { LanguageLevel prev = myLanguageLevel; myLanguageLevel = languageLevel;