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 { public enum class DependenciesOnBuiltins : DependencyOnBuiltins {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//TODO: KT-5457
}
NONE { NONE {
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) { override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//do nothing //do nothing
@@ -111,6 +107,11 @@ public trait ModuleInfo {
dependencies.add(builtinsModule) dependencies.add(builtinsModule)
} }
} }
override fun adjustDependencies(builtinsModule: ModuleDescriptorImpl, dependencies: MutableList<ModuleDescriptorImpl>) {
//TODO: KT-5457
}
} }
} }
@@ -740,45 +740,48 @@ public class JetParsing extends AbstractJetParsing {
/* /*
* enumClassBody * enumClassBody
* : "{" (enumEntry | memberDeclaration)* "}" * : "{" enumEntries members "}"
* ; * ;
*/ */
private void parseEnumClassBody() { private void parseEnumClassBody() {
if (!at(LBRACE)) return; if (!at(LBRACE)) return;
PsiBuilder.Marker classBody = mark(); PsiBuilder.Marker body = mark();
myBuilder.enableNewlines(); myBuilder.enableNewlines();
advance(); // LBRACE 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)) { while (!eof() && !at(RBRACE)) {
PsiBuilder.Marker entryOrMember = mark(); PsiBuilder.Marker entry = mark();
ModifierDetector detector = new ModifierDetector(); ModifierDetector detector = new ModifierDetector();
parseModifierList(detector, ONLY_ESCAPED_REGULAR_ANNOTATIONS); 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)) { if (!atSet(SOFT_KEYWORDS_AT_MEMBER_START) && at(IDENTIFIER)) {
parseEnumEntry(); parseEnumEntry();
type = ENUM_ENTRY; closeDeclarationWithCommentBinders(entry, ENUM_ENTRY, true);
} }
else { else {
type = parseMemberDeclarationRest(detector.isEnumDetected(), detector.isDefaultDetected()); entry.rollbackTo();
} break;
if (type == null) {
errorAndAdvance("Expecting an enum entry or member declaration");
entryOrMember.drop();
}
else {
closeDeclarationWithCommentBinders(entryOrMember, type, true);
} }
} }
expect(RBRACE, "Expecting '}' to close enum class body");
myBuilder.restoreNewlinesState();
classBody.done(CLASS_BODY);
} }
/* /*
@@ -808,7 +811,7 @@ public class JetParsing extends AbstractJetParsing {
/* /*
* classBody * classBody
* : ("{" memberDeclaration* "}")? * : ("{" members "}")?
* ; * ;
*/ */
private void parseClassBody() { private void parseClassBody() {
@@ -817,12 +820,7 @@ public class JetParsing extends AbstractJetParsing {
myBuilder.enableNewlines(); myBuilder.enableNewlines();
if (expect(LBRACE, "Expecting a class body")) { if (expect(LBRACE, "Expecting a class body")) {
while (!eof()) { parseMembers();
if (at(RBRACE)) {
break;
}
parseMemberDeclaration();
}
expect(RBRACE, "Missing '}"); expect(RBRACE, "Missing '}");
} }
@@ -831,6 +829,20 @@ public class JetParsing extends AbstractJetParsing {
body.done(CLASS_BODY); body.done(CLASS_BODY);
} }
/**
* members
* : memberDeclaration*
* ;
*/
private void parseMembers() {
while (!eof()) {
if (at(RBRACE)) {
break;
}
parseMemberDeclaration();
}
}
/* /*
* memberDeclaration * memberDeclaration
* : modifiers memberDeclaration' * : modifiers memberDeclaration'
@@ -1,7 +1,7 @@
enum class E { enum class E {
abstract class Nested
ENTRY ENTRY
abstract class Nested
} }
fun box(): String { fun box(): String {
@@ -19,13 +19,13 @@ enum class A1(val prop1: String) {
} }
enum class A2 { enum class A2 {
val prop1: String
X: A2("asd") X: A2("asd")
Y: A2() { Y: A2() {
override fun f() = super.f() + "#Y" override fun f() = super.f() + "#Y"
} }
Z: A2(5) Z: A2(5)
val prop1: String
val prop2: String = "const2" val prop2: String = "const2"
var prop3: String = "" 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 ENUM_ENTRY
OBJECT_DECLARATION_NAME OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('Ann') PsiElement(IDENTIFIER)('Ann')
PsiErrorElement:Expecting an enum entry or member declaration PsiErrorElement:Expecting member declaration
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
PsiErrorElement:Expecting an enum entry or member declaration PsiErrorElement:Expecting member declaration
PsiElement(RPAR)(')') PsiElement(RPAR)(')')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('W')
PsiWhiteSpace('\n\n ')
FUN FUN
MODIFIER_LIST MODIFIER_LIST
ANNOTATION_ENTRY
CONSTRUCTOR_CALLEE
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('W')
PsiWhiteSpace('\n\n ')
ANNOTATION_ENTRY ANNOTATION_ENTRY
PsiElement(AT)('@') PsiElement(AT)('@')
CONSTRUCTOR_CALLEE CONSTRUCTOR_CALLEE
@@ -1,13 +1,12 @@
enum class A { enum class A {
constructor(x: Int) {}
abc1 : A(1,2,3) abc1 : A(1,2,3)
abc2 : A(1,2,3) {} abc2 : A(1,2,3) {}
abc3
constructor(x: Int) {}
init {} init {}
abc3
constructor(x: Int): this() {} constructor(x: Int): this() {}
init { init {
@@ -12,27 +12,6 @@ JetFile: enumParsing.kt
CLASS_BODY CLASS_BODY
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ') 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 ENUM_ENTRY
OBJECT_DECLARATION_NAME OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('abc1') PsiElement(IDENTIFIER)('abc1')
@@ -92,6 +71,31 @@ JetFile: enumParsing.kt
CLASS_BODY CLASS_BODY
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}') 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 ') PsiWhiteSpace('\n\n ')
ANONYMOUS_INITIALIZER ANONYMOUS_INITIALIZER
PsiElement(init)('init') PsiElement(init)('init')
@@ -100,10 +104,6 @@ JetFile: enumParsing.kt
PsiElement(LBRACE)('{') PsiElement(LBRACE)('{')
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
ENUM_ENTRY
OBJECT_DECLARATION_NAME
PsiElement(IDENTIFIER)('abc3')
PsiWhiteSpace('\n\n ')
SECONDARY_CONSTRUCTOR SECONDARY_CONSTRUCTOR
PsiElement(constructor)('constructor') PsiElement(constructor)('constructor')
VALUE_PARAMETER_LIST VALUE_PARAMETER_LIST
@@ -205,6 +205,12 @@ public class JetParsingTestGenerated extends AbstractJetParsingTest {
doParsingTest(fileName); doParsingTest(fileName);
} }
@TestMetadata("EnumNoAnnotations.kt")
public void testEnumNoAnnotations() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/EnumNoAnnotations.kt");
doParsingTest(fileName);
}
@TestMetadata("Enums.kt") @TestMetadata("Enums.kt")
public void testEnums() throws Exception { public void testEnums() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/Enums.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/psi/Enums.kt");
+5 -1
View File
@@ -25,7 +25,11 @@ class
classBody classBody
: ("{" memberDeclaration* "}")? : ("{" members "}")?
;
members
: memberDeclaration*
; ;
delegationSpecifier delegationSpecifier
+5 -1
View File
@@ -5,7 +5,11 @@ See [Enum classes](enum-classes.html)
*/ */
enumClassBody enumClassBody
: "{" (enumEntry | memberDeclaration)* "}" : "{" enumEntries members "}"
;
enumEntries
: enumEntry*
; ;
enumEntry enumEntry
@@ -1,12 +1,6 @@
// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetNamedFunction // PSI_ELEMENT: org.jetbrains.kotlin.psi.JetNamedFunction
// OPTIONS: usages // OPTIONS: usages
enum class E { enum class E {
init {
foo(1)
}
open fun <caret>foo(n: Int): Int = n
O O
A { A {
init { init {
@@ -22,4 +16,10 @@ enum class E {
override fun foo(n: Int): Int = n + 2 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 (14: 13) foo(1)
Function call (20: 13) foo(1) Function call (21: 9) foo(1)
Function call (5: 9) foo(1) Function call (7: 13) foo(1)
@@ -29,9 +29,9 @@ interface T1
// ----- // -----
enum class E1 { enum class E1 {
object O7
ENTRY ENTRY
object O7
} }
// ----- // -----
@@ -67,9 +67,9 @@ interface T2
// ----- // -----
enum class E2 { enum class E2 {
object O14 {}
ENTRY ENTRY
object O14 {}
} }
// ----- // -----
@@ -110,8 +110,8 @@ interface T3
// ----- // -----
enum class E3 { enum class E3 {
ENTRY
object O21 { object O21 {
} }
ENTRY
} }
@@ -24,8 +24,8 @@ interface T1
// ----- // -----
enum class E1 { enum class E1 {
object O7
ENTRY ENTRY
object O7
} }
// ----- // -----
@@ -56,8 +56,8 @@ interface T2
// ----- // -----
enum class E2 { enum class E2 {
object O14 {}
ENTRY ENTRY
object O14 {}
} }
// ----- // -----
@@ -93,7 +93,7 @@ interface T3
// ----- // -----
enum class E3 { enum class E3 {
ENTRY
object O21 { object O21 {
} }
ENTRY
} }
@@ -1,6 +1,4 @@
enum class <caret>E { enum class <caret>E {
open fun foo(n: Int): Int = n
O O
A { A {
override fun foo(n: Int): Int = n + 1 override fun foo(n: Int): Int = n + 1
@@ -10,6 +8,8 @@ enum class <caret>E {
override fun foo(n: Int): Int = n + 2 override fun foo(n: Int): Int = n + 2
} }
open fun foo(n: Int): Int = n
} }
// REF: (E).A // REF: (E).A
@@ -1,6 +1,4 @@
enum class E { enum class E {
open fun <caret>foo(n: Int): Int = n
O O
A { A {
override fun foo(n: Int): Int = n + 1 override fun foo(n: Int): Int = n + 1
@@ -10,6 +8,8 @@ enum class E {
override fun foo(n: Int): Int = n + 2 override fun foo(n: Int): Int = n + 2
} }
open fun <caret>foo(n: Int): Int = n
} }
// REF: (in E.A).foo(Int) // REF: (in E.A).foo(Int)
@@ -1,6 +1,4 @@
enum class E { enum class E {
open fun foo(n: Int, s: String): Int = n
O O
A { A {
override fun foo(n: Int, s: String): Int = n + 1 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 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 { enum class E {
open fun <caret>foo(n: Int): Int = n
O O
A { A {
override fun foo(n: Int): Int = n + 1 override fun foo(n: Int): Int = n + 1
@@ -10,4 +8,6 @@ enum class E {
override fun foo(n: Int): Int = n + 2 override fun foo(n: Int): Int = n + 2
} }
open fun <caret>foo(n: Int): Int = n
} }
@@ -1,8 +1,6 @@
package test package test
enum class E { enum class E {
open fun bar(n: Int): Int = n
O O
A { A {
override fun bar(n: Int): Int = n + 1 override fun bar(n: Int): Int = n + 1
@@ -12,4 +10,6 @@ enum class E {
override fun bar(n: Int): Int = n + 2 override fun bar(n: Int): Int = n + 2
} }
open fun bar(n: Int): Int = n
} }
@@ -1,8 +1,6 @@
package test package test
enum class E { enum class E {
open fun foo(n: Int): Int = n
O O
A { A {
override fun foo(n: Int): Int = n + 1 override fun foo(n: Int): Int = n + 1
@@ -12,4 +10,6 @@ enum class E {
override fun foo(n: Int): Int = n + 2 override fun foo(n: Int): Int = n + 2
} }
open fun foo(n: Int): Int = n
} }
@@ -1,8 +1,6 @@
package foo package foo
enum class B(open val bar: Int) { enum class B(open val bar: Int) {
val x = 1
var y = 12;
a : B(0) { a : B(0) {
override val bar = 3 override val bar = 3
init { init {
@@ -12,6 +10,8 @@ enum class B(open val bar: Int) {
b : B(4) { b : B(4) {
} }
c : B(5) c : B(5)
val x = 1
var y = 12;
} }
trait X { trait X {