From c24c3daf54abf54d45db4674fa0bcdca79444a51 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Wed, 11 Mar 2015 18:59:54 +0300 Subject: [PATCH] Allowed shorthand parameter list with type reference in lambda. --- .../kotlin/parsing/JetExpressionParsing.java | 13 +- compiler/testData/psi/FunctionLiterals.kt | 8 ++ compiler/testData/psi/FunctionLiterals.txt | 134 ++++++++++++++++++ compiler/testData/psi/FunctionLiterals_ERR.kt | 9 +- .../testData/psi/FunctionLiterals_ERR.txt | 104 +++++++++++++- .../SingleLineFunctionLiteral.after.inv.kt | 2 +- .../SingleLineFunctionLiteral.after.kt | 2 +- 7 files changed, 259 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java index 6c6191294d8..2080bd149b6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/parsing/JetExpressionParsing.java @@ -1033,7 +1033,6 @@ public class JetExpressionParsing extends AbstractJetParsing { PsiBuilder.Marker rollbackMarker = mark(); boolean preferParamsToExpressions = (lookahead(1) == COMMA); parseFunctionLiteralShorthandParameterList(); - parseOptionalFunctionLiteralType(); paramsFound = preferParamsToExpressions ? rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : @@ -1112,15 +1111,13 @@ public class JetExpressionParsing extends AbstractJetParsing { expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); + if (at(COLON)) { + advance(); // COLON + myJetParsing.parseTypeRef(TokenSet.create(ARROW, COMMA)); + } parameter.done(VALUE_PARAMETER); - if (at(COLON)) { - PsiBuilder.Marker errorMarker = mark(); - advance(); // COLON - myJetParsing.parseTypeRef(); - errorMarker.error("To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType -> ...}"); - } - else if (at(ARROW)) { + if (at(ARROW)) { break; } else if (at(COMMA)) { diff --git a/compiler/testData/psi/FunctionLiterals.kt b/compiler/testData/psi/FunctionLiterals.kt index 61c6e8e34fe..0db6e14ea3d 100644 --- a/compiler/testData/psi/FunctionLiterals.kt +++ b/compiler/testData/psi/FunctionLiterals.kt @@ -31,4 +31,12 @@ fun foo() { {((a: Int = object { fun t() {} }) -> Int).(x: Int) : String -> "" } { A.B.(x: Int) -> } {((a: Boolean = true) -> Int).(x: Any) : Unit -> } + + {a: b -> f} + {a: b, c -> f} + {a: b, c: d -> f} + {a: (Int) -> Unit, c: (Int) -> Unit -> f} + + //{a: ((Int) -> Unit) ->} todo + //{[a] a: A -> } } diff --git a/compiler/testData/psi/FunctionLiterals.txt b/compiler/testData/psi/FunctionLiterals.txt index 3711819993c..e254d547bc9 100644 --- a/compiler/testData/psi/FunctionLiterals.txt +++ b/compiler/testData/psi/FunctionLiterals.txt @@ -664,5 +664,139 @@ JetFile: FunctionLiterals.kt BLOCK PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('b') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('b') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('b') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('d') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Unit') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Unit') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + PsiComment(EOL_COMMENT)('//{a: ((Int) -> Unit) ->} todo') + PsiWhiteSpace('\n ') + PsiComment(EOL_COMMENT)('//{[a] a: A -> }') PsiWhiteSpace('\n') PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/FunctionLiterals_ERR.kt b/compiler/testData/psi/FunctionLiterals_ERR.kt index 9ae2b150238..a7ca216974b 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.kt +++ b/compiler/testData/psi/FunctionLiterals_ERR.kt @@ -13,7 +13,14 @@ fun foo() { {T.t(a) -> a} {T.t -(a : A) -> a} - {a : b -> f} + {a : b, -> f} + {a : , c -> f} + {a : -> f} + {a, -> f} + + {a : b, } + {a : , } + {T.a : b -> f} {(a, b) } diff --git a/compiler/testData/psi/FunctionLiterals_ERR.txt b/compiler/testData/psi/FunctionLiterals_ERR.txt index 89c5bf11c51..5ad088f2ec9 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.txt +++ b/compiler/testData/psi/FunctionLiterals_ERR.txt @@ -277,14 +277,14 @@ JetFile: FunctionLiterals_ERR.kt VALUE_PARAMETER_LIST VALUE_PARAMETER PsiElement(IDENTIFIER)('a') - PsiWhiteSpace(' ') - PsiErrorElement:To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType -> ...} + PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ') TYPE_REFERENCE USER_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') + PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER PsiErrorElement:Expecting parameter name @@ -296,6 +296,106 @@ JetFile: FunctionLiterals_ERR.kt PsiElement(IDENTIFIER)('f') PsiElement(RBRACE)('}') PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + PsiErrorElement:Type expected + + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + PsiErrorElement:Type expected + + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiErrorElement:Expecting parameter name + + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('f') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + BLOCK + BINARY_WITH_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('b') + PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line) + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + BLOCK + BINARY_WITH_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + PsiErrorElement:Type expected + + PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line) + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL PsiElement(LBRACE)('{') diff --git a/idea/testData/formatter/SingleLineFunctionLiteral.after.inv.kt b/idea/testData/formatter/SingleLineFunctionLiteral.after.inv.kt index ba120739995..54adfac48da 100644 --- a/idea/testData/formatter/SingleLineFunctionLiteral.after.inv.kt +++ b/idea/testData/formatter/SingleLineFunctionLiteral.after.inv.kt @@ -3,7 +3,7 @@ fun test(some: (Int) -> Int) { fun foo() = test() {it} val function = test {(a: Int) -> a} -val function1 = test {a : Int -> a} +val function1 = test {a: Int -> a} val function2 = test { } val function3 = test {} val function4 = test { } diff --git a/idea/testData/formatter/SingleLineFunctionLiteral.after.kt b/idea/testData/formatter/SingleLineFunctionLiteral.after.kt index 230a834d82a..c4bf6358109 100644 --- a/idea/testData/formatter/SingleLineFunctionLiteral.after.kt +++ b/idea/testData/formatter/SingleLineFunctionLiteral.after.kt @@ -3,7 +3,7 @@ fun test(some: (Int) -> Int) { fun foo() = test() { it } val function = test {(a: Int) -> a } -val function1 = test { a : Int -> a } +val function1 = test { a: Int -> a } val function2 = test { } val function3 = test {} val function4 = test { }