mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-59594 PEP 701: Stop recovery of incomplete f-string fragments at statement-only keywords
(cherry picked from commit 7aa912a43d63f6c9867d772e120c5b45adb10be3) IJ-MR-115763 GitOrigin-RevId: ca6909a8e7a59e06eae69b631160e4d48541ce58
This commit is contained in:
committed by
intellij-monorepo-bot
parent
37d25ee815
commit
b3351b941e
@@ -259,6 +259,7 @@ public class PythonIndentingProcessor extends MergingLexerAdapter {
|
||||
}
|
||||
|
||||
private void adjustBraceLevel() {
|
||||
boolean insideFStringFragment = !myFStringStack.isEmpty() && !myFStringStack.peek().fragments.isEmpty();
|
||||
final IElementType tokenType = getTokenType();
|
||||
if (PyTokenTypes.OPEN_BRACES.contains(tokenType)) {
|
||||
myBraceLevel++;
|
||||
@@ -266,8 +267,11 @@ public class PythonIndentingProcessor extends MergingLexerAdapter {
|
||||
else if (PyTokenTypes.CLOSE_BRACES.contains(tokenType)) {
|
||||
myBraceLevel--;
|
||||
}
|
||||
else if (myBraceLevel != 0 && RECOVERY_TOKENS.contains(tokenType)) {
|
||||
else if ((myBraceLevel != 0 || insideFStringFragment) && RECOVERY_TOKENS.contains(tokenType)) {
|
||||
myBraceLevel = 0;
|
||||
if (insideFStringFragment) {
|
||||
myFStringStack.clear();
|
||||
}
|
||||
final int pos = getTokenStart();
|
||||
pushToken(PyTokenTypes.STATEMENT_BREAK, pos, pos);
|
||||
final int indents = myIndentStack.size();
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
s = f'{foo:{bar'
|
||||
print(42)
|
||||
raise Exception
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
PyFile:FormatPartFStringFragmentRecoveryStoppedAtStatementOnlyKeyword.py
|
||||
PyAssignmentStatement
|
||||
PyTargetExpression: s
|
||||
PsiElement(Py:IDENTIFIER)('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStringLiteralExpression: {foo:{bar'
|
||||
print(42)
|
||||
|
||||
PyFormattedStringElement
|
||||
PsiElement(Py:FSTRING_START)('f'')
|
||||
PyFStringFragment
|
||||
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
|
||||
PyReferenceExpression: foo
|
||||
PsiElement(Py:IDENTIFIER)('foo')
|
||||
PyFStringFragmentFormatPart
|
||||
PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':')
|
||||
PyFStringFragment
|
||||
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
|
||||
PyReferenceExpression: bar
|
||||
PsiElement(Py:IDENTIFIER)('bar')
|
||||
PsiErrorElement:Unexpected expression part
|
||||
PsiElement(Py:SINGLE_QUOTED_STRING)(''')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(Py:IDENTIFIER)('print')
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:INTEGER_LITERAL)('42')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiErrorElement:Type conversion, ':' or '}' expected
|
||||
<empty list>
|
||||
PsiErrorElement:' expected
|
||||
<empty list>
|
||||
PyRaiseStatement
|
||||
PsiElement(Py:RAISE_KEYWORD)('raise')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: Exception
|
||||
PsiElement(Py:IDENTIFIER)('Exception')
|
||||
@@ -0,0 +1,3 @@
|
||||
s = f'{foo'
|
||||
print(42)
|
||||
raise Exception
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
PyFile:IncompleteFStringFragmentRecoveryStoppedAtStatementOnlyKeyword.py
|
||||
PyAssignmentStatement
|
||||
PyTargetExpression: s
|
||||
PsiElement(Py:IDENTIFIER)('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStringLiteralExpression: {foo'
|
||||
print(42)
|
||||
|
||||
PyFormattedStringElement
|
||||
PsiElement(Py:FSTRING_START)('f'')
|
||||
PyFStringFragment
|
||||
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
|
||||
PyReferenceExpression: foo
|
||||
PsiElement(Py:IDENTIFIER)('foo')
|
||||
PsiErrorElement:Unexpected expression part
|
||||
PsiElement(Py:SINGLE_QUOTED_STRING)(''')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(Py:IDENTIFIER)('print')
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:INTEGER_LITERAL)('42')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiErrorElement:Type conversion, ':' or '}' expected
|
||||
<empty list>
|
||||
PsiErrorElement:' expected
|
||||
<empty list>
|
||||
PyRaiseStatement
|
||||
PsiElement(Py:RAISE_KEYWORD)('raise')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: Exception
|
||||
PsiElement(Py:IDENTIFIER)('Exception')
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
s = f'{f"{foo"'
|
||||
print(42)
|
||||
raise Exception
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
PyFile:NestedIncompleteFStringFragmentRecoveryStoppedAtStatementOnlyKeyword.py
|
||||
PyAssignmentStatement
|
||||
PyTargetExpression: s
|
||||
PsiElement(Py:IDENTIFIER)('s')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStringLiteralExpression: {f"{foo"'
|
||||
print(42)
|
||||
|
||||
PyFormattedStringElement
|
||||
PsiElement(Py:FSTRING_START)('f'')
|
||||
PyFStringFragment
|
||||
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
|
||||
PyStringLiteralExpression: {foo"'
|
||||
print(42)
|
||||
|
||||
PyFormattedStringElement
|
||||
PsiElement(Py:FSTRING_START)('f"')
|
||||
PyFStringFragment
|
||||
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
|
||||
PyReferenceExpression: foo
|
||||
PsiElement(Py:IDENTIFIER)('foo')
|
||||
PsiErrorElement:Unexpected expression part
|
||||
PsiElement(Py:SINGLE_QUOTED_STRING)('"'')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(Py:IDENTIFIER)('print')
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:INTEGER_LITERAL)('42')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiErrorElement:Type conversion, ':' or '}' expected
|
||||
<empty list>
|
||||
PsiErrorElement:" expected
|
||||
<empty list>
|
||||
PsiErrorElement:' expected
|
||||
<empty list>
|
||||
PyRaiseStatement
|
||||
PsiElement(Py:RAISE_KEYWORD)('raise')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: Exception
|
||||
PsiElement(Py:IDENTIFIER)('Exception')
|
||||
@@ -861,6 +861,18 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
public void testIncompleteFStringFragmentRecoveryStoppedAtStatementOnlyKeyword() {
|
||||
doTest(LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
public void testNestedIncompleteFStringFragmentRecoveryStoppedAtStatementOnlyKeyword() {
|
||||
doTest(LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
public void testFormatPartFStringFragmentRecoveryStoppedAtStatementOnlyKeyword() {
|
||||
doTest(LanguageLevel.PYTHON36);
|
||||
}
|
||||
|
||||
// PY-19036
|
||||
public void testAwaitInNonAsyncNestedFunction() {
|
||||
doTest(LanguageLevel.PYTHON35);
|
||||
|
||||
Reference in New Issue
Block a user