diff --git a/grammar/src/class.grm b/grammar/src/class.grm index 4b10dd5a9aa..658ef24caa6 100644 --- a/grammar/src/class.grm +++ b/grammar/src/class.grm @@ -16,7 +16,7 @@ class "wraps"? ("(" primaryConstructorParameter{","} ")")? (":" attributes delegationSpecifier{","})? - classBody? + (classBody? | enumClassBody) ; typeParameters diff --git a/grammar/src/enum.grm b/grammar/src/enum.grm new file mode 100644 index 00000000000..adb0eb553ce --- /dev/null +++ b/grammar/src/enum.grm @@ -0,0 +1,7 @@ +enumClassBody + : "{" enumEntry* "}" + ; + +enumEntry + : modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? classBody? + ; diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 4d5e4810d14..913b100ede7 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -54,6 +54,7 @@ public interface JetNodeTypes { JetNodeType CLASS_OBJECT = new JetNodeType("CLASS_OBJECT"); JetNodeType TYPE_CONSTRAINT_LIST = new JetNodeType("TYPE_CONSTRAINT_LIST"); JetNodeType TYPE_CONSTRAINT = new JetNodeType("TYPE_CONSTRAINT"); + JetNodeType ENUM_ENTRY = new JetNodeType("ENUM_ENTRY"); IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME"); } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/Consumer.java b/idea/src/org/jetbrains/jet/lang/parsing/Consumer.java new file mode 100644 index 00000000000..c236931e9ff --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/parsing/Consumer.java @@ -0,0 +1,8 @@ +package org.jetbrains.jet.lang.parsing; + +/** + * @author abreslav + */ +public interface Consumer { + void consume(T item); +} diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 6dbbc6318b7..f96fdde2cb6 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -8,7 +8,9 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.jet.JetNodeType; import org.jetbrains.jet.lexer.JetKeywordToken; +import org.jetbrains.jet.lexer.JetToken; +import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -30,7 +32,9 @@ public class JetParsing extends AbstractJetParsing { } private static final TokenSet TOPLEVEL_OBJECT_FIRST = TokenSet.create(TYPE_KEYWORD, CLASS_KEYWORD, - EXTENSION_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, REF_KEYWORD, NAMESPACE_KEYWORD, DECOMPOSER_KEYWORD); + EXTENSION_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, NAMESPACE_KEYWORD, DECOMPOSER_KEYWORD); + private static final TokenSet ENUM_MEMBER_FIRST = TokenSet.create(TYPE_KEYWORD, CLASS_KEYWORD, + EXTENSION_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, DECOMPOSER_KEYWORD, IDENTIFIER); private static final TokenSet CLASS_NAME_RECOVERY_SET = TokenSet.orSet(TokenSet.create(LT, WRAPS_KEYWORD, LPAR, COLON, LBRACE), TOPLEVEL_OBJECT_FIRST); private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, WRAPS_KEYWORD, LPAR, COLON, LBRACE, GT); @@ -168,7 +172,9 @@ public class JetParsing extends AbstractJetParsing { */ private void parseTopLevelObject() { PsiBuilder.Marker decl = mark(); - parseModifierList(); + + EnumDetector detector = new EnumDetector(); + parseModifierList(detector); IElementType keywordToken = tt(); JetNodeType declType = null; @@ -176,7 +182,7 @@ public class JetParsing extends AbstractJetParsing { declType = parseNamespaceBlock(); } else if (keywordToken == CLASS_KEYWORD) { - declType = parseClass(); + declType = parseClass(detector.isEnum()); } else if (keywordToken == EXTENSION_KEYWORD) { declType = parseExtension(); @@ -269,12 +275,22 @@ public class JetParsing extends AbstractJetParsing { * (modifier | attribute)* */ private void parseModifierList() { + parseModifierList(null); + } + + /** + * (modifier | attribute)* + * + * Feeds modifiers (not attributes) into the passed consumer, if it is not null + */ + private void parseModifierList(Consumer tokenConsumer) { PsiBuilder.Marker list = mark(); boolean empty = true; while (!eof()) { if (at(LBRACKET)) { parseAttributeAnnotation(); } else if (atSet(MODIFIER_KEYWORDS)) { + if (tokenConsumer != null) tokenConsumer.consume(tt()); advance(); // MODIFIER } else { @@ -372,10 +388,10 @@ public class JetParsing extends AbstractJetParsing { * "wraps"? * ("(" primaryConstructorParameter{","} ")")? * (":" attributes delegationSpecifier{","})? - * classBody? + * (classBody? | enumClassBody) * ; */ - private JetNodeType parseClass() { + private JetNodeType parseClass(boolean enumClass) { assert at(CLASS_KEYWORD); advance(); // CLASS_KEYWORD @@ -393,19 +409,95 @@ public class JetParsing extends AbstractJetParsing { } if (at(LBRACE)) { - parseClassBody(); + if (enumClass) { + parseEnumClassBody(); + } + else { + parseClassBody(); + } } return CLASS; } + /* + * enumClassBody + * : "{" enumEntry* "}" + * ; + */ + private void parseEnumClassBody() { + if (!at(LBRACE)) return; + + PsiBuilder.Marker classBody = mark(); + + advance(); // LBRACE + + while (!eof() && !at(RBRACE)) { + PsiBuilder.Marker entryOrMember = mark(); + + TokenSet constructorNameFollow = TokenSet.create(SEMICOLON, COLON, LPAR, LT, LBRACE); + int lastId = findLastBefore(ENUM_MEMBER_FIRST, constructorNameFollow, false); + EnumDetector enumDetector = new EnumDetector(); + createTruncatedBuilder(lastId).parseModifierList(enumDetector); + + IElementType type; + if (at(IDENTIFIER)) { + parseEnumEntry(); + type = ENUM_ENTRY; + } + else { + type = parseMemberDeclarationRest(enumDetector.isEnum()); + } + + if (type == null) { + errorAndAdvance("Expecting an enum entry or member declaration"); + entryOrMember.drop(); + } + else { + entryOrMember.done(type); + } + } + + expect(RBRACE, "Expecting '}' to close enum class body"); + + classBody.done(CLASS_BODY); + } + + /* + * enumEntry + * : modifiers SimpleName typeParameters? valueParameters? (":" initializer{","})? classBody? + * ; + */ + private void parseEnumEntry() { + assert at(IDENTIFIER); + + advance(); // IDENTIFIER + + parseTypeParameterList(TokenSet.create(COLON, LPAR, SEMICOLON, LBRACE)); + + if (at(LPAR)) { + parseValueParameterList(false, TokenSet.create(COLON, SEMICOLON, LBRACE)); + } + + if (at(COLON)) { + advance(); // COLON + + parseInitializerList(); + } + + if (at(LBRACE)) { + parseClassBody(); + } + + consumeIf(SEMICOLON); + } + /* * classBody * : ("{" memberDeclaration{","} "}")? * ; */ /*package*/ void parseClassBody() { - // TODO: enum classes assert at(LBRACE); PsiBuilder.Marker body = mark(); advance(); // LBRACE @@ -435,8 +527,21 @@ public class JetParsing extends AbstractJetParsing { private void parseMemberDeclaration() { PsiBuilder.Marker decl = mark(); - parseModifierList(); + EnumDetector enumDetector = new EnumDetector(); + parseModifierList(enumDetector); + JetNodeType declType = parseMemberDeclarationRest(enumDetector.isEnum()); + + if (declType == null) { + errorAndAdvance("Expecting member declaration"); + decl.drop(); + } + else { + decl.done(declType); + } + } + + private JetNodeType parseMemberDeclarationRest(boolean isEnum) { IElementType keywordToken = tt(); JetNodeType declType = null; if (keywordToken == CLASS_KEYWORD) { @@ -444,7 +549,7 @@ public class JetParsing extends AbstractJetParsing { declType = parseClassObject(); } else { - declType = parseClass(); + declType = parseClass(isEnum); } } else if (keywordToken == EXTENSION_KEYWORD) { @@ -465,14 +570,7 @@ public class JetParsing extends AbstractJetParsing { else if (keywordToken == THIS_KEYWORD) { declType = parseConstructor(); } - - if (declType == null) { - errorAndAdvance("Expecting member declaration"); - decl.drop(); - } - else { - decl.done(declType); - } + return declType; } /* @@ -1326,4 +1424,19 @@ public class JetParsing extends AbstractJetParsing { return new JetParsing(new TruncatedSemanticWhitespaceAwarePsiBuilder(myBuilder, eofPosition)); } + private static class EnumDetector implements Consumer { + + private boolean myEnum = false; + + @Override + public void consume(IElementType item) { + if (item == ENUM_KEYWORD) { + myEnum = true; + } + } + + public boolean isEnum() { + return myEnum; + } + } } \ No newline at end of file diff --git a/idea/testData/psi/Enums.jet b/idea/testData/psi/Enums.jet new file mode 100644 index 00000000000..ce6e7f72675 --- /dev/null +++ b/idea/testData/psi/Enums.jet @@ -0,0 +1,14 @@ +enum class Color(val rgb : Int) { + RED : Color(0xFF000) + GREEN : Color(0x00FF00) + BLUE : Color(0x0000FF) +} + +enum class List(val size : Int) { + Nil : List(0) + + Cons(value : T, tail : List) : List(/*tail.size + 1*/a) + + val isEmpty : Bool + get() = size //> 0 +} \ No newline at end of file diff --git a/idea/testData/psi/Enums.txt b/idea/testData/psi/Enums.txt new file mode 100644 index 00000000000..b986eb53436 --- /dev/null +++ b/idea/testData/psi/Enums.txt @@ -0,0 +1,218 @@ +JetFile: Enums.jet + NAMESPACE + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('Color') + TYPE_PARAMETER_LIST + + PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + PsiElement(LPAR)('(') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('rgb') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + PsiElement(IDENTIFIER)('RED') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Color') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + PsiElement(INTEGER_LITERAL)('0xFF000') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + ENUM_ENTRY + PsiElement(IDENTIFIER)('GREEN') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Color') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + PsiElement(INTEGER_LITERAL)('0x00FF00') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + ENUM_ENTRY + PsiElement(IDENTIFIER)('BLUE') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Color') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + PsiElement(INTEGER_LITERAL)('0x0000FF') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n') + CLASS + MODIFIER_LIST + PsiElement(enum)('enum') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('List') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + MODIFIER_LIST + PsiElement(out)('out') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + PsiElement(LPAR)('(') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('size') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + ENUM_ENTRY + PsiElement(IDENTIFIER)('Nil') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Nothing') + PsiElement(GT)('>') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + PsiElement(INTEGER_LITERAL)('0') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n\n ') + ENUM_ENTRY + PsiElement(IDENTIFIER)('Cons') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('value') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('T') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('tail') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + INITIALIZER_LIST + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiComment(BLOCK_COMMENT)('/*tail.size + 1*/') + VALUE_ARGUMENT + PsiElement(IDENTIFIER)('a') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n\n ') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('isEmpty') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Bool') + PsiWhiteSpace('\n ') + PROPERTY_ACCESSOR + PsiElement(get)('get') + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('size') + PsiWhiteSpace(' ') + PsiComment(EOL_COMMENT)('//> 0') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/idea/testData/psi/SoftKeywords.txt b/idea/testData/psi/SoftKeywords.txt index ddc5c1dfbb5..7bd7f5fa95d 100644 --- a/idea/testData/psi/SoftKeywords.txt +++ b/idea/testData/psi/SoftKeywords.txt @@ -942,7 +942,353 @@ JetFile: SoftKeywords.jet TYPE_REFERENCE USER_TYPE PsiElement(IDENTIFIER)('t') - PsiWhiteSpace('\n ') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + VALUE_PARAMETER + MODIFIER_LIST + PsiElement(public)('public') + PsiWhiteSpace(' ') + PsiElement(protected)('protected') + PsiWhiteSpace(' ') + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(internal)('internal') + PsiWhiteSpace(' ') + PsiElement(abstract)('abstract') + PsiWhiteSpace('\n ') + PsiElement(virtual)('virtual') + PsiWhiteSpace('\n ') + PsiElement(enum)('enum') + PsiWhiteSpace('\n ') + PsiElement(open)('open') + PsiWhiteSpace('\n ') + PsiElement(attribute)('attribute') + PsiWhiteSpace('\n ') + PsiElement(override)('override') + PsiWhiteSpace('\n ') + PsiElement(virtual)('virtual') + PsiWhiteSpace('\n ') + PsiElement(abstract)('abstract') + PsiWhiteSpace('\n ') + PsiElement(private)('private') + PsiWhiteSpace('\n ') + PsiElement(protected)('protected') + PsiWhiteSpace('\n ') + PsiElement(public)('public') + PsiWhiteSpace('\n ') + PsiElement(internal)('internal') + PsiWhiteSpace('\n ') + PsiElement(lazy)('lazy') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('open') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiWhiteSpace('\n\n ') PsiElement(RPAR)(')') PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n\n') + CLASS + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('F') + TYPE_PARAMETER_LIST + + PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + PsiElement(LPAR)('(') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('bar') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('abstract') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('virtual') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('enum') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('open') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('attribute') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('override') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('virtual') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('abstract') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('private') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('protected') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('public') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('internal') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('lazy') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('wraps') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('import') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('where') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('by') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('get') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('set') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('public') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('private') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('protected') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + PsiElement(IDENTIFIER)('internal') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('t') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PRIMARY_CONSTRUCTOR_PARAMETER + MODIFIER_LIST + PsiElement(public)('public') + PsiWhiteSpace(' ') + PsiElement(protected)('protected') + PsiWhiteSpace(' ') + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(internal)('internal') + PsiWhiteSpace(' ') + PsiElement(abstract)('abstract') + PsiWhiteSpace('\n ') + PsiElement(virtual)('virtual') + PsiWhiteSpace('\n ') + PsiElement(enum)('enum') + PsiWhiteSpace('\n ') + PsiElement(open)('open') + PsiWhiteSpace('\n ') + PsiElement(attribute)('attribute') + PsiWhiteSpace('\n ') + PsiElement(override)('override') + PsiWhiteSpace('\n ') + PsiElement(virtual)('virtual') + PsiWhiteSpace('\n ') + PsiElement(abstract)('abstract') + PsiWhiteSpace('\n ') + PsiElement(private)('private') + PsiWhiteSpace('\n ') + PsiElement(protected)('protected') + PsiWhiteSpace('\n ') + PsiElement(public)('public') + PsiWhiteSpace('\n ') + PsiElement(internal)('internal') + PsiWhiteSpace('\n ') + PsiElement(lazy)('lazy') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('open') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('b') + PsiWhiteSpace('\n') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java index 4fe1bfd87b8..d39a06aec6a 100644 --- a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java +++ b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java @@ -58,4 +58,5 @@ public class JetParsingTest extends ParsingTestCase { public void testSimpleClassMembers_ERR() throws Exception {doTest(true);} public void testConstructors() throws Exception {doTest(true);} public void testTypeConstraints() throws Exception {doTest(true);} + public void testEnums() throws Exception {doTest(true);} }