blob: 5965f370195e7e72978a3d30beed0e2c6f43b207 [file]
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python;
import com.jetbrains.python.fixtures.PyLexerTestCase;
import com.jetbrains.python.lexer.PythonIndentingLexer;
/**
* @author yole
*/
public class PythonLexerTest extends PyLexerTestCase {
public void testSimpleExpression() {
doTest("a=1", "Py:IDENTIFIER", "Py:EQ", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
public void testMergeSpaces() {
doTest("a = 1", "Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
public void testLineBreakInBraces() {
doTest("[a,\n b]", "Py:LBRACKET", "Py:IDENTIFIER", "Py:COMMA", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:RBRACKET", "Py:STATEMENT_BREAK");
}
public void testLineBreakInBraces2() {
doTest("x=[a,\n b]", "Py:IDENTIFIER", "Py:EQ", "Py:LBRACKET", "Py:IDENTIFIER", "Py:COMMA", "Py:LINE_BREAK",
"Py:IDENTIFIER", "Py:RBRACKET", "Py:STATEMENT_BREAK");
}
public void testLineBreakInBracesAfterComment() {
doTest("x=[a, #c\n b]",
"Py:IDENTIFIER", "Py:EQ", "Py:LBRACKET", "Py:IDENTIFIER", "Py:COMMA", "Py:SPACE", "Py:END_OF_LINE_COMMENT",
"Py:LINE_BREAK", "Py:IDENTIFIER", "Py:RBRACKET", "Py:STATEMENT_BREAK");
}
public void testBraceAfterIndent() {
doTest("x=\n [a,\n b]",
"Py:IDENTIFIER", "Py:EQ", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:LBRACKET", "Py:IDENTIFIER", "Py:COMMA", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:RBRACKET", "Py:STATEMENT_BREAK");
}
public void testBackslash() {
doTest("a=\\\nb",
"Py:IDENTIFIER", "Py:EQ", "Py:SPACE", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testBackslashAfterSpace() {
doTest("a = \\\n b",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testMultipleBackslashes() {
doTest("[\\\n\\\n]",
"Py:LBRACKET", "Py:SPACE", "Py:LINE_BREAK", "Py:SPACE", "Py:LINE_BREAK", "Py:RBRACKET", "Py:STATEMENT_BREAK");
}
public void testIndent() {
doTest("if a:\n b",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testMultiLineIndent() {
doTest("if a:\n b\n c",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testDedent() {
doTest("if a:\n b\nc",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
"Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testMultiDedent() {
doTest("if a:\n b\n c\nd",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:INDENT",
"Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:DEDENT",
"Py:DEDENT", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testEmptyLine() {
doTest("if a:\n b\n \n c",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:INDENT",
"Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testEndOfLineSpace() {
doTest("if a:\n b\n c \n \n d",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK",
"Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testComment() {
doTest("if a:\n b\n #comment\nc",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:END_OF_LINE_COMMENT", "Py:DEDENT", "Py:LINE_BREAK",
"Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testIndentedComment() {
doTest("#a\n #b\n#c",
"Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK", "Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK", "Py:END_OF_LINE_COMMENT", "Py:STATEMENT_BREAK");
}
public void testIndentedCommentAndCode() {
doTest("if a:\n #b\n c",
"Py:IF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testWithNotKeyword() {
doTest("with=as", "Py:IDENTIFIER", "Py:EQ", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testBytesLiteral() {
doTest("a=b'ABC'", "Py:IDENTIFIER", "Py:EQ", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testOctalLiteral() {
doTest("0o123", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
public void testBinaryLiteral() {
doTest("0b0101", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
private static final String THREE_QUOTES = "\"\"\"";
public void testLongString() {
doTest(THREE_QUOTES + THREE_QUOTES + "\nb=" + THREE_QUOTES + THREE_QUOTES,
"Py:DOCSTRING", "Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:EQ", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testLongStringEscaped() {
doTest("''' \\'''foo\\''' ''';", "Py:DOCSTRING", "Py:SEMICOLON", "Py:STATEMENT_BREAK");
}
public void testLongStringWithLineBreak() {
doTest(THREE_QUOTES + "\\\na\n\n" + THREE_QUOTES + ";", "Py:DOCSTRING", "Py:SEMICOLON", "Py:STATEMENT_BREAK");
}
public void _testWithKeyword() {
// processing of 'from __future__ import' is now done on parser level, so a pure lexer test won't handle
// this correctly
doTest("from __future__ import with_statement\nwith x as y", "Py:FROM_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:SPACE",
"Py:IMPORT_KEYWORD", "Py:SPACE", "Py:IDENTIFIER",
"Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:WITH_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:SPACE", "Py:AS_KEYWORD", "Py:SPACE", "Py:IDENTIFIER");
}
public void testBackslashBeforeEmptyLine() {
doTest("x=\"a\" + \\\n \"b\" \\\n\nprint x", "Py:IDENTIFIER", "Py:EQ", "Py:SINGLE_QUOTED_STRING", "Py:SPACE", "Py:PLUS", "Py:SPACE", "Py:LINE_BREAK",
"Py:SINGLE_QUOTED_STRING", "Py:SPACE", "Py:LINE_BREAK", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:IDENTIFIER" , "Py:SPACE", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
public void testBackslashFuction() {
doTest("def test():\n" +
" print \\\n" +
"\n" +
"def test2():\n" +
" pass\n" +
"\n" +
"print 'hello'", "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK",
"Py:LINE_BREAK", "Py:INDENT", "Py:IDENTIFIER", "Py:SPACE", "Py:LINE_BREAK", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", "Py:IDENTIFIER", "Py:SPACE",
"Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testIncompleteTripleQuotedString() { // PY-1768
doTest("tmp = '''abc\nd", "Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testEscapedClosingTripleApos() { // PY-1777
doTest("a=''' foo '\\''' bar '''", "Py:IDENTIFIER", "Py:EQ", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testEscapedClosingTripleQuote() { // PY-1777
doTest("a="+THREE_QUOTES + " foo \"\\" + THREE_QUOTES + " bar " + THREE_QUOTES, "Py:IDENTIFIER", "Py:EQ", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testEOFDocstring() { // PY-4169
doTest(THREE_QUOTES + " foo \"\\" + THREE_QUOTES + " bar " + THREE_QUOTES,"Py:DOCSTRING", "Py:STATEMENT_BREAK");
}
public void testOddNumberOfQuotes() { // PY-2802
doTest("'''foo''''", "Py:TRIPLE_QUOTED_STRING", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testDedentBeforeComment() { // PY-2209 & friends
doTest("class UserProfile:\n" +
" pass\n" +
"\n" +
"#noinspection PyUnusedLocal\n" +
"def foo(sender):\n" +
" pass",
"Py:CLASS_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK",
"Py:DEDENT", "Py:LINE_BREAK", "Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK",
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK");
}
public void testDedentAfterComment() { // PY-2137
doTest("def foo():\n" +
" pass\n" +
" #comment\n",
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:END_OF_LINE_COMMENT", "Py:DEDENT", "Py:LINE_BREAK", "Py:STATEMENT_BREAK");
}
public void testIndentAtStartOfFile() { // PY-4941
doTest(" a", "Py:SPACE", "Py:INDENT", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
// PY-3067
public void testErrorOpenParInExpr() {
doTest("def f():\n" +
" (\n" +
"\n" +
"def g():\n" +
" pass\n",
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK");
}
// PY-3067
public void testErrorOpenParInExprBeforeComment() {
doTest("def f():\n" +
" (\n" +
"#comment\n" +
"def g():\n" +
" pass\n",
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
"Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK");
}
// PY-7255
public void testDocstringInDict() {
doTest("d = {\n" +
" 'foo':\n" +
" 'bar'\n" +
" 'baz'\n" +
"}",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:LBRACE", "Py:LINE_BREAK",
"Py:SINGLE_QUOTED_STRING", "Py:COLON", "Py:LINE_BREAK", "Py:SINGLE_QUOTED_STRING", "Py:LINE_BREAK",
"Py:SINGLE_QUOTED_STRING", "Py:LINE_BREAK", "Py:RBRACE", "Py:STATEMENT_BREAK");
}
// PY-3067
public void testErrorOpenParInMethod() {
doTest("class C:\n" +
" def f(self):\n" +
" (\n" +
"\n" +
" def g(self):\n" +
" pass\n",
"Py:CLASS_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:LPAR", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK", "Py:DEDENT", "Py:LINE_BREAK", // Error recovery
"Py:DEF_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:COLON", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:INDENT", "Py:PASS_KEYWORD", "Py:STATEMENT_BREAK", "Py:DEDENT", "Py:DEDENT", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK");
}
// PY-6722
public void testBackslashAndEmptyLineInsideSquareBrackets() {
doTest("xs = [ \\\n" +
"\n" +
"]\n" +
"print(xs)\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:LBRACKET", "Py:SPACE", "Py:LINE_BREAK",
"Py:LINE_BREAK",
"Py:RBRACKET", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:IDENTIFIER", "Py:LPAR", "Py:IDENTIFIER", "Py:RPAR", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK");
}
// PY-6722
public void testSingleBackslashLineInsideSquareBrackets() {
doTest("xs = [\n" +
"\\\n" +
"]\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:LBRACKET", "Py:LINE_BREAK",
"Py:SPACE", "Py:LINE_BREAK",
"Py:RBRACKET", "Py:STATEMENT_BREAK", "Py:LINE_BREAK",
"Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInHexInteger() {
doTest("0xCAFE_F00D", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInOctInteger() {
doTest("0o1_23","Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
doTest("01_23", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInBinInteger() {
doTest("0b_0011_1111_0100_1110", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInDecimalInteger() {
doTest("10_000_000", "Py:INTEGER_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInPointFloat() {
doTest("10_00.00_23", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInExponentFloat() {
doTest("10_00.00_23e1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23E1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.e1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.E1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23e+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23E+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.e+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.E+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23e-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23E-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.e-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.E-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23e1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23E1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00e1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00E1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23e+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23E+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00e+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00E+1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23e-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_0000_23E-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00e-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00E-1_2", "Py:FLOAT_LITERAL", "Py:STATEMENT_BREAK");
}
// PY-18973
public void testUnderscoresInImagNumber() {
doTest("10_00.00_23j", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23J", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23e1_2j", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_00.00_23e1_2J", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_000_000j", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
doTest("10_000_000J", "Py:IMAGINARY_LITERAL", "Py:STATEMENT_BREAK");
}
public void testFStringMatchingQuoteRecoveryInsideContentOfNestedStringLiteral() {
doTest("s = f'{ur\"foo'bar\"}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:SINGLE_QUOTED_STRING", "Py:FSTRING_END",
"Py:IDENTIFIER", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testFStringMatchingQuoteRecoveryQuoteOfNestedStringLiteralWithPrefix() {
doTest("s = f'{ur'foo'}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:IDENTIFIER", "Py:FSTRING_END",
"Py:IDENTIFIER", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testFStringMatchingQuoteRecoveryQuoteOfNestedStringLiteralWithoutPrefix() {
doTest("s = f'{'foo'}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:FSTRING_END",
"Py:IDENTIFIER", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testNoStatementBreakInsideFragmentOfMultilineFString() {
doTest("s = f'''{1 + \n" +
"2}'''",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:INTEGER_LITERAL", "Py:SPACE", "Py:PLUS", "Py:LINE_BREAK",
"Py:INTEGER_LITERAL", "Py:FSTRING_FRAGMENT_END", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
}
public void testStatementBreakInsideFragmentOfSingleLineFString() {
doTest("s = f'{1 +\n" +
" 2}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:INTEGER_LITERAL", "Py:SPACE", "Py:PLUS", "Py:STATEMENT_BREAK",
"Py:LINE_BREAK", "Py:INDENT", "Py:INTEGER_LITERAL", "Py:RBRACE", "Py:SINGLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
public void testFStringUnmatchedQuotesAsTextParts() {
doTest("s = f'foo\"bar'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
}
public void testFStringUnmatchedLineBreaksAsTextParts() {
doTest("s = f'''foo\n" +
"bar'''",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
}
public void testFStringNamedUnicodeEscapes() {
doTest("s = f'\\N{LATIN SMALL LETTER A}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
doTest("s = f'\\N{LATIN SMALL LETTER A'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
doTest("s = f'\\N{'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
}
public void testFStringBackslashEscapedBraces() {
doTest("s = f'foo\\{x}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT",
"Py:FSTRING_FRAGMENT_START", "Py:IDENTIFIER", "Py:FSTRING_FRAGMENT_END",
"Py:FSTRING_END", "Py:STATEMENT_BREAK");
doTest("s = f'{x:foo\\{y}bar\\}'",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE",
"Py:FSTRING_START", "Py:FSTRING_FRAGMENT_START", "Py:IDENTIFIER",
"Py:FSTRING_FRAGMENT_FORMAT_START", "Py:FSTRING_TEXT", "Py:FSTRING_TEXT",
"Py:FSTRING_FRAGMENT_START", "Py:IDENTIFIER", "Py:FSTRING_FRAGMENT_END",
"Py:FSTRING_TEXT", "Py:FSTRING_TEXT",
"Py:FSTRING_FRAGMENT_END", "Py:FSTRING_END", "Py:STATEMENT_BREAK");
}
// PY-21697
public void testTripleSingleQuotedStringWithEscapedSlashAfterOneQuote() {
doTest("s = '''\n" +
"'\\\\'''\n" +
"'''\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:TRIPLE_QUOTED_STRING",
"Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
// PY-21697
public void testTripleSingleQuotedStringWithEscapedSlashAfterTwoQuotes() {
doTest("s = '''\n" +
"''\\\\'''\n" +
"'''\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:TRIPLE_QUOTED_STRING",
"Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
// PY-21697
public void testTripleDoubleQuotedStringWithEscapedSlashAfterOneQuote() {
doTest("s = \"\"\"\n" +
"\"\\\\\"\"\"\n" +
"\"\"\"\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:TRIPLE_QUOTED_STRING",
"Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
// PY-21697
public void testTripleDoubleQuotedStringWithEscapedSlashAfterTwoQuotes() {
doTest("s = \"\"\"\n" +
"\"\"\\\\\"\"\"\n" +
"\"\"\"\n",
"Py:IDENTIFIER", "Py:SPACE", "Py:EQ", "Py:SPACE", "Py:TRIPLE_QUOTED_STRING",
"Py:STATEMENT_BREAK", "Py:LINE_BREAK", "Py:TRIPLE_QUOTED_STRING", "Py:STATEMENT_BREAK");
}
// PY-40757
public void testVerticalTab() {
doTest("\u000Bimport math",
"BAD_CHARACTER", "Py:IMPORT_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
// PY-40757
public void testVerticalTabAfterComment() {
doTest("# comment\n" +
"\u000Bimport math",
"Py:END_OF_LINE_COMMENT", "Py:LINE_BREAK",
"BAD_CHARACTER", "Py:IMPORT_KEYWORD", "Py:SPACE", "Py:IDENTIFIER", "Py:STATEMENT_BREAK");
}
private static void doTest(String text, String... expectedTokens) {
PyLexerTestCase.doLexerTest(text, new PythonIndentingLexer(), expectedTokens);
}
}