diff --git a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java index b4e2e562fb5c..bc11498e7dc1 100644 --- a/python/src/com/jetbrains/python/parsing/ExpressionParsing.java +++ b/python/src/com/jetbrains/python/parsing/ExpressionParsing.java @@ -151,8 +151,7 @@ public class ExpressionParsing extends Parsing { final PsiBuilder.Marker expr = myBuilder.mark(); myBuilder.advanceLexer(); - if (myBuilder.getTokenType() == PyTokenTypes.RBRACE) { - myBuilder.advanceLexer(); + if (matchToken(PyTokenTypes.RBRACE)) { expr.done(PyElementTypes.DICT_LITERAL_EXPRESSION); return; } @@ -165,15 +164,14 @@ public class ExpressionParsing extends Parsing { return; } - if (myBuilder.getTokenType() == PyTokenTypes.COLON) { - myBuilder.advanceLexer(); + if (matchToken(PyTokenTypes.COLON)) { parseDictLiteralTail(expr, firstExprMarker); } - else if (myBuilder.getTokenType() == PyTokenTypes.COMMA || myBuilder.getTokenType() == PyTokenTypes.RBRACE) { + else if (atToken(PyTokenTypes.COMMA) || atToken(PyTokenTypes.RBRACE)) { firstExprMarker.drop(); parseSetLiteralTail(expr); } - else if (myBuilder.getTokenType() == PyTokenTypes.FOR_KEYWORD) { + else if (atToken(PyTokenTypes.FOR_KEYWORD)) { firstExprMarker.drop(); parseComprehension(expr, PyTokenTypes.RBRACE, PyElementTypes.SET_COMP_EXPRESSION); } @@ -196,16 +194,11 @@ public class ExpressionParsing extends Parsing { parseComprehension(startMarker, PyTokenTypes.RBRACE, PyElementTypes.DICT_COMP_EXPRESSION); } else { - if (myBuilder.getTokenType() == PyTokenTypes.COMMA) { - myBuilder.advanceLexer(); - } while (myBuilder.getTokenType() != PyTokenTypes.RBRACE) { + checkMatches(PyTokenTypes.COMMA, message("PARSE.expected.comma")); if (!parseKeyValueExpression()) { break; } - if (myBuilder.getTokenType() != PyTokenTypes.RBRACE) { - checkMatches(PyTokenTypes.COMMA, message("PARSE.expected.comma")); - } } myBuilder.advanceLexer(); startMarker.done(PyElementTypes.DICT_LITERAL_EXPRESSION); diff --git a/python/testData/psi/DictMissingComma.py b/python/testData/psi/DictMissingComma.py new file mode 100644 index 000000000000..22126c055bbb --- /dev/null +++ b/python/testData/psi/DictMissingComma.py @@ -0,0 +1 @@ +d = {'key1':1 'key2':2} \ No newline at end of file diff --git a/python/testData/psi/DictMissingComma.txt b/python/testData/psi/DictMissingComma.txt new file mode 100644 index 000000000000..0ec802270c1f --- /dev/null +++ b/python/testData/psi/DictMissingComma.txt @@ -0,0 +1,25 @@ +PyFile:DictMissingComma.py + PyAssignmentStatement + PyTargetExpression: d + PsiElement(Py:IDENTIFIER)('d') + PsiWhiteSpace(' ') + PsiElement(Py:EQ)('=') + PsiWhiteSpace(' ') + PyDictLiteralExpression + PsiElement(Py:LBRACE)('{') + PyKeyValueExpression + PyStringLiteralExpression: key1 + PsiElement(Py:STRING_LITERAL)(''key1'') + PsiElement(Py:COLON)(':') + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('1') + PsiErrorElement:',' expected + + PsiWhiteSpace(' ') + PyKeyValueExpression + PyStringLiteralExpression: key2 + PsiElement(Py:STRING_LITERAL)(''key2'') + PsiElement(Py:COLON)(':') + PyNumericLiteralExpression + PsiElement(Py:INTEGER_LITERAL)('2') + PsiElement(Py:RBRACE)('}') \ 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 773ed87d4deb..4ccbb77e3e60 100644 --- a/python/testSrc/com/jetbrains/python/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonParsingTest.java @@ -202,6 +202,10 @@ public class PythonParsingTest extends ParsingTestCase { doTest(LanguageLevel.PYTHON30); } + public void testDictMissingComma() throws Exception { // PY-1025 + doTest(); + } + public void doTest() throws Exception { doTest(LanguageLevel.PYTHON25); }