Enum parsing changed: first entries, then members. Grammar fixed accordingly.

A set of compiler tests and some plugin tests changed accordingly.
Compiler Kotlin code changed accordingly.
This commit is contained in:
Mikhail Glukhikh
2015-05-05 12:41:20 +03:00
parent 7a4dee44b8
commit cf741cb868
23 changed files with 243 additions and 103 deletions
@@ -97,10 +97,6 @@ public trait ModuleInfo {
public enum class DependenciesOnBuiltins : DependencyOnBuiltins {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//TODO: KT-5457
}
NONE {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//do nothing
@@ -111,6 +107,11 @@ public trait ModuleInfo {
dependencies.add(builtinsModule)
}
}
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//TODO: KT-5457
}
}
}
@@ -740,45 +740,48 @@ public class JetParsing extends AbstractJetParsing {
/*
* enumClassBody
* : "{" (enumEntry | memberDeclaration)* "}"
* : "{" enumEntries members "}"
* ;
*/
private void parseEnumClassBody() {
if (!at(LBRACE)) return;
PsiBuilder.Marker classBody = mark();
PsiBuilder.Marker body = mark();
myBuilder.enableNewlines();
advance(); // LBRACE
parseEnumEntries();
parseMembers();
expect(RBRACE, "Expecting '}' to close enum class body");
myBuilder.restoreNewlinesState();
body.done(CLASS_BODY);
}
/**
* enumEntries
* : enumEntry*
* ;
*/
private void parseEnumEntries() {
while (!eof() && !at(RBRACE)) {
PsiBuilder.Marker entryOrMember = mark();
PsiBuilder.Marker entry = mark();
ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, ONLY_ESCAPED_REGULAR_ANNOTATIONS);
IElementType type;
// ?: how can we find ourselves at SOFT_KEYWORDS_AT_MEMBER_START if we are at identifier?
// Or, is it just for performance?
if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) {
parseEnumEntry();
type = ENUM_ENTRY;
closeDeclarationWithCommentBinders(entry, ENUM_ENTRY, true);
}
else {
type = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected());
}
if (type == null) {
errorAndAdvance("Expecting an enum entry or member declaration");
entryOrMember.drop();
}
else {
closeDeclarationWithCommentBinders(entryOrMember, type, true);
entry.rollbackTo();
break;
}
}
expect(RBRACE, "Expecting '}' to close enum class body");
myBuilder.restoreNewlinesState();
classBody.done(CLASS_BODY);
}
/*
@@ -808,7 +811,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* classBody
* : ("{" memberDeclaration* "}")?
* : ("{" members "}")?
* ;
*/
private void parseClassBody() {
@@ -817,12 +820,7 @@ public class JetParsing extends AbstractJetParsing {
myBuilder.enableNewlines();
if (expect(LBRACE, "Expecting a class body")) {
while (!eof()) {
if (at(RBRACE)) {
break;
}
parseMemberDeclaration();
}
parseMembers();
expect(RBRACE, "Missing '}");
}
@@ -831,6 +829,20 @@ public class JetParsing extends AbstractJetParsing {
body.done(CLASS_BODY);
}
/**
* members
* : memberDeclaration*
* ;
*/
private void parseMembers() {
while (!eof()) {
if (at(RBRACE)) {
break;
}
parseMemberDeclaration();
}
}
/*
* memberDeclaration
* : modifiers memberDeclaration'
@@ -1,7 +1,7 @@
enum class E {
abstract class Nested
ENTRY
abstract class Nested
}
fun box(): String {
@@ -19,13 +19,13 @@ enum class A1(val prop1: String) {
}
enum class A2 {
val prop1: String
X: A2("asd")
Y: A2() {
override fun f() = super.f() + "#Y"
}
Z: A2(5)
val prop1: String
val prop2: String = "const2"
var prop3: String = ""
@@ -0,0 +1,11 @@
package a.b.c.test.enum
enum class Enum {
// We have six entries in the following line,
// not one entry with five annotations
A B C D E F {
override fun f() = 4
}
open fun f() = 3
}
+100
View File
@@ -0,0 +1,100 @@
JetFile: EnumNoAnnotations.kt
PACKAGE_DIRECTIVE
PsiElement(package)('package')
PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('test')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('enum')
PsiWhiteSpace('\n\n')
CLASS
MODIFIER_LIST
PsiElement(enum)('enum')
PsiWhiteSpace(' ')
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Enum')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
ENUM_ENTRY
PsiComment(EOL_COMMENT)('// We have six entries in the following line,')
PsiWhiteSpace('\n ')
PsiComment(EOL_COMMENT)('// not one entry with five annotations')
PsiWhiteSpace('\n ')
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('A')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('B')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('C')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('D')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('E')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('F')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
FUN
MODIFIER_LIST
PsiElement(override)('override')
PsiWhiteSpace(' ')
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('4')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
FUN
MODIFIER_LIST
PsiElement(open)('open')
PsiWhiteSpace(' ')
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -133,17 +133,20 @@ JetFile: enumEntries.kt
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('Ann')
PsiErrorElement:Expecting an enum entry or member declaration
PsiErrorElement:Expecting member declaration
PsiElement(LPAR)('(')
PsiErrorElement:Expecting an enum entry or member declaration
PsiErrorElement:Expecting member declaration
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('W')
PsiWhiteSpace('\n\n ')
FUN
MODIFIER_LIST
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('W')
PsiWhiteSpace('\n\n ')
ANNOTATION_ENTRY
PsiElement(AT)('@')
CONSTRUCTOR_CALLEE
@@ -1,13 +1,12 @@
enum class A {
constructor(x: Int) {}
abc1 : A(1,2,3)
abc2 : A(1,2,3) {}
abc3
constructor(x: Int) {}
init {}
abc3
constructor(x: Int): this() {}
init {
@@ -12,27 +12,6 @@ JetFile: enumParsing.kt
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
SECONDARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CONSTRUCTOR_DELEGATION_CALL
CONSTRUCTOR_DELEGATION_REFERENCE
<empty list>
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('abc1')
@@ -92,6 +71,31 @@ JetFile: enumParsing.kt
CLASS_BODY
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('abc3')
PsiWhiteSpace('\n\n ')
SECONDARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('x')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
CONSTRUCTOR_DELEGATION_CALL
CONSTRUCTOR_DELEGATION_REFERENCE
<empty list>
BLOCK
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
ANONYMOUS_INITIALIZER
PsiElement(init)('init')
@@ -100,10 +104,6 @@ JetFile: enumParsing.kt
PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('abc3')
PsiWhiteSpace('\n\n ')
SECONDARY_CONSTRUCTOR
PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST
@@ -205,6 +205,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest(fileName);
}
@TestMetadata("EnumNoAnnotations.kt")
public void testEnumNoAnnotations() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/EnumNoAnnotations.kt");
doParsingTest(fileName);
}
@TestMetadata("Enums.kt")
public void testEnums() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/Enums.kt");
+5 -1
View File
@@ -25,7 +25,11 @@ class
classBody
: ("{" memberDeclaration* "}")?
: ("{" members "}")?
;
members
: memberDeclaration*
;
delegationSpecifier
+5 -1
View File
@@ -5,7 +5,11 @@ See [Enum classes](enum-classes.html)
*/
enumClassBody
: "{" (enumEntry | memberDeclaration)* "}"
: "{" enumEntries members "}"
;
enumEntries
: enumEntry*
;
enumEntry
@@ -1,12 +1,6 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetNamedFunction
// OPTIONS: usages
enum class E {
init {
foo(1)
}
open fun <caret>foo(n: Int): Int = n
O
A {
init {
@@ -22,4 +16,10 @@ enum class E {
override fun foo(n: Int): Int = n + 2
}
init {
foo(1)
}
open fun <caret>foo(n: Int): Int = n
}
@@ -1,3 +1,3 @@
Function call (13: 13) foo(1)
Function call (20: 13) foo(1)
Function call (5: 9) foo(1)
Function call (14: 13) foo(1)
Function call (21: 9) foo(1)
Function call (7: 13) foo(1)
@@ -29,9 +29,9 @@ interface T1
// -----
enum class E1 {
object O7
ENTRY
object O7
}
// -----
@@ -67,9 +67,9 @@ interface T2
// -----
enum class E2 {
object O14 {}
ENTRY
object O14 {}
}
// -----
@@ -110,8 +110,8 @@ interface T3
// -----
enum class E3 {
ENTRY
object O21 {
}
ENTRY
}
@@ -24,8 +24,8 @@ interface T1
// -----
enum class E1 {
object O7
ENTRY
object O7
}
// -----
@@ -56,8 +56,8 @@ interface T2
// -----
enum class E2 {
object O14 {}
ENTRY
object O14 {}
}
// -----
@@ -93,7 +93,7 @@ interface T3
// -----
enum class E3 {
ENTRY
object O21 {
}
ENTRY
}
@@ -1,6 +1,4 @@
enum class <caret>E {
open fun foo(n: Int): Int = n
O
A {
override fun foo(n: Int): Int = n + 1
@@ -10,6 +8,8 @@ enum class <caret>E {
override fun foo(n: Int): Int = n + 2
}
open fun foo(n: Int): Int = n
}
// REF: (E).A
@@ -1,6 +1,4 @@
enum class E {
open fun <caret>foo(n: Int): Int = n
O
A {
override fun foo(n: Int): Int = n + 1
@@ -10,6 +8,8 @@ enum class E {
override fun foo(n: Int): Int = n + 2
}
open fun <caret>foo(n: Int): Int = n
}
// REF: (in E.A).foo(Int)
@@ -1,6 +1,4 @@
enum class E {
open fun foo(n: Int, s: String): Int = n
O
A {
override fun foo(n: Int, s: String): Int = n + 1
@@ -10,4 +8,6 @@ enum class E {
override fun foo(n: Int, s: String): Int = n + 2
}
open fun foo(n: Int, s: String): Int = n
}
@@ -1,6 +1,4 @@
enum class E {
open fun <caret>foo(n: Int): Int = n
O
A {
override fun foo(n: Int): Int = n + 1
@@ -10,4 +8,6 @@ enum class E {
override fun foo(n: Int): Int = n + 2
}
open fun <caret>foo(n: Int): Int = n
}
@@ -1,8 +1,6 @@
package test
enum class E {
open fun bar(n: Int): Int = n
O
A {
override fun bar(n: Int): Int = n + 1
@@ -12,4 +10,6 @@ enum class E {
override fun bar(n: Int): Int = n + 2
}
open fun bar(n: Int): Int = n
}
@@ -1,8 +1,6 @@
package test
enum class E {
open fun foo(n: Int): Int = n
O
A {
override fun foo(n: Int): Int = n + 1
@@ -12,4 +10,6 @@ enum class E {
override fun foo(n: Int): Int = n + 2
}
open fun foo(n: Int): Int = n
}
@@ -1,8 +1,6 @@
package foo
enum class B(open val bar: Int) {
val x = 1
var y = 12;
a : B(0) {
override val bar = 3
init {
@@ -12,6 +10,8 @@ enum class B(open val bar: Int) {
b : B(4) {
}
c : B(5)
val x = 1
var y = 12;
}
trait X {