mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-15653 Do not consume open parenthesis after missing identifier in class and function headers
This commit is contained in:
@@ -45,7 +45,7 @@ public class FunctionParsing extends Parsing {
|
||||
|
||||
protected void parseFunctionInnards(PsiBuilder.Marker functionMarker) {
|
||||
myBuilder.advanceLexer();
|
||||
parseIdentifierOrSkip();
|
||||
parseIdentifierOrSkip(PyTokenTypes.LPAR);
|
||||
parseParameterList();
|
||||
parseReturnTypeAnnotation();
|
||||
checkMatches(PyTokenTypes.COLON, message("PARSE.expected.colon"));
|
||||
@@ -213,7 +213,7 @@ public class FunctionParsing extends Parsing {
|
||||
return false;
|
||||
}
|
||||
PsiBuilder.Marker invalidElements = myBuilder.mark();
|
||||
while (!atToken(endToken) && !atToken(PyTokenTypes.LINE_BREAK) && !atToken(PyTokenTypes.COMMA) && !atToken(null)) {
|
||||
while (!atToken(endToken) && !atAnyOfTokens(PyTokenTypes.LINE_BREAK, PyTokenTypes.COMMA, null)) {
|
||||
nextToken();
|
||||
}
|
||||
invalidElements.error(message("PARSE.expected.formal.param.name"));
|
||||
|
||||
@@ -63,14 +63,14 @@ public class Parsing {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean parseIdentifierOrSkip() {
|
||||
protected boolean parseIdentifierOrSkip(@NotNull IElementType... validSuccessiveTokens) {
|
||||
if (myBuilder.getTokenType() == PyTokenTypes.IDENTIFIER) {
|
||||
myBuilder.advanceLexer();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
final PsiBuilder.Marker nameExpected = myBuilder.mark();
|
||||
if (myBuilder.getTokenType() != PyTokenTypes.STATEMENT_BREAK) {
|
||||
if (myBuilder.getTokenType() != PyTokenTypes.STATEMENT_BREAK && !atAnyOfTokens(validSuccessiveTokens)) {
|
||||
myBuilder.advanceLexer();
|
||||
}
|
||||
nameExpected.error(PyBundle.message("PARSE.expected.identifier"));
|
||||
|
||||
@@ -792,7 +792,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
|
||||
public void parseClassDeclaration(PsiBuilder.Marker classMarker, ParsingScope scope) {
|
||||
assertCurrentToken(PyTokenTypes.CLASS_KEYWORD);
|
||||
myBuilder.advanceLexer();
|
||||
parseIdentifierOrSkip();
|
||||
parseIdentifierOrSkip(PyTokenTypes.LPAR, PyTokenTypes.COLON);
|
||||
if (myBuilder.getTokenType() == PyTokenTypes.LPAR) {
|
||||
getExpressionParser().parseArgumentList();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
class :
|
||||
pass
|
||||
@@ -0,0 +1,13 @@
|
||||
PyFile:MissingClassNameAndThenColon.py
|
||||
PyClass: null
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
PyPassStatement
|
||||
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||
@@ -0,0 +1,2 @@
|
||||
class ():
|
||||
pass
|
||||
@@ -0,0 +1,14 @@
|
||||
PyFile:MissingClassNameAndThenListOfBaseClasses.py
|
||||
PyClass: null
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PyArgumentList
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
PyPassStatement
|
||||
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||
@@ -0,0 +1,2 @@
|
||||
def ():
|
||||
pass
|
||||
@@ -0,0 +1,14 @@
|
||||
PyFile:MissingFunctionNameAndThenParametersList.py
|
||||
PyFunction('null')
|
||||
PsiElement(Py:DEF_KEYWORD)('def')
|
||||
PsiErrorElement:Identifier expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PyParameterList
|
||||
PsiElement(Py:LPAR)('(')
|
||||
PsiElement(Py:RPAR)(')')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace('\n ')
|
||||
PyStatementList
|
||||
PyPassStatement
|
||||
PsiElement(Py:PASS_KEYWORD)('pass')
|
||||
@@ -473,6 +473,21 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON35);
|
||||
}
|
||||
|
||||
// PY-15653
|
||||
public void testMissingFunctionNameAndThenParametersList() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-15653
|
||||
public void testMissingClassNameAndThenListOfBaseClasses() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-15653
|
||||
public void testMissingClassNameAndThenColon() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void doTest(LanguageLevel languageLevel) {
|
||||
LanguageLevel prev = myLanguageLevel;
|
||||
myLanguageLevel = languageLevel;
|
||||
|
||||
Reference in New Issue
Block a user