KT-193: Guard primary constructor modifier list with a lookahead for LPAR
This commit is contained in:
@@ -419,13 +419,27 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
|
expect(IDENTIFIER, "Class name expected", CLASS_NAME_RECOVERY_SET);
|
||||||
boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
boolean typeParametersDeclared = parseTypeParameterList(TYPE_PARAMETER_GT_RECOVERY_SET);
|
||||||
|
|
||||||
if (parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false)) {
|
PsiBuilder.Marker beforeConstructorModifiers = mark();
|
||||||
|
boolean hasConstructorModifiers = parseModifierList(PRIMARY_CONSTRUCTOR_MODIFIER_LIST, false);
|
||||||
|
|
||||||
|
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
|
||||||
|
if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON) ) {
|
||||||
|
beforeConstructorModifiers.rollbackTo();
|
||||||
|
return CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are still inside a class declaration
|
||||||
|
beforeConstructorModifiers.drop();
|
||||||
|
|
||||||
|
if (at(LPAR)) {
|
||||||
parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
|
parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
|
||||||
}
|
}
|
||||||
else {
|
else if (hasConstructorModifiers) {
|
||||||
if (at(LPAR)) {
|
// A comprehensive error message for cases like:
|
||||||
parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
|
// class A private : Foo
|
||||||
}
|
// or
|
||||||
|
// class A private {
|
||||||
|
error("Expecting primary constructor parameter list");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (at(COLON)) {
|
if (at(COLON)) {
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
open class A
|
||||||
|
|
||||||
|
open class AB private {
|
||||||
|
fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class A1 {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
open class B<T : A> private () {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
JetFile: PrimaryConstructorModifiers_ERR.jet
|
||||||
|
NAMESPACE
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(open)('open')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('A')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
<empty list>
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(open)('open')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('AB')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
<empty list>
|
||||||
|
PRIMARY_CONSTRUCTOR_MODIFIER_LIST
|
||||||
|
PsiElement(private)('private')
|
||||||
|
PsiErrorElement:Expecting primary constructor parameter list
|
||||||
|
<empty list>
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
CLASS_BODY
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
FUN
|
||||||
|
PsiElement(fun)('fun')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
BLOCK
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
CLASS
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('A1')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
<empty list>
|
||||||
|
CLASS_BODY
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
CLASS
|
||||||
|
MODIFIER_LIST
|
||||||
|
PsiElement(open)('open')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(class)('class')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(IDENTIFIER)('B')
|
||||||
|
TYPE_PARAMETER_LIST
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
TYPE_PARAMETER
|
||||||
|
PsiElement(IDENTIFIER)('T')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PsiElement(COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
REFERENCE_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('A')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
PRIMARY_CONSTRUCTOR_MODIFIER_LIST
|
||||||
|
PsiElement(private)('private')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_PARAMETER_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
CLASS_BODY
|
||||||
|
PsiElement(LBRACE)('{')
|
||||||
|
PsiWhiteSpace('\n\n')
|
||||||
|
PsiElement(RBRACE)('}')
|
||||||
Reference in New Issue
Block a user