From 1d3a7823d3b6b8afdfb956f7616d6c6825c80a66 Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 3 Sep 2012 19:39:05 +0400 Subject: [PATCH] Fixed parsing error in StatementParsing.parseSimpleStatement (EA-30244) --- .../python/parsing/StatementParsing.java | 16 +++++++++------- python/testData/psi/EqYieldEq.py | 1 + python/testData/psi/EqYieldEq.txt | 19 +++++++++++++++++++ .../jetbrains/python/PythonParsingTest.java | 5 +++++ 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 python/testData/psi/EqYieldEq.py create mode 100644 python/testData/psi/EqYieldEq.txt diff --git a/python/src/com/jetbrains/python/parsing/StatementParsing.java b/python/src/com/jetbrains/python/parsing/StatementParsing.java index ae8d235d62b1..96c7d4cb5e88 100644 --- a/python/src/com/jetbrains/python/parsing/StatementParsing.java +++ b/python/src/com/jetbrains/python/parsing/StatementParsing.java @@ -197,19 +197,21 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { while (true) { PsiBuilder.Marker maybeExprMarker = builder.mark(); + final boolean isYieldExpr = builder.getTokenType() == PyTokenTypes.YIELD_KEYWORD; if (!getExpressionParser().parseYieldOrTupleExpression(false)) { maybeExprMarker.drop(); builder.error(EXPRESSION_EXPECTED); break; } if (builder.getTokenType() == PyTokenTypes.EQ) { - maybeExprMarker.rollbackTo(); - final int rollbackOffset = builder.getCurrentOffset(); - getExpressionParser().parseExpression(false, true); - final int offsetAfterExpr = builder.getCurrentOffset(); - if (builder.getTokenType() != PyTokenTypes.EQ) { - LOG.error("'=' after rollback expected", builder.getTokenType() + "; " + - builder.getOriginalText().subSequence(rollbackOffset, offsetAfterExpr).toString()); + if (isYieldExpr) { + maybeExprMarker.drop(); + builder.error("Cannot assign to 'yield' expression"); + } + else { + maybeExprMarker.rollbackTo(); + getExpressionParser().parseExpression(false, true); + LOG.assertTrue(builder.getTokenType() == PyTokenTypes.EQ, builder.getTokenType()); } builder.advanceLexer(); } diff --git a/python/testData/psi/EqYieldEq.py b/python/testData/psi/EqYieldEq.py new file mode 100644 index 000000000000..96f4b800df70 --- /dev/null +++ b/python/testData/psi/EqYieldEq.py @@ -0,0 +1 @@ +bb = yield dd = cc diff --git a/python/testData/psi/EqYieldEq.txt b/python/testData/psi/EqYieldEq.txt new file mode 100644 index 000000000000..a8a58a688eb5 --- /dev/null +++ b/python/testData/psi/EqYieldEq.txt @@ -0,0 +1,19 @@ +PyFile:EqYieldEq.py + PyAssignmentStatement + PyTargetExpression: bb + PsiElement(Py:IDENTIFIER)('bb') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyYieldExpression + PsiElement(Py:YIELD_KEYWORD)('yield') + PsiWhiteSpace(' ') + PyReferenceExpression: dd + PsiElement(Py:IDENTIFIER)('dd') + PsiErrorElement:Cannot assign to 'yield' expression + + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyReferenceExpression: cc + PsiElement(Py:IDENTIFIER)('cc') \ 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 cf3edd5f3324..b4485a5e57c9 100644 --- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java @@ -343,6 +343,11 @@ public class PythonParsingTest extends ParsingTestCase { doTest(); } + // EA-30244 + public void testEqYieldEq() { + doTest(); + } + public void doTest() { doTest(LanguageLevel.PYTHON25); }