Self-types and anonymous initializers

This commit is contained in:
Andrey Breslav
2011-01-05 23:17:10 +03:00
parent 4466d1f08f
commit b84107104c
13 changed files with 767 additions and 527 deletions
+1
View File
@@ -39,6 +39,7 @@ memberDeclaration
: class
: extension
: typedef
: anonymousInitializer
;
classObject
+5 -1
View File
@@ -10,7 +10,11 @@ Foo<Bar<X>, T, Object> // user type
*/
type
: attributes (functionType | userType | tupleType)
: attributes (selfType | functionType | userType | tupleType)
;
selfType
: "This"
;
userType
@@ -107,6 +107,8 @@ public interface JetNodeTypes {
JetNodeType OBJECT_LITERAL = new JetNodeType("OBJECT_LITERAL");
JetNodeType ROOT_NAMESPACE = new JetNodeType("ROOT_NAMESPACE");
JetNodeType FIELD_REFERENCE = new JetNodeType("FIELD_REFERENCE");
JetNodeType SELF_TYPE = new JetNodeType("SELF_TYPE");
JetNodeType ANONYMOUS_INITIALIZER = new JetNodeType("ANONYMOUS_INITIALIZER");
IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME");
@@ -537,7 +537,6 @@ public class JetParsing extends AbstractJetParsing {
* ;
*/
/*package*/ void parseClassBody() {
// TODO : anonymous initializer, like {...} in Java?
assert _at(LBRACE);
PsiBuilder.Marker body = mark();
@@ -558,6 +557,10 @@ public class JetParsing extends AbstractJetParsing {
/*
* memberDeclaration
* : modifiers memberDeclaration'
* ;
*
* memberDeclaration'
* : classObject
* : constructor
* : decomposer
@@ -566,6 +569,7 @@ public class JetParsing extends AbstractJetParsing {
* : class
* : extension
* : typedef
* : anonymousInitializer
* ;
*/
private void parseMemberDeclaration() {
@@ -613,6 +617,9 @@ public class JetParsing extends AbstractJetParsing {
}
else if (keywordToken == THIS_KEYWORD) {
declType = parseConstructor();
} else if (keywordToken == LBRACE) {
parseBlock();
declType = ANONYMOUS_INITIALIZER;
}
return declType;
}
@@ -1203,11 +1210,10 @@ public class JetParsing extends AbstractJetParsing {
/*
* type
* : attributes (functionType | userType | tupleType)
* : attributes (selfType | functionType | userType | tupleType)
* ;
*/
public void parseTypeRef() {
// TODO: Self type
PsiBuilder.Marker type = mark();
parseAttributeList();
@@ -1221,6 +1227,9 @@ public class JetParsing extends AbstractJetParsing {
else if (at(LPAR)) {
parseTupleType();
}
else if (at(CAPITALIZED_THIS_KEYWORD)) {
parseSelfType();
}
else {
errorWithRecovery("Type expected",
TokenSet.orSet(TOPLEVEL_OBJECT_FIRST,
@@ -1229,6 +1238,19 @@ public class JetParsing extends AbstractJetParsing {
type.done(TYPE_REFERENCE);
}
/*
* selfType
* : "This"
* ;
*/
private void parseSelfType() {
assert _at(CAPITALIZED_THIS_KEYWORD);
PsiBuilder.Marker type = mark();
advance(); // CAPITALIZED_THIS_KEYWORD
type.done(SELF_TYPE);
}
/*
* userType
* : ("namespace" ".")? simpleUserType{"."}
@@ -102,6 +102,7 @@ RAW_STRING_LITERAL = {THREE_QUO} {QUO_STRING_CHAR}* {THREE_QUO}?
<YYINITIAL> "this" { return JetTokens.THIS_KEYWORD ;}
<YYINITIAL> "null" { return JetTokens.NULL_KEYWORD ;}
<YYINITIAL> "else" { return JetTokens.ELSE_KEYWORD ;}
<YYINITIAL> "This" { return JetTokens.CAPITALIZED_THIS_KEYWORD ;}
<YYINITIAL> "try" { return JetTokens.TRY_KEYWORD ;}
<YYINITIAL> "val" { return JetTokens.VAL_KEYWORD ;}
<YYINITIAL> "var" { return JetTokens.VAR_KEYWORD ;}
+33 -31
View File
@@ -23,36 +23,38 @@ public interface JetTokens {
JetToken STRING_LITERAL = new JetToken("STRING_LITERAL");
JetToken RAW_STRING_LITERAL = new JetToken("RAW_STRING_LITERAL");
JetKeywordToken NAMESPACE_KEYWORD = JetKeywordToken.keyword("namespace");
JetKeywordToken AS_KEYWORD = JetKeywordToken.keyword("as");
JetKeywordToken TYPE_KEYWORD = JetKeywordToken.keyword("type");
JetKeywordToken CLASS_KEYWORD = JetKeywordToken.keyword("class");
JetKeywordToken THIS_KEYWORD = JetKeywordToken.keyword("this");
JetKeywordToken VAL_KEYWORD = JetKeywordToken.keyword("val");
JetKeywordToken VAR_KEYWORD = JetKeywordToken.keyword("var");
JetKeywordToken FUN_KEYWORD = JetKeywordToken.keyword("fun");
JetKeywordToken DECOMPOSER_KEYWORD = JetKeywordToken.keyword("decomposer");
JetKeywordToken EXTENSION_KEYWORD = JetKeywordToken.keyword("extension");
JetKeywordToken FOR_KEYWORD = JetKeywordToken.keyword("for");
JetKeywordToken NULL_KEYWORD = JetKeywordToken.keyword("null");
JetKeywordToken TYPEOF_KEYWORD = JetKeywordToken.keyword("typeof");
JetKeywordToken NEW_KEYWORD = JetKeywordToken.keyword("new");
JetKeywordToken TRUE_KEYWORD = JetKeywordToken.keyword("true");
JetKeywordToken FALSE_KEYWORD = JetKeywordToken.keyword("false");
JetKeywordToken IS_KEYWORD = JetKeywordToken.keyword("is");
JetKeywordToken IN_KEYWORD = JetKeywordToken.keyword("in");
JetKeywordToken THROW_KEYWORD = JetKeywordToken.keyword("throw");
JetKeywordToken RETURN_KEYWORD = JetKeywordToken.keyword("return");
JetKeywordToken BREAK_KEYWORD = JetKeywordToken.keyword("break");
JetKeywordToken CONTINUE_KEYWORD = JetKeywordToken.keyword("continue");
JetKeywordToken OBJECT_KEYWORD = JetKeywordToken.keyword("object");
JetKeywordToken IF_KEYWORD = JetKeywordToken.keyword("if");
JetKeywordToken TRY_KEYWORD = JetKeywordToken.keyword("try");
JetKeywordToken ELSE_KEYWORD = JetKeywordToken.keyword("else");
JetKeywordToken WHILE_KEYWORD = JetKeywordToken.keyword("while");
JetKeywordToken DO_KEYWORD = JetKeywordToken.keyword("do");
JetKeywordToken MATCH_KEYWORD = JetKeywordToken.keyword("match");
JetKeywordToken CASE_KEYWORD = JetKeywordToken.keyword("case");
JetKeywordToken NAMESPACE_KEYWORD = JetKeywordToken.keyword("namespace");
JetKeywordToken AS_KEYWORD = JetKeywordToken.keyword("as");
JetKeywordToken TYPE_KEYWORD = JetKeywordToken.keyword("type");
JetKeywordToken CLASS_KEYWORD = JetKeywordToken.keyword("class");
JetKeywordToken THIS_KEYWORD = JetKeywordToken.keyword("this");
JetKeywordToken VAL_KEYWORD = JetKeywordToken.keyword("val");
JetKeywordToken VAR_KEYWORD = JetKeywordToken.keyword("var");
JetKeywordToken FUN_KEYWORD = JetKeywordToken.keyword("fun");
JetKeywordToken DECOMPOSER_KEYWORD = JetKeywordToken.keyword("decomposer");
JetKeywordToken EXTENSION_KEYWORD = JetKeywordToken.keyword("extension");
JetKeywordToken FOR_KEYWORD = JetKeywordToken.keyword("for");
JetKeywordToken NULL_KEYWORD = JetKeywordToken.keyword("null");
JetKeywordToken TYPEOF_KEYWORD = JetKeywordToken.keyword("typeof");
JetKeywordToken NEW_KEYWORD = JetKeywordToken.keyword("new");
JetKeywordToken TRUE_KEYWORD = JetKeywordToken.keyword("true");
JetKeywordToken FALSE_KEYWORD = JetKeywordToken.keyword("false");
JetKeywordToken IS_KEYWORD = JetKeywordToken.keyword("is");
JetKeywordToken IN_KEYWORD = JetKeywordToken.keyword("in");
JetKeywordToken THROW_KEYWORD = JetKeywordToken.keyword("throw");
JetKeywordToken RETURN_KEYWORD = JetKeywordToken.keyword("return");
JetKeywordToken BREAK_KEYWORD = JetKeywordToken.keyword("break");
JetKeywordToken CONTINUE_KEYWORD = JetKeywordToken.keyword("continue");
JetKeywordToken OBJECT_KEYWORD = JetKeywordToken.keyword("object");
JetKeywordToken IF_KEYWORD = JetKeywordToken.keyword("if");
JetKeywordToken TRY_KEYWORD = JetKeywordToken.keyword("try");
JetKeywordToken ELSE_KEYWORD = JetKeywordToken.keyword("else");
JetKeywordToken WHILE_KEYWORD = JetKeywordToken.keyword("while");
JetKeywordToken DO_KEYWORD = JetKeywordToken.keyword("do");
JetKeywordToken MATCH_KEYWORD = JetKeywordToken.keyword("match");
JetKeywordToken CASE_KEYWORD = JetKeywordToken.keyword("case");
// TODO: Discuss "This" keyword
JetKeywordToken CAPITALIZED_THIS_KEYWORD = JetKeywordToken.keyword("This");
JetToken IDENTIFIER = new JetToken("IDENTIFIER");
@@ -135,7 +137,7 @@ public interface JetTokens {
NULL_KEYWORD, TYPEOF_KEYWORD, NEW_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD,
IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD,
ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, MATCH_KEYWORD, TRY_KEYWORD, CASE_KEYWORD,
NOT_IN, NOT_IS
NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD
);
TokenSet SOFT_KEYWORDS = TokenSet.create(WRAPS_KEYWORD, IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, LAZY_KEYWORD, GET_KEYWORD,
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
class Foo {
{
foo()
val c = f
}
this() {
}
}
@@ -0,0 +1,45 @@
JetFile: AnonymousInitializer.jet
NAMESPACE
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Foo')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n\n ')
ANONYMOUS_INITIALIZER
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('foo')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('c')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n ')
CONSTRUCTOR
PsiElement(this)('this')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+6
View File
@@ -0,0 +1,6 @@
class Foo<T : List<This>>(a : This, b : bar<This>) : List<This> by foo as List<This> {
fun foo(a : This) : This {
val a : This = new Foo<This>();
}
}
+144
View File
@@ -0,0 +1,144 @@
JetFile: ThisType.jet
NAMESPACE
CLASS
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('Foo')
TYPE_PARAMETER_LIST
PsiElement(LT)('<')
TYPE_PARAMETER
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('List')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
PsiElement(GT)('>')
PRIMARY_CONSTRUCTOR_PARAMETERS_LIST
PsiElement(LPAR)('(')
PRIMARY_CONSTRUCTOR_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
PRIMARY_CONSTRUCTOR_PARAMETER
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('bar')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
DELEGATOR_BY
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('List')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
PsiElement(by)('by')
PsiWhiteSpace(' ')
BINARY_EXPRESSION
PsiElement(IDENTIFIER)('foo')
PsiWhiteSpace(' ')
PsiElement(as)('as')
PsiWhiteSpace(' ')
CALL_EXPRESSION
PsiElement(IDENTIFIER)('List')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
CLASS_BODY
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('foo')
TYPE_PARAMETER_LIST
<empty list>
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
NEW
PsiElement(new)('new')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('Foo')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(SEMICOLON)(';')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
+3 -3
View File
@@ -21,9 +21,9 @@ fun countOnes(x : INumber) = if (x == 0) 0 else mostSignificantBit(x) + countOne
fun Int.matchMask(mask : Int) = this and mask == mask
virtual class INumber<T : this> : IComparable<T> {
virtual class INumber : IComparable<This> {
val bits : Int
[operator] fun plus(other : T) : T
[operator] fun shl(bits : Int) : T
[operator] fun plus(other : This) : This
[operator] fun shl(bits : Int) : This
// ...
}
+10 -19
View File
@@ -468,18 +468,9 @@ JetFile: BitArith.jet
PsiElement(class)('class')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('INumber')
TYPE_PARAMETER_LIST
PsiElement(LT)('<')
TYPE_PARAMETER
PsiElement(IDENTIFIER)('T')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiErrorElement:Type expected
PsiElement(this)('this')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
DELEGATION_SPECIFIER_LIST
@@ -490,8 +481,8 @@ JetFile: BitArith.jet
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
SELF_TYPE
PsiElement(This)('This')
PsiElement(GT)('>')
PsiWhiteSpace(' ')
CLASS_BODY
@@ -530,15 +521,15 @@ JetFile: BitArith.jet
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
SELF_TYPE
PsiElement(This)('This')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
SELF_TYPE
PsiElement(This)('This')
PsiWhiteSpace('\n ')
FUN
MODIFIER_LIST
@@ -569,8 +560,8 @@ JetFile: BitArith.jet
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('T')
SELF_TYPE
PsiElement(This)('This')
PsiWhiteSpace('\n ')
PsiComment(EOL_COMMENT)('// ...')
PsiWhiteSpace('\n')