Parsing object declarations

This commit is contained in:
Andrey Breslav
2011-06-02 18:44:56 +04:00
parent 7ad600220b
commit efd417e043
19 changed files with 2044 additions and 1956 deletions
+4
View File
@@ -32,6 +32,7 @@ class Example(a : Foo, i : Int) : Bar(i), Some {
memberDeclaration memberDeclaration
: classObject : classObject
: object
: constructor : constructor
: function : function
: property : property
@@ -100,3 +101,6 @@ setter
parameter parameter
: SimpleName ":" type : SimpleName ":" type
; ;
object
: "object" SimpleName ":" ":" delegationSpecifier{","}? classBody? // Class body can be optional: this is a declaration
+1
View File
@@ -124,6 +124,7 @@ declaration
: extension : extension
: class : class
: typedef : typedef
: object
; ;
statement statement
+1
View File
@@ -21,6 +21,7 @@ import
toplevelObject toplevelObject
: namespace : namespace
: class : class
: object
: extension : extension
: function : function
: property : property
@@ -16,6 +16,7 @@ public interface JetNodeTypes {
JetNodeType FUN = new JetNodeType("FUN", JetFunction.class); JetNodeType FUN = new JetNodeType("FUN", JetFunction.class);
JetNodeType EXTENSION = new JetNodeType("EXTENSION", JetExtension.class); JetNodeType EXTENSION = new JetNodeType("EXTENSION", JetExtension.class);
JetNodeType TYPEDEF = new JetNodeType("TYPEDEF", JetTypedef.class); JetNodeType TYPEDEF = new JetNodeType("TYPEDEF", JetTypedef.class);
JetNodeType OBJECT_DECLARATION = new JetNodeType("OBJECT_DECLARATION", JetObjectDeclaration.class);
JetNodeType CLASS_OBJECT = new JetNodeType("CLASS_OBJECT", JetClassObject.class); JetNodeType CLASS_OBJECT = new JetNodeType("CLASS_OBJECT", JetClassObject.class);
JetNodeType CONSTRUCTOR = new JetNodeType("CONSTRUCTOR", JetConstructor.class); JetNodeType CONSTRUCTOR = new JetNodeType("CONSTRUCTOR", JetConstructor.class);
@@ -597,7 +597,7 @@ public class JetControlFlowProcessor {
@Override @Override
public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
List<JetDelegationSpecifier> delegationSpecifiers = expression.getDelegationSpecifiers(); List<JetDelegationSpecifier> delegationSpecifiers = expression.getObjectDeclaration().getDelegationSpecifiers();
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) { if (delegationSpecifier instanceof JetDelegatorByExpressionSpecifier) {
JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier; JetDelegatorByExpressionSpecifier specifier = (JetDelegatorByExpressionSpecifier) delegationSpecifier;
@@ -1140,6 +1140,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
* : extension * : extension
* : class * : class
* : typedef * : typedef
* : object
* ; * ;
*/ */
private JetNodeType parseLocalDeclarationRest(boolean isEnum) { private JetNodeType parseLocalDeclarationRest(boolean isEnum) {
@@ -1160,6 +1161,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
else if (keywordToken == TYPE_KEYWORD) { else if (keywordToken == TYPE_KEYWORD) {
declType = myJetParsing.parseTypeDef(); declType = myJetParsing.parseTypeDef();
} }
else if (keywordToken == OBJECT_KEYWORD) {
myJetParsing.parseObject(true);
declType = OBJECT_DECLARATION;
}
return declType; return declType;
} }
@@ -1594,29 +1599,11 @@ public class JetExpressionParsing extends AbstractJetParsing {
argument.done(VALUE_ARGUMENT); argument.done(VALUE_ARGUMENT);
} }
/*
* objectLiteral
* : "object" ":" delegationSpecifier{","}? classBody // Cannot make class body optional: foo(object F, a)
* ;
*/
public void parseObjectLiteral() { public void parseObjectLiteral() {
assert _at(OBJECT_KEYWORD);
PsiBuilder.Marker literal = mark(); PsiBuilder.Marker literal = mark();
PsiBuilder.Marker declaration = mark();
advance(); // OBJECT_KEYWORD myJetParsing.parseObject(false);
declaration.done(OBJECT_DECLARATION);
if (at(LBRACE)) {
myJetParsing.parseClassBody();
}
else {
expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, NAMESPACE_KEYWORD));
myJetParsing.parseDelegationSpecifierList();
if (at(LBRACE)) {
myJetParsing.parseClassBody();
}
}
literal.done(OBJECT_LITERAL); literal.done(OBJECT_LITERAL);
} }
@@ -213,6 +213,7 @@ public class JetParsing extends AbstractJetParsing {
* : function * : function
* : property * : property
* : typedef * : typedef
* : object
* ; * ;
*/ */
private void parseTopLevelObject() { private void parseTopLevelObject() {
@@ -241,6 +242,10 @@ public class JetParsing extends AbstractJetParsing {
else if (keywordToken == TYPE_KEYWORD) { else if (keywordToken == TYPE_KEYWORD) {
declType = parseTypeDef(); declType = parseTypeDef();
} }
else if (keywordToken == OBJECT_KEYWORD) {
parseObject(true);
declType = OBJECT_DECLARATION;
}
if (declType == null) { if (declType == null) {
errorAndAdvance("Expecting namespace or top level declaration"); errorAndAdvance("Expecting namespace or top level declaration");
@@ -504,11 +509,10 @@ public class JetParsing extends AbstractJetParsing {
* ; * ;
*/ */
/*package*/ void parseClassBody() { /*package*/ void parseClassBody() {
assert _at(LBRACE);
PsiBuilder.Marker body = mark(); PsiBuilder.Marker body = mark();
myBuilder.enableNewlines(); myBuilder.enableNewlines();
advance(); // LBRACE expect(LBRACE, "Expecting a class body", TokenSet.create(LBRACE));
while (!eof()) { while (!eof()) {
if (at(RBRACE)) { if (at(RBRACE)) {
@@ -536,6 +540,7 @@ public class JetParsing extends AbstractJetParsing {
* : extension * : extension
* : typedef * : typedef
* : anonymousInitializer * : anonymousInitializer
* : object
* ; * ;
*/ */
private void parseMemberDeclaration() { private void parseMemberDeclaration() {
@@ -580,6 +585,10 @@ public class JetParsing extends AbstractJetParsing {
} }
else if (keywordToken == THIS_KEYWORD) { else if (keywordToken == THIS_KEYWORD) {
declType = parseConstructor(); declType = parseConstructor();
}
else if (keywordToken == OBJECT_KEYWORD) {
parseObject(true);
declType = OBJECT_DECLARATION;
} else if (keywordToken == LBRACE) { } else if (keywordToken == LBRACE) {
parseBlock(); parseBlock();
declType = ANONYMOUS_INITIALIZER; declType = ANONYMOUS_INITIALIZER;
@@ -587,6 +596,46 @@ public class JetParsing extends AbstractJetParsing {
return declType; return declType;
} }
/*
* object
* : "object" SimpleName? ":" delegationSpecifier{","}? classBody // Cannot make class body optional: foo(object F, a)
* ;
*/
public void parseObject(boolean declaration) {
assert _at(OBJECT_KEYWORD);
advance(); // OBJECT_KEYWORD
if (declaration) {
expect(IDENTIFIER, "Expecting object name", TokenSet.create(LBRACE));
}
else {
if (at(IDENTIFIER)) {
error("An object expression cannot bind a name");
}
}
if (declaration) { // Body is optional
if (at(COLON)) {
advance(); // COLON
parseDelegationSpecifierList();
}
if (at(LBRACE)) {
parseClassBody();
}
}
else {
if (at(LBRACE)) {
parseClassBody();
}
else {
expect(COLON, "Expecting ':'", TokenSet.create(IDENTIFIER, NAMESPACE_KEYWORD));
parseDelegationSpecifierList();
parseClassBody();
}
}
}
/* /*
* constructor * constructor
* : modifiers "this" functionParameters (":" initializer{","}) block? * : modifiers "this" functionParameters (":" initializer{","}) block?
@@ -0,0 +1,40 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import java.util.Collections;
import java.util.List;
/**
* @author abreslav
*/
public class JetObjectDeclaration extends JetNamedDeclaration implements JetClassOrObject {
public JetObjectDeclaration(@NotNull ASTNode node) {
super(node);
}
@Override
@Nullable
public JetDelegationSpecifierList getDelegationSpecifierList() {
return (JetDelegationSpecifierList) findChildByType(JetNodeTypes.DELEGATION_SPECIFIER_LIST);
}
@Override
@NotNull
public List<JetDelegationSpecifier> getDelegationSpecifiers() {
JetDelegationSpecifierList list = getDelegationSpecifierList();
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
}
@Override
@NotNull
public List<JetDeclaration> getDeclarations() {
JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY);
if (body == null) return Collections.emptyList();
return body.getDeclarations();
}
}
@@ -2,16 +2,12 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.JetNodeTypes;
import java.util.Collections;
import java.util.List;
/** /**
* @author max * @author max
*/ */
public class JetObjectLiteralExpression extends JetExpression implements JetClassOrObject { public class JetObjectLiteralExpression extends JetExpression {
public JetObjectLiteralExpression(@NotNull ASTNode node) { public JetObjectLiteralExpression(@NotNull ASTNode node) {
super(node); super(node);
} }
@@ -21,25 +17,8 @@ public class JetObjectLiteralExpression extends JetExpression implements JetClas
visitor.visitObjectLiteralExpression(this); visitor.visitObjectLiteralExpression(this);
} }
@Override
@Nullable
public JetDelegationSpecifierList getDelegationSpecifierList() {
return (JetDelegationSpecifierList) findChildByType(JetNodeTypes.DELEGATION_SPECIFIER_LIST);
}
@Override
@NotNull @NotNull
public List<JetDelegationSpecifier> getDelegationSpecifiers() { public JetObjectDeclaration getObjectDeclaration() {
JetDelegationSpecifierList list = getDelegationSpecifierList(); return (JetObjectDeclaration) findChildByType(JetNodeTypes.OBJECT_DECLARATION);
return list != null ? list.getDelegationSpecifiers() : Collections.<JetDelegationSpecifier>emptyList();
}
@Override
@NotNull
public List<JetDeclaration> getDeclarations() {
JetClassBody body = (JetClassBody) findChildByType(JetNodeTypes.CLASS_BODY);
if (body == null) return Collections.emptyList();
return body.getDeclarations();
} }
} }
+1
View File
@@ -293,6 +293,7 @@ JetFile: ByCaluses.jet
PsiElement(by)('by') PsiElement(by)('by')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
+16
View File
@@ -172,6 +172,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -186,6 +187,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -200,6 +202,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -223,6 +226,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -258,6 +262,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -291,6 +296,8 @@ JetFile: SimpleClassMembers.jet
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
PsiElement(RPAR)(')') PsiElement(RPAR)(')')
PsiWhiteSpace('\n ') PsiWhiteSpace('\n ')
CLASS_BODY
PsiErrorElement:Expecting a class body
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ') PsiWhiteSpace('\n\n ')
CLASS CLASS
@@ -529,6 +536,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -543,6 +551,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -557,6 +566,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -580,6 +590,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -615,6 +626,7 @@ JetFile: SimpleClassMembers.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -648,4 +660,8 @@ JetFile: SimpleClassMembers.jet
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
PsiElement(RPAR)(')') PsiElement(RPAR)(')')
PsiWhiteSpace('\n\n\n') PsiWhiteSpace('\n\n\n')
CLASS_BODY
PsiErrorElement:Expecting a class body
PsiElement(RBRACE)('}') PsiElement(RBRACE)('}')
PsiErrorElement:Missing '}
<empty list>
+1
View File
@@ -485,6 +485,7 @@ JetFile: SimpleExpressions.jet
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -18,6 +18,7 @@ JetFile: AnonymousObjects.jet
PsiElement(LPAR)('(') PsiElement(LPAR)('(')
VALUE_ARGUMENT VALUE_ARGUMENT
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -155,6 +156,7 @@ JetFile: AnonymousObjects.jet
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -1872,6 +1872,7 @@ JetFile: BinaryTree.jet
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
+1
View File
@@ -9,6 +9,7 @@ JetFile: Builder.jet
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
DOT_QUALIFIED_EXPRESSION DOT_QUALIFIED_EXPRESSION
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -135,6 +135,7 @@ JetFile: PolymorphicClassObjects.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -37,6 +37,7 @@ JetFile: UpdateOperation.jet
PsiElement(class)('class') PsiElement(class)('class')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
CLASS_BODY CLASS_BODY
@@ -140,6 +140,7 @@ JetFile: ArrayList.jet
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')
@@ -225,6 +225,7 @@ JetFile: List.jet
PsiElement(EQ)('=') PsiElement(EQ)('=')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
OBJECT_LITERAL OBJECT_LITERAL
OBJECT_DECLARATION
PsiElement(object)('object') PsiElement(object)('object')
PsiWhiteSpace(' ') PsiWhiteSpace(' ')
PsiElement(COLON)(':') PsiElement(COLON)(':')