From dee94c5e12a24a26d183146c48d28fb647c6502b Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 16 Dec 2010 16:29:08 +0300 Subject: [PATCH] Function types --- grammar/src/class.grm | 2 +- grammar/src/class_members.grm | 6 +- idea/src/org/jetbrains/jet/JetNodeTypes.java | 1 + .../jet/lang/parsing/JetParsing.java | 73 ++- idea/testData/psi/FunctionTypes.jet | 14 + idea/testData/psi/FunctionTypes.txt | 417 ++++++++++++++++++ idea/testData/psi/FunctionTypes_ERR.jet | 2 + idea/testData/psi/FunctionTypes_ERR.txt | 64 +++ .../jetbrains/jet/parsing/JetParsingTest.java | 2 + 9 files changed, 575 insertions(+), 6 deletions(-) create mode 100644 idea/testData/psi/FunctionTypes.jet create mode 100644 idea/testData/psi/FunctionTypes.txt create mode 100644 idea/testData/psi/FunctionTypes_ERR.jet create mode 100644 idea/testData/psi/FunctionTypes_ERR.txt diff --git a/grammar/src/class.grm b/grammar/src/class.grm index 9abb98c5a1a..fbb49cfdcce 100644 --- a/grammar/src/class.grm +++ b/grammar/src/class.grm @@ -47,5 +47,5 @@ typeConstraint ; primaryConstructorParameter - : modifiers ("val" | "var")? parameter // TODO: ref/out? + : modifiers ("val" | "var")? functionParameterRest ; \ No newline at end of file diff --git a/grammar/src/class_members.grm b/grammar/src/class_members.grm index 143c9243f0f..e83585b7edf 100644 --- a/grammar/src/class_members.grm +++ b/grammar/src/class_members.grm @@ -54,7 +54,11 @@ functionParameters ; functionParameter - : modifiers parameter ("=" expression)? + : modifiers functionParameterRest + ; + +functionParameterRest + : parameter ("=" expression)? ; initializers diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 408227f6054..77e62b96a38 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -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"); diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 57142c60668..62199f949af 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -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; + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/idea/testData/psi/FunctionTypes.jet b/idea/testData/psi/FunctionTypes.jet new file mode 100644 index 00000000000..ae37a029419 --- /dev/null +++ b/idea/testData/psi/FunctionTypes.jet @@ -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}) : {() : ()}} diff --git a/idea/testData/psi/FunctionTypes.txt b/idea/testData/psi/FunctionTypes.txt new file mode 100644 index 00000000000..0426efe3d23 --- /dev/null +++ b/idea/testData/psi/FunctionTypes.txt @@ -0,0 +1,417 @@ +JetFile: FunctionTypes.jet + NAMESPACE + TYPEDEF + PsiElement(type)('type') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('f') + PsiWhiteSpace(' ') + TYPE_PARAMETER_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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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 + + 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)('}') \ No newline at end of file diff --git a/idea/testData/psi/FunctionTypes_ERR.jet b/idea/testData/psi/FunctionTypes_ERR.jet new file mode 100644 index 00000000000..9aa7318d4a2 --- /dev/null +++ b/idea/testData/psi/FunctionTypes_ERR.jet @@ -0,0 +1,2 @@ +type f = {([a] a) b} +type f = {(a, ) : b} diff --git a/idea/testData/psi/FunctionTypes_ERR.txt b/idea/testData/psi/FunctionTypes_ERR.txt new file mode 100644 index 00000000000..9a7fffd7b32 --- /dev/null +++ b/idea/testData/psi/FunctionTypes_ERR.txt @@ -0,0 +1,64 @@ +JetFile: FunctionTypes_ERR.jet + NAMESPACE + TYPEDEF + PsiElement(type)('type') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('f') + PsiWhiteSpace(' ') + TYPE_PARAMETER_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 + + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('b') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n') + TYPEDEF + PsiElement(type)('type') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('f') + PsiWhiteSpace(' ') + TYPE_PARAMETER_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 + + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('b') + 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 e8cb4e9ba31..f21f5a94fc3 100644 --- a/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java +++ b/idea/tests/org/jetbrains/jet/parsing/JetParsingTest.java @@ -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);} }