mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
don't parse compound statements after semicolon at top level of file (PY-7660)
This commit is contained in:
@@ -7,6 +7,7 @@ public class ParsingScope {
|
||||
private boolean myFunction = false;
|
||||
private boolean myClass = false;
|
||||
private boolean mySuite = false;
|
||||
private boolean myAfterSemicolon = false;
|
||||
|
||||
public ParsingScope withFunction(boolean flag) {
|
||||
final ParsingScope result = copy();
|
||||
@@ -38,6 +39,14 @@ public class ParsingScope {
|
||||
return mySuite;
|
||||
}
|
||||
|
||||
public boolean isAfterSemicolon() {
|
||||
return myAfterSemicolon;
|
||||
}
|
||||
|
||||
public void setAfterSemicolon(boolean value) {
|
||||
myAfterSemicolon = value;
|
||||
}
|
||||
|
||||
protected ParsingScope createInstance() {
|
||||
return new ParsingScope();
|
||||
}
|
||||
|
||||
@@ -30,10 +30,18 @@ public class PyParser implements PsiParser {
|
||||
long start = System.currentTimeMillis();
|
||||
final PsiBuilder.Marker rootMarker = builder.mark();
|
||||
ParsingContext context = createParsingContext(builder, myLanguageLevel, myFutureFlag);
|
||||
StatementParsing stmt_parser = context.getStatementParser();
|
||||
builder.setTokenTypeRemapper(stmt_parser); // must be done before touching the caching lexer with eof() call.
|
||||
StatementParsing statementParser = context.getStatementParser();
|
||||
builder.setTokenTypeRemapper(statementParser); // must be done before touching the caching lexer with eof() call.
|
||||
boolean lastAfterSemicolon = false;
|
||||
while (!builder.eof()) {
|
||||
stmt_parser.parseStatement(context.emptyParsingScope());
|
||||
ParsingScope scope = context.emptyParsingScope();
|
||||
if (lastAfterSemicolon) {
|
||||
statementParser.parseSimpleStatement(scope);
|
||||
}
|
||||
else {
|
||||
statementParser.parseStatement(scope);
|
||||
}
|
||||
lastAfterSemicolon = scope.isAfterSemicolon();
|
||||
}
|
||||
rootMarker.done(root);
|
||||
ASTNode ast = builder.getTreeBuilt();
|
||||
|
||||
@@ -254,8 +254,10 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
|
||||
else if (builder.getTokenType() == PyTokenTypes.SEMICOLON) {
|
||||
if (!scope.isSuite()) {
|
||||
builder.advanceLexer();
|
||||
scope.setAfterSemicolon(true);
|
||||
if (builder.getTokenType() == PyTokenTypes.STATEMENT_BREAK) {
|
||||
builder.advanceLexer();
|
||||
scope.setAfterSemicolon(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
a = 0; if a:
|
||||
pass
|
||||
@@ -0,0 +1,28 @@
|
||||
PyFile:CompoundStatementAfterSemicolon.py
|
||||
PyAssignmentStatement
|
||||
PyTargetExpression: a
|
||||
PsiElement(Py:IDENTIFIER)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyNumericLiteralExpression
|
||||
PsiElement(Py:INTEGER_LITERAL)('0')
|
||||
PsiElement(Py:SEMICOLON)(';')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IF_KEYWORD)('if')
|
||||
PsiErrorElement:Statement expected, found Py:IF_KEYWORD
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PyExpressionStatement
|
||||
PyReferenceExpression: a
|
||||
PsiElement(Py:IDENTIFIER)('a')
|
||||
PsiErrorElement:End of statement expected
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiErrorElement:Statement expected, found Py:COLON
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiErrorElement:Unexpected indent
|
||||
<empty list>
|
||||
PyPassStatement
|
||||
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||
@@ -352,6 +352,9 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON25);
|
||||
}
|
||||
|
||||
public void testCompoundStatementAfterSemicolon() { // PY-7660
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void doTest(LanguageLevel languageLevel) {
|
||||
LanguageLevel prev = myLanguageLevel;
|
||||
|
||||
Reference in New Issue
Block a user