Function types

This commit is contained in:
Andrey Breslav
2010-12-16 16:29:08 +03:00
parent 86c59d7530
commit dee94c5e12
9 changed files with 575 additions and 6 deletions
+1 -1
View File
@@ -47,5 +47,5 @@ typeConstraint
;
primaryConstructorParameter
: modifiers ("val" | "var")? parameter // TODO: ref/out?
: modifiers ("val" | "var")? functionParameterRest
;
+5 -1
View File
@@ -54,7 +54,11 @@ functionParameters
;
functionParameter
: modifiers parameter ("=" expression)?
: modifiers functionParameterRest
;
functionParameterRest
: parameter ("=" expression)?
;
initializers
@@ -41,6 +41,7 @@ public interface JetNodeTypes {
JetNodeType TYPE_REFERENCE = new JetNodeType("TYPE_REFERENCE");
JetNodeType LABELED_TUPLE_ENTRY = new JetNodeType("LABELED_TUPLE_ENTRY");
JetNodeType TUPLE_TYPE = new JetNodeType("TUPLE_TYPE");
JetNodeType VALUE_PARAMETER = new JetNodeType("VALUE_PARAMETER");
IElementType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME");
@@ -32,6 +32,7 @@ public class JetParsing {
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);
private final WhitespaceSkippedCallback myWhitespaceSkippedCallback = new WhitespaceSkippedCallback() {
public void onSkip(IElementType type, int start, int end) {
@@ -511,10 +512,18 @@ public class JetParsing {
}
/*
* attributes
* : attributeAnnotation*
* ;
*/
private void parseAttributeList() {
while (at(LBRACKET)) parseAttributeAnnotation();
}
/*
* ("(" primaryConstructorParameter{","} ")")
*/
private void parsePrimaryConstructorParameterList() {
assert at(LPAR);
PsiBuilder.Marker cons = mark();
@@ -531,6 +540,11 @@ public class JetParsing {
cons.done(PRIMARY_CONSTRUCTOR_PARAMETERS_LIST);
}
/*
* primaryConstructorParameter
* : modifiers ("val" | "var")? functionParameterRest
* ;
*/
private void parsePrimaryConstructorParameter() {
PsiBuilder.Marker param = mark();
parseModifierList();
@@ -544,7 +558,12 @@ public class JetParsing {
param.done(PRIMARY_CONSTRUCTOR_PARAMETER);
}
private void parseFunctionParameterRest() {
/*
* functionParameterRest
* : parameter ("=" expression)?
* ;
*/
private boolean parseFunctionParameterRest() {
expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET);
if (at(COLON)) {
@@ -553,12 +572,14 @@ public class JetParsing {
}
else {
error("Parameters must have type annotation");
return false;
}
if (at(EQ)) {
advance(); // EQ
parseExpression();
}
return true;
}
private void parseExpression() {
@@ -707,7 +728,7 @@ public class JetParsing {
parseTypeRef();
labeledEntry.done(LABELED_TUPLE_ENTRY);
}
else if (TokenSet.create(LBRACKET, IDENTIFIER, LBRACE, LPAR).contains(tt())) {
else if (TYPE_REF_FIRST.contains(tt())) {
parseTypeRef();
}
else {
@@ -732,13 +753,57 @@ public class JetParsing {
private void parseSimpleFunctionType() {
assert at(LBRACE);
advance(); // LPAR
advance(); // LBRACE
// TODO
parseFunctionTypeContents();
expect(RBRACE, "Expecting '}");
}
/*
* functionTypeContents
* : "(" (parameter | type){","} ")" ":" type
* ;
*/
private void parseFunctionTypeContents() {
PsiBuilder.Marker parameters = mark();
expect(LPAR, "Expecting '(");
if (!at(RPAR)) {
while (true) {
if (!parseValueParameter()) {
parseTypeRef();
}
if (!at(COMMA)) break;
advance(); // COMMA
}
}
expect(RPAR, "Expecting ')'");
parameters.done(VALUE_PARAMETER_LIST);
expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
parseTypeRef();
}
/*
* functionParameter
* : modifiers functionParameterRest
* ;
*/
private boolean parseValueParameter() {
PsiBuilder.Marker parameter = mark();
parseModifierList();
if (!parseFunctionParameterRest()) {
parameter.rollbackTo();
return false;
}
parameter.done(VALUE_PARAMETER);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+14
View File
@@ -0,0 +1,14 @@
type f = {([a] a) : b}
type f = {(a) : b}
type f = {() : [x] b}
type f = {() : ()}
type f = {(a : [a] a) : b}
type f = {(a : a) : b}
type f = {() : b}
type f = {() : ()}
type f = {(a : [a] a, foo, x : bar) : b}
type f = {(foo, a : a) : b}
type f = {(foo, a : {(a) : b}) : b}
type f = {(foo, a : {(a) : b}) : {() : ()}}
+417
View File
@@ -0,0 +1,417 @@
JetFile: FunctionTypes.jet
NAMESPACE
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('x')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
TUPLE_TYPE
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
TUPLE_TYPE
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('x')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('bar')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('foo')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
TUPLE_TYPE
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiElement(RBRACE)('}')
PsiElement(RBRACE)('}')
+2
View File
@@ -0,0 +1,2 @@
type f = {([a] a) b}
type f = {(a, ) : b}
+64
View File
@@ -0,0 +1,64 @@
JetFile: FunctionTypes_ERR.jet
NAMESPACE
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
ATTRIBUTE_ANNOTATION
PsiElement(LBRACKET)('[')
ATTRIBUTE
USER_TYPE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RBRACKET)(']')
PsiWhiteSpace(' ')
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(RPAR)(')')
PsiErrorElement:Expecting ':' followed by a return type
<empty list>
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
TYPEDEF
PsiElement(type)('type')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('f')
PsiWhiteSpace(' ')
TYPE_PARAMETER_LIST
<empty list>
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiElement(LBRACE)('{')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('a')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_REFERENCE
PsiErrorElement:Type expected
<empty list>
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
PsiElement(IDENTIFIER)('b')
PsiElement(RBRACE)('}')
@@ -42,4 +42,6 @@ public class JetParsingTest extends ParsingTestCase {
public void testTypeAnnotations() throws Exception {doTest(true);}
public void testTupleTypes() throws Exception {doTest(true);}
public void testTupleTypes_ERR() throws Exception {doTest(true);}
public void testFunctionTypes() throws Exception {doTest(true);}
public void testFunctionTypes_ERR() throws Exception {doTest(true);}
}