PY-31442 Handle hash signs in literal parts of f-strings

Made the corresponding states of the lexer exclusive so that the pattern
for line comments doesn't match literal fragments starting with a hash sign
as the longest (together with closing braces and quotes). It also means that
we need to replicate the BAD_CHARACTER rule in these states as a fallback
pattern for unmatched input.
This commit is contained in:
Mikhail Golubev
2018-10-01 12:46:45 +03:00
parent 1e527a9ba4
commit 2e8b9f7a9f
12 changed files with 492 additions and 415 deletions
@@ -0,0 +1 @@
s = f'#foo'
@@ -0,0 +1,12 @@
PyFile:FStringContainsHashInLiteralPart.py
PyAssignmentStatement
PyTargetExpression: s
PsiElement(Py:IDENTIFIER)('s')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyStringLiteralExpression: #foo
PyFormattedStringNode
PsiElement(Py:FSTRING_START)('f'')
PsiElement(Py:FSTRING_TEXT)('#foo')
PsiElement(Py:FSTRING_END)(''')
@@ -0,0 +1 @@
s = f'{42:#b}'
@@ -0,0 +1,19 @@
PyFile:FStringContainsHashSignInFormatPart.py
PyAssignmentStatement
PyTargetExpression: s
PsiElement(Py:IDENTIFIER)('s')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyStringLiteralExpression: {42:#b}
PyFormattedStringNode
PsiElement(Py:FSTRING_START)('f'')
PyFStringFragment
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
PyFStringFragmentFormatPart
PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':')
PsiElement(Py:FSTRING_TEXT)('#b')
PsiElement(Py:FSTRING_FRAGMENT_END)('}')
PsiElement(Py:FSTRING_END)(''')
@@ -0,0 +1 @@
s = f'{42:\
@@ -0,0 +1,21 @@
PyFile:UnterminatedFStringWithTrailingBackslashInFormatPart.py
PyAssignmentStatement
PyTargetExpression: s
PsiElement(Py:IDENTIFIER)('s')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyStringLiteralExpression: {42:
PyFormattedStringNode
PsiElement(Py:FSTRING_START)('f'')
PyFStringFragment
PsiElement(Py:FSTRING_FRAGMENT_START)('{')
PyNumericLiteralExpression
PsiElement(Py:INTEGER_LITERAL)('42')
PyFStringFragmentFormatPart
PsiElement(Py:FSTRING_FRAGMENT_FORMAT_START)(':')
PsiErrorElement:} expected
<empty list>
PsiElement(BAD_CHARACTER)('\')
PsiErrorElement:Statement expected, found BAD_CHARACTER
<empty list>
@@ -0,0 +1,15 @@
PyFile:UnterminatedFStringWithTrailingBackslashInLiteralPart.py
PyAssignmentStatement
PyTargetExpression: s
PsiElement(Py:IDENTIFIER)('s')
PsiWhiteSpace(' ')
PsiElement(Py:EQ)('=')
PsiWhiteSpace(' ')
PyStringLiteralExpression:
PyFormattedStringNode
PsiElement(Py:FSTRING_START)('f'')
PsiErrorElement:unexpected f-string token
<empty list>
PsiElement(BAD_CHARACTER)('\')
PsiErrorElement:Statement expected, found BAD_CHARACTER
<empty list>