Parsing: allow primary ctor in object syntactically

It's needed for better recovering for cases of changes like 'class' -> 'object'

The only sensible case when it's may be bad:
class A {
   object B
   constructor() : super()
}

But it seems to be rare, and ';' can be used to separate object from secondary ctor
This commit is contained in:
Denis Zharkov
2015-05-29 18:38:01 +03:00
parent 3f7ca5a586
commit 9c574469ca
6 changed files with 57 additions and 70 deletions
@@ -705,14 +705,18 @@ public class JetParsing extends AbstractJetParsing {
* class
* : modifiers ("class" | "interface") SimpleName
* typeParameters?
* modifiers ("(" primaryConstructorParameter{","} ")")?
* primaryConstructor?
* (":" annotations delegationSpecifier{","})?
* typeConstraints
* (classBody? | enumClassBody)
* ;
*
* primaryConstructor
* : (modifiers "constructor")? ("(" functionParameter{","} ")")
* ;
*
* object
* : "object" SimpleName? ":" delegationSpecifier{","}? classBody?
* : "object" SimpleName? primaryConstructor? ":" delegationSpecifier{","}? classBody?
* ;
*/
IElementType parseClassOrObject(
@@ -761,7 +765,7 @@ public class JetParsing extends AbstractJetParsing {
);
// Some modifiers found, but no parentheses following: class has already ended, and we are looking at something else
if ((object && at(CONSTRUCTOR_KEYWORD)) || (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD))) {
if (hasConstructorModifiers && !atSet(LPAR, LBRACE, COLON, CONSTRUCTOR_KEYWORD)) {
beforeConstructorModifiers.rollbackTo();
return object ? OBJECT_DECLARATION : CLASS;
}
+1 -1
View File
@@ -28,7 +28,7 @@ private @open [Ann1(1)] @Ann2("1") Ann3("2") class A(
@companion object
@companion @private object B
@companion @private object B;
@main
@@ -419,6 +419,7 @@ JetFile: validDeclarations.kt
PsiWhiteSpace(' ')
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('B')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n\n ')
SECONDARY_CONSTRUCTOR
MODIFIER_LIST
@@ -127,17 +127,14 @@ JetFile: nestedClassAmbiguity.kt
PsiWhiteSpace(' ')
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('Nested4')
PsiWhiteSpace('\n ')
SECONDARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
PRIMARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CONSTRUCTOR_DELEGATION_CALL
CONSTRUCTOR_DELEGATION_REFERENCE
<empty list>
BLOCK
CLASS_BODY
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
@@ -146,26 +143,29 @@ JetFile: nestedClassAmbiguity.kt
PsiWhiteSpace(' ')
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('Nested5')
PsiWhiteSpace(' ')
SECONDARY_CONSTRUCTOR
MODIFIER_LIST
PsiElement(private)('private')
PsiWhiteSpace(' ')
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
CONSTRUCTOR_DELEGATION_CALL
CONSTRUCTOR_DELEGATION_REFERENCE
PsiElement(super)('super')
VALUE_ARGUMENT_LIST
PRIMARY_CONSTRUCTOR
MODIFIER_LIST
PsiElement(private)('private')
PsiWhiteSpace(' ')
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATOR_SUPER_CALL
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
PsiErrorElement:Type expected
PsiElement(super)('super')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
@@ -176,45 +176,24 @@ JetFile: nestedClassAmbiguity.kt
PsiWhiteSpace(' ')
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('TopLevel')
PsiWhiteSpace(' ')
MODIFIER_LIST
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('constructor')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
VALUE_ARGUMENT
PsiErrorElement:Expecting an expression
<empty list>
PsiErrorElement:Expecting ')'
PsiElement(val)('val')
PsiWhiteSpace(' ')
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('x')
PsiErrorElement:Expecting a top level declaration
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
MODIFIER_LIST
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiErrorElement:Expecting a top level declaration
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
FUN
PsiErrorElement:Expecting a top level declaration
<empty list>
BLOCK
PRIMARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
FUN
+4 -1
View File
@@ -17,12 +17,15 @@ internal class Example<X, T : Comparable<X>>(protected val x : Foo<X, T>, y : So
class
: modifiers ("class" | "trait") SimpleName
typeParameters?
(modifiers "constructor")? ("(" functionParameter{","} ")")?
primaryConstructor?
(":" annotations delegationSpecifier{","})?
typeConstraints
(classBody? | enumClassBody)
;
primaryConstructor
: (modifiers "constructor")? ("(" functionParameter{","} ")")
;
classBody
: ("{" members "}")?
+1 -1
View File
@@ -111,7 +111,7 @@ parameter
;
object
: "object" SimpleName (":" delegationSpecifier{","})? classBody? // Class body can be optional: this is a declaration
: "object" SimpleName primaryConstructor? (":" delegationSpecifier{","})? classBody? // Class body can be optional: this is a declaration
secondaryConstructor
: modifiers "constructor" valueParameters (":" constructorDelegationCall)? block