tweak Python parser to handle incomplete code better (PY-4053)

This commit is contained in:
Dmitry Jemerov
2011-07-01 14:20:51 +02:00
parent 4bec759ac9
commit 17178af318
6 changed files with 58 additions and 6 deletions

View File

@@ -460,6 +460,7 @@ public class ExpressionParsing extends Parsing {
}
if (!parseSingleExpression(false)) {
myBuilder.error(message("PARSE.expected.expression"));
break;
}
}
}

View File

@@ -36,13 +36,13 @@ public class Parsing {
return getParsingContext().getFunctionParser();
}
protected void checkMatches(final IElementType token, final String message) {
protected boolean checkMatches(final IElementType token, final String message) {
if (myBuilder.getTokenType() == token) {
myBuilder.advanceLexer();
return true;
}
else {
myBuilder.error(message);
}
myBuilder.error(message);
return false;
}
protected boolean checkMatches(final TokenSet tokenSet, final String message) {

View File

@@ -532,8 +532,9 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
final PsiBuilder.Marker ifPart = myBuilder.mark();
myBuilder.advanceLexer();
getExpressionParser().parseExpression();
checkMatches(PyTokenTypes.COLON, "colon expected");
parseSuite();
if (checkMatches(PyTokenTypes.COLON, "colon expected")) {
parseSuite();
}
ifPart.done(PyElementTypes.IF_PART_IF);
PsiBuilder.Marker elifPart = myBuilder.mark();
while (myBuilder.getTokenType() == PyTokenTypes.ELIF_KEYWORD) {

View File

@@ -0,0 +1,5 @@
def get_key():
if isinstance(self.instance,
def clean():
pass

View File

@@ -0,0 +1,41 @@
PyFile:MissingParenInCall.py
PyFunction('get_key')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('get_key')
PyParameterList
PsiElement(Py:LPAR)('(')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyIfStatement
PyIfPartIf
PsiElement(Py:IF_KEYWORD)('if')
PsiWhiteSpace(' ')
PyCallExpression: isinstance
PyReferenceExpression: isinstance
PsiElement(Py:IDENTIFIER)('isinstance')
PyArgumentList
PsiElement(Py:LPAR)('(')
PyReferenceExpression: instance
PyReferenceExpression: self
PsiElement(Py:IDENTIFIER)('self')
PsiElement(Py:DOT)('.')
PsiElement(Py:IDENTIFIER)('instance')
PsiElement(Py:COMMA)(',')
PsiErrorElement:expression expected
<empty list>
PsiWhiteSpace('\n\n')
PyFunction('clean')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('clean')
PyParameterList
PsiElement(Py:LPAR)('(')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPassStatement
PsiElement(Py:PASS_KEYWORD)('pass')

View File

@@ -279,6 +279,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
public void testMissingParenInCall() { // PY-4053
doTest();
}
public void doTest() {
doTest(LanguageLevel.PYTHON25);
}