From 55ca4e8a5a3f734d56124da6010374765453aa66 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 14 Jan 2011 21:24:46 +0300 Subject: [PATCH] Allow type parameters right after fun, val, var --- grammar/src/class_members.grm | 11 +- .../jet/lang/parsing/JetParsing.java | 25 ++- .../testData/psi/TypeParametersBeforeName.jet | 7 + .../testData/psi/TypeParametersBeforeName.txt | 165 ++++++++++++++++++ 4 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 idea/testData/psi/TypeParametersBeforeName.jet create mode 100644 idea/testData/psi/TypeParametersBeforeName.txt diff --git a/grammar/src/class_members.grm b/grammar/src/class_members.grm index 3b45fea8ea0..eec94bee2de 100644 --- a/grammar/src/class_members.grm +++ b/grammar/src/class_members.grm @@ -71,7 +71,11 @@ block ; function - : modifiers "fun" (type ".")? attributes/*for receiver type*/ typeParameters? functionParameters (":" type)? functionBody? + : modifiers "fun" typeParameters? + (type "." | attributes/*for receiver type*/)? + SimpleName + typeParameters? functionParameters (":" type)? + functionBody? ; functionBody @@ -80,7 +84,10 @@ functionBody ; property - : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression SEMI?)? + : modifiers ("val" | "var") + typeParameters? (type "." | attributes)? + SimpleName (":" type)? + ("=" expression SEMI?)? (getter? setter? | setter? getter?) SEMI? ; diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 8cc26a42356..9017a295662 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -672,7 +672,10 @@ public class JetParsing extends AbstractJetParsing { /* * property - * : modifiers ("val" | "var") attributes (type ".")? SimpleName (":" type)? ("=" expression SEMI?)? + * : modifiers ("val" | "var") + * typeParameters? (type "." | attributes)? + * SimpleName (":" type)? + * ("=" expression SEMI?)? * (getter? setter? | setter? getter?) SEMI? * ; */ @@ -681,14 +684,16 @@ public class JetParsing extends AbstractJetParsing { } public JetNodeType parseProperty(boolean local) { - // TODO: how to write an extension ptoperty for a generic type? (val List.i -- what is T?!) - if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) { advance(); // VAL_KEYWORD or VAR_KEYWORD } else { errorAndAdvance("Expecting 'val' or 'var'"); } + if (at(LT)) { + parseTypeParameterList(TokenSet.create(IDENTIFIER, EQ, COLON, SEMICOLON)); + } + TokenSet propertyNameFollow = TokenSet.create(COLON, EQ, LBRACE, SEMICOLON); // TODO: extract constant @@ -805,11 +810,11 @@ public class JetParsing extends AbstractJetParsing { /* * function - * : modifiers "fun" (type ".")? functionRest - * ; - * - * functionRest - * : attributes SimpleName typeParameters? functionParameters (":" type)? functionBody? + * : modifiers "fun" typeParameters? + * (type "." | attributes)? + * SimpleName + * typeParameters? functionParameters (":" type)? + * functionBody? * ; */ public JetNodeType parseFunction() { @@ -817,6 +822,10 @@ public class JetParsing extends AbstractJetParsing { advance(); // FUN_KEYWORD + if (at(LT)) { + parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR)); + } + int lastDot = findLastBefore(TokenSet.create(DOT), TokenSet.create(LPAR), true); if (lastDot == -1) { // There's no explicit receiver type specified diff --git a/idea/testData/psi/TypeParametersBeforeName.jet b/idea/testData/psi/TypeParametersBeforeName.jet new file mode 100644 index 00000000000..93cafe82b55 --- /dev/null +++ b/idea/testData/psi/TypeParametersBeforeName.jet @@ -0,0 +1,7 @@ +fun foo() +fun [a] foo() +fun [a] T.foo() +fun [a] {() : Unit}.foo() + +val List.foo +var List.foo \ No newline at end of file diff --git a/idea/testData/psi/TypeParametersBeforeName.txt b/idea/testData/psi/TypeParametersBeforeName.txt new file mode 100644 index 00000000000..9e15d9ea36c --- /dev/null +++ b/idea/testData/psi/TypeParametersBeforeName.txt @@ -0,0 +1,165 @@ +JetFile: TypeParametersBeforeName.jet + NAMESPACE + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + TYPE_PARAMETER_LIST + + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + ATTRIBUTE_ANNOTATION + PsiElement(LBRACKET)('[') + ATTRIBUTE + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + TYPE_PARAMETER_LIST + + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + TYPE_REFERENCE + ATTRIBUTE_ANNOTATION + PsiElement(LBRACKET)('[') + ATTRIBUTE + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('foo') + TYPE_PARAMETER_LIST + + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + TYPE_REFERENCE + ATTRIBUTE_ANNOTATION + PsiElement(LBRACKET)('[') + ATTRIBUTE + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + FUNCTION_TYPE + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Unit') + PsiElement(RBRACE)('}') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('foo') + TYPE_PARAMETER_LIST + + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n\n') + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + PsiElement(GT)('>') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('foo') + PsiWhiteSpace('\n') + PROPERTY + PsiElement(var)('var') + PsiWhiteSpace(' ') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('A') + PsiElement(GT)('>') + PsiWhiteSpace(' ') + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('List') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + PsiElement(GT)('>') + PsiElement(DOT)('.') + PsiElement(IDENTIFIER)('foo') \ No newline at end of file