diff --git a/python/python-psi-impl/src/com/jetbrains/python/parsing/StatementParsing.java b/python/python-psi-impl/src/com/jetbrains/python/parsing/StatementParsing.java index 23bc91f605db..f7ecb28c3014 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/parsing/StatementParsing.java +++ b/python/python-psi-impl/src/com/jetbrains/python/parsing/StatementParsing.java @@ -191,7 +191,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper { myBuilder.advanceLexer(); if (!getPatternParser().parseCasePattern()) { SyntaxTreeBuilder.Marker patternError = myBuilder.mark(); - while (!myBuilder.eof() && !atAnyOfTokens(PyTokenTypes.IF_KEYWORD, PyTokenTypes.COLON)) { + while (!myBuilder.eof() && !atAnyOfTokens(PyTokenTypes.IF_KEYWORD, PyTokenTypes.COLON, PyTokenTypes.STATEMENT_BREAK)) { nextToken(); } patternError.error(PyPsiBundle.message("PARSE.expected.pattern")); diff --git a/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause.py b/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause.py new file mode 100644 index 000000000000..ff245238744d --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause.py @@ -0,0 +1,7 @@ +match x: + case 1: + pass + case + case 3: + pass + case \ No newline at end of file diff --git a/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause_after.py b/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause_after.py new file mode 100644 index 000000000000..8340aafac28b --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause_after.py @@ -0,0 +1,7 @@ +match x: + case 1: + pass + case : + case 3: + pass + case : \ No newline at end of file diff --git a/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause.py b/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause.py new file mode 100644 index 000000000000..ec7050d4f2ed --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause.py @@ -0,0 +1,6 @@ +match x: + case 1: + pass + case + case 3: + pass \ No newline at end of file diff --git a/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause_after.py b/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause_after.py new file mode 100644 index 000000000000..e4be1c81232c --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAfterIntermediateCaseClause_after.py @@ -0,0 +1,6 @@ +match x: + case 1: + pass + case : + case 3: + pass \ No newline at end of file diff --git a/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause.py b/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause.py new file mode 100644 index 000000000000..883eef844ff7 --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause.py @@ -0,0 +1,6 @@ +match x: + case 1: + pass + case 2 + case 3: + pass \ No newline at end of file diff --git a/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause_after.py b/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause_after.py new file mode 100644 index 000000000000..254e9801347e --- /dev/null +++ b/python/testData/codeInsight/smartEnter/colonAndIndentAfterIntermediateCaseClause_after.py @@ -0,0 +1,7 @@ +match x: + case 1: + pass + case 2: + + case 3: + pass \ No newline at end of file diff --git a/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.py b/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.py new file mode 100644 index 000000000000..39df7ec45c51 --- /dev/null +++ b/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.py @@ -0,0 +1,6 @@ +match x: + case True: + pass + case + case True: + pass \ No newline at end of file diff --git a/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.txt b/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.txt new file mode 100644 index 000000000000..dea77fbacf40 --- /dev/null +++ b/python/testData/psi/PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.txt @@ -0,0 +1,41 @@ +PyFile:PatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause.py + PyMatchStatement + PsiElement(Py:MATCH_KEYWORD)('match') + PsiWhiteSpace(' ') + PyReferenceExpression: x + PsiElement(Py:IDENTIFIER)('x') + PsiElement(Py:COLON)(':') + PsiWhiteSpace('\n ') + PyCaseClause + PsiElement(Py:CASE_KEYWORD)('case') + PsiWhiteSpace(' ') + PyLiteralPattern + PyBoolLiteralExpression + PsiElement(Py:TRUE_KEYWORD)('True') + PsiElement(Py:COLON)(':') + PsiWhiteSpace('\n ') + PyStatementList + PyPassStatement + PsiElement(Py:PASS_KEYWORD)('pass') + PsiWhiteSpace('\n ') + PyCaseClause + PsiElement(Py:CASE_KEYWORD)('case') + PsiErrorElement:Pattern expected + + PsiErrorElement:':' expected + + PsiWhiteSpace('\n ') + PyStatementList + PsiErrorElement:Indent expected + + PyCaseClause + PsiElement(Py:CASE_KEYWORD)('case') + PsiWhiteSpace(' ') + PyLiteralPattern + PyBoolLiteralExpression + PsiElement(Py:TRUE_KEYWORD)('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/PySmartEnterTest.java b/python/testSrc/com/jetbrains/python/PySmartEnterTest.java index 86d8788233b3..c0fb8d76af41 100644 --- a/python/testSrc/com/jetbrains/python/PySmartEnterTest.java +++ b/python/testSrc/com/jetbrains/python/PySmartEnterTest.java @@ -464,4 +464,19 @@ public class PySmartEnterTest extends PyTestCase { public void testColonAfterCaseClauseWithoutPatternWithGuardCondition() { doTest(); } + + // PY-49785 + public void testColonAfterIntermediateCaseClause() { + doTest(); + } + + // PY-49785 + public void testColonAndIndentAfterIntermediateCaseClause() { + doTest(); + } + + // PY-49785 + public void testColonAfterFinalCaseClauseWithPrecedingIncompleteCaseClause() { + doTest(); + } } diff --git a/python/testSrc/com/jetbrains/python/parsing/PythonParsingTest.java b/python/testSrc/com/jetbrains/python/parsing/PythonParsingTest.java index 48520bdea5d9..0402cd76b468 100644 --- a/python/testSrc/com/jetbrains/python/parsing/PythonParsingTest.java +++ b/python/testSrc/com/jetbrains/python/parsing/PythonParsingTest.java @@ -994,6 +994,10 @@ public class PythonParsingTest extends ParsingTestCase { doTest(LanguageLevel.PYTHON310); } + public void testPatternMatchingRecoveryNoPatternAfterCaseInIntermediateCaseClause() { + doTest(LanguageLevel.PYTHON310); + } + public void testPatternMatchingRecoveryIllegalStatementsInsideMatch() { doTest(LanguageLevel.PYTHON310); }