From da6e1890bdd0fab3f0461461bd6f2f099003e459 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 15 Dec 2014 15:39:40 +0300 Subject: [PATCH] Don't lookahead too far when looking for '.' between type and parameters and for comma in function literal parameters --- .../lang/parsing/JetExpressionParsing.java | 18 +- compiler/testData/psi/FunctionLiterals.kt | 4 + compiler/testData/psi/FunctionLiterals.txt | 172 ++++++++++++++++++ 3 files changed, 192 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 611d0a8895c..2f953fc98cb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -1134,7 +1134,21 @@ public class JetExpressionParsing extends AbstractJetParsing { // it to function params if possible. boolean preferParamsToExpressions = false; - int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR))); + // Last dot before ARROW and RPAR, but also stop at top-level keywords and '{', '}' + int lastDot = matchTokenStreamPredicate(new LastBefore( + new At(DOT), + new AtSet(TokenSet.orSet( + TokenSet.create(ARROW, RPAR), + TokenSet.orSet( + TokenSet.create(LBRACE, RBRACE), + TokenSet.andNot( + KEYWORDS, + TokenSet.create(CAPITALIZED_THIS_KEYWORD) + ) + ) + )) + )); + if (lastDot >= 0) { createTruncatedBuilder(lastDot).parseTypeRef(); if (at(DOT)) { @@ -1187,7 +1201,7 @@ public class JetExpressionParsing extends AbstractJetParsing { if (at(COMMA)) errorAndAdvance("Expecting a parameter declaration"); PsiBuilder.Marker parameter = mark(); - int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, ARROW))); + int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtSet(COMMA, RPAR, COLON, ARROW, RBRACE, LBRACE))); createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, REGULAR_ANNOTATIONS_ONLY_WITH_BRACKETS); expect(IDENTIFIER, "Expecting parameter declaration"); diff --git a/compiler/testData/psi/FunctionLiterals.kt b/compiler/testData/psi/FunctionLiterals.kt index 4c27813eefb..61c6e8e34fe 100644 --- a/compiler/testData/psi/FunctionLiterals.kt +++ b/compiler/testData/psi/FunctionLiterals.kt @@ -27,4 +27,8 @@ fun foo() { {x, y -> 1} {[a] x, [b] y, [c] z -> 1} + + {((a: Int = object { fun t() {} }) -> Int).(x: Int) : String -> "" } + { A.B.(x: Int) -> } + {((a: Boolean = true) -> Int).(x: Any) : Unit -> } } diff --git a/compiler/testData/psi/FunctionLiterals.txt b/compiler/testData/psi/FunctionLiterals.txt index c23682ac634..3711819993c 100644 --- a/compiler/testData/psi/FunctionLiterals.txt +++ b/compiler/testData/psi/FunctionLiterals.txt @@ -492,5 +492,177 @@ JetFile: FunctionLiterals.kt PsiWhiteSpace(' ') PsiElement(INTEGER_LITERAL)('1') PsiElement(RBRACE)('}') + PsiWhiteSpace('\n\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + TYPE_REFERENCE + PsiElement(LPAR)('(') + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + OBJECT_LITERAL + OBJECT_DECLARATION + PsiElement(object)('object') + PsiWhiteSpace(' ') + CLASS_BODY + PsiElement(LBRACE)('{') + PsiWhiteSpace(' ') + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('t') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiElement(RBRACE)('}') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('x') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + STRING_TEMPLATE + PsiElement(OPEN_QUOTE)('"') + PsiElement(CLOSING_QUOTE)('"') + PsiWhiteSpace(' ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(GT)('>') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('x') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + TYPE_REFERENCE + PsiElement(LPAR)('(') + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Boolean') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + BOOLEAN_CONSTANT + PsiElement(true)('true') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(RPAR)(')') + PsiElement(DOT)('.') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('x') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Any') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Unit') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + BLOCK + + PsiElement(RBRACE)('}') PsiWhiteSpace('\n') PsiElement(RBRACE)('}') \ No newline at end of file