diff --git a/grammar/src/expressions.grm b/grammar/src/expressions.grm index ae5acebf2a6..85f4c9d6577 100644 --- a/grammar/src/expressions.grm +++ b/grammar/src/expressions.grm @@ -188,7 +188,8 @@ arrayAccess ; objectLiteral - : "object" delegationSpecifier{","}? classBody? + : "object" delegationSpecifier{","} classBody? + : "object" classBody ; /* Factory methods: diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index aa730156804..8a580e2cb68 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -51,6 +51,7 @@ public interface JetNodeTypes { JetNodeType INITIALIZER_LIST = new JetNodeType("INITIALIZER_LIST"); JetNodeType THIS_CALL = new JetNodeType("THIS_CALL"); JetNodeType BLOCK = new JetNodeType("BLOCK"); + JetNodeType CLASS_OBJECT = new JetNodeType("CLASS_OBJECT"); IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME"); } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 7787d5d9448..2071e132883 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -11,8 +11,11 @@ import static org.jetbrains.jet.lexer.JetTokens.*; * @author abreslav */ public class JetExpressionParsing extends AbstractJetParsing { - public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder) { + private final JetParsing myJetParsing; + + public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) { super(builder); + myJetParsing = jetParsing; } /* @@ -82,6 +85,25 @@ public class JetExpressionParsing extends AbstractJetParsing { argument.done(type); } + /* + * objectLiteral + * : "object" delegationSpecifier{","} classBody? + * : "object" classBody + * ; + */ + public void parseObjectLiteral() { + assert at(OBJECT_KEYWORD); + advance(); // OBJECT_KEYWORD + if (at(LBRACE)) { + myJetParsing.parseClassBody(); + } + else { + myJetParsing.parseDelegationSpecifierList(); + if (at(LBRACE)) { + myJetParsing.parseClassBody(); + } + } + } } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 903f05a289d..8f3c527a103 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -36,13 +36,13 @@ public class JetParsing extends AbstractJetParsing { private static final TokenSet TYPE_PARAMETER_GT_RECOVERY_SET = TokenSet.create(WHERE_KEYWORD, WRAPS_KEYWORD, LPAR, COLON, LBRACE, GT); private static final TokenSet PARAMETER_NAME_RECOVERY_SET = TokenSet.create(COLON, EQ, COMMA, RPAR); private static final TokenSet NAMESPACE_NAME_RECOVERY_SET = TokenSet.create(DOT, EOL_OR_SEMICOLON); - private static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LBRACE, LPAR); + /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, LBRACE, LPAR); private final JetExpressionParsing myExpressionParsing; public JetParsing(SemanticWhitespaceAwarePsiBuilder builder) { super(builder); - this.myExpressionParsing = new JetExpressionParsing(builder); + this.myExpressionParsing = new JetExpressionParsing(builder, this); } /* @@ -430,7 +430,7 @@ public class JetParsing extends AbstractJetParsing { * : ("{" memberDeclaration{","} "}")? * ; */ - private void parseClassBody() { + /*package*/ void parseClassBody() { // TODO: enum classes assert at(LBRACE); PsiBuilder.Marker body = mark(); @@ -577,8 +577,14 @@ public class JetParsing extends AbstractJetParsing { * ; */ private JetNodeType parseClassObject() { - // TODO - return null; + assert at(CLASS_KEYWORD) && lookahead(1) == OBJECT_KEYWORD; + + advance(); // CLASS_KEYWORD + + myExpressionParsing.parseObjectLiteral(); + + + return CLASS_OBJECT; } /* @@ -877,7 +883,7 @@ public class JetParsing extends AbstractJetParsing { /* * delegationSpecifier{","} */ - private void parseDelegationSpecifierList() { + /*package*/ void parseDelegationSpecifierList() { PsiBuilder.Marker list = mark(); while (true) { @@ -1024,7 +1030,7 @@ public class JetParsing extends AbstractJetParsing { } expect(GT, "Missing '>'", recoverySet); - // TODO : where an stuff + // TODO : where and stuff } list.done(TYPE_PARAMETER_LIST); } diff --git a/idea/testData/psi/SimpleClassMembers.jet b/idea/testData/psi/SimpleClassMembers.jet index e9f36daf043..1e7fbfc78c3 100644 --- a/idea/testData/psi/SimpleClassMembers.jet +++ b/idea/testData/psi/SimpleClassMembers.jet @@ -22,7 +22,23 @@ class foo { class Bar { extension foo for X { + class object { + } + + private class object { + + } + + private class object Fooo { + + } + + private class object Fooo, Bar by foo { + + } + + private class object Fooo, Bar by foo, Goo() } class Bar {} @@ -56,4 +72,23 @@ class foo { } + class object { + + } + + private class object { + + } + + private class object Fooo { + + } + + private class object Fooo, Bar by foo { + + } + + private class object Fooo, Bar by foo, Goo() + + } diff --git a/idea/testData/psi/SimpleClassMembers.txt b/idea/testData/psi/SimpleClassMembers.txt index 8997880b234..2f5a715f212 100644 --- a/idea/testData/psi/SimpleClassMembers.txt +++ b/idea/testData/psi/SimpleClassMembers.txt @@ -171,7 +171,117 @@ JetFile: SimpleClassMembers.jet PsiWhiteSpace(' ') CLASS_BODY PsiElement(LBRACE)('{') - PsiWhiteSpace('\n\n ') + PsiWhiteSpace('\n ') + CLASS_OBJECT + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_BY + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + PsiElement(by)('by') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_BY + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + PsiElement(by)('by') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Goo') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') PsiElement(RBRACE)('}') PsiWhiteSpace('\n\n ') CLASS @@ -411,5 +521,115 @@ JetFile: SimpleClassMembers.jet PsiElement(LBRACE)('{') PsiWhiteSpace('\n\n ') PsiElement(RBRACE)('}') - PsiWhiteSpace('\n\n') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_BY + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + PsiElement(by)('by') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + CLASS_OBJECT + MODIFIER_LIST + PsiElement(private)('private') + PsiWhiteSpace(' ') + PsiElement(class)('class') + PsiWhiteSpace(' ') + PsiElement(object)('object') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER_LIST + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CLASS + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Fooo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_BY + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Bar') + PsiWhiteSpace(' ') + PsiElement(by)('by') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + DELEGATION_SPECIFIER + DELEGATOR_SUPER_CALL + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Goo') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n\n\n') PsiElement(RBRACE)('}') \ No newline at end of file