KT-193: Guard primary constructor modifier list with a lookahead for LPAR

This commit is contained in:
Andrey Breslav
2011-11-07 19:16:40 +03:00
parent d1787a5f6e
commit d292b6bcfe
3 changed files with 119 additions and 5 deletions
@@ -419,13 +419,27 @@ public class JetParsing extends AbstractJetParsing {
expect(IDENTIFIER, "Class name expected", CLASS_NAME_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));
}
else {
if (at(LPAR)) {
parseValueParameterList(false, TokenSet.create(COLON, LBRACE));
}
else if (hasConstructorModifiers) {
// A comprehensive error message for cases like:
// class A private : Foo
// or
// class A private {
error("Expecting primary constructor parameter list");
}
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)('}')