better recovery for syntax errors in parameter list (PY-3635); fix old bug with tuple parameters parsing

This commit is contained in:
Dmitry Jemerov
2011-05-24 17:13:23 +04:00
parent 79c0c49857
commit 8a97673aeb
5 changed files with 53 additions and 6 deletions
@@ -113,16 +113,17 @@ public class FunctionParsing extends Parsing {
if (myBuilder.getTokenType() == PyTokenTypes.COMMA) {
myBuilder.advanceLexer();
}
else if (myBuilder.getTokenType() == PyTokenTypes.LPAR) {
parseParameterSubList();
continue;
}
else {
myBuilder.error(message("PARSE.expected.comma.lpar.rpar"));
break;
}
}
if (myBuilder.getTokenType() == PyTokenTypes.LPAR) {
parseParameterSubList();
continue;
}
final PsiBuilder.Marker parameter = myBuilder.mark();
boolean isStarParameter = false;
if (myBuilder.getTokenType() == PyTokenTypes.MULT) {
@@ -155,8 +156,13 @@ public class FunctionParsing extends Parsing {
parameter.done(PyElementTypes.NAMED_PARAMETER);
}
else {
myBuilder.error(message("PARSE.expected.formal.param.name"));
parameter.rollbackTo();
PsiBuilder.Marker invalidElements = myBuilder.mark();
while (!atToken(endToken) && !atToken(PyTokenTypes.LINE_BREAK) && !atToken(PyTokenTypes.COMMA) && !atToken(null)) {
nextToken();
}
invalidElements.error(message("PARSE.expected.formal.param.name"));
break;
}
}
@@ -5,6 +5,7 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.jetbrains.python.psi.PyElementType;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -57,7 +58,7 @@ public class Parsing {
LOG.assertTrue(myBuilder.getTokenType() == tokenType);
}
protected boolean atToken(final IElementType tokenType) {
protected boolean atToken(@Nullable final IElementType tokenType) {
return myBuilder.getTokenType() == tokenType;
}
@@ -0,0 +1,2 @@
def select2 (self,filds=None, from=''):
print (sql)
@@ -0,0 +1,34 @@
PyFile:ErrorInParameterList.py
PyFunction('select2')
PsiElement(Py:DEF_KEYWORD)('def')
PsiWhiteSpace(' ')
PsiElement(Py:IDENTIFIER)('select2')
PsiWhiteSpace(' ')
PyParameterList
PsiElement(Py:LPAR)('(')
PyNamedParameter('self')
PsiElement(Py:IDENTIFIER)('self')
PsiElement(Py:COMMA)(',')
PyNamedParameter('filds')
PsiElement(Py:IDENTIFIER)('filds')
PsiElement(Py:EQ)('=')
PyReferenceExpression: None
PsiElement(Py:IDENTIFIER)('None')
PsiElement(Py:COMMA)(',')
PsiWhiteSpace(' ')
PsiErrorElement:formal parameter name expected
PsiElement(Py:FROM_KEYWORD)('from')
PsiElement(Py:EQ)('=')
PsiElement(Py:STRING_LITERAL)('''')
PsiElement(Py:RPAR)(')')
PsiElement(Py:COLON)(':')
PsiWhiteSpace('\n ')
PyStatementList
PyPrintStatement
PsiElement(Py:PRINT_KEYWORD)('print')
PsiWhiteSpace(' ')
PyParenthesizedExpression
PsiElement(Py:LPAR)('(')
PyReferenceExpression: sql
PsiElement(Py:IDENTIFIER)('sql')
PsiElement(Py:RPAR)(')')
@@ -267,6 +267,10 @@ public class PythonParsingTest extends ParsingTestCase {
doTest();
}
public void testErrorInParameterList() { // PY-3635
doTest();
}
public void doTest() {
doTest(LanguageLevel.PYTHON25);
}