From 421bb57f50157dcf578ff179a87acb5ba837147c Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 15 Dec 2014 14:58:43 +0300 Subject: [PATCH] Fix parser performance: don't do the additional lookahead when looking for the comma in parameters --- .../lang/parsing/JetExpressionParsing.java | 39 +++++++------------ compiler/testData/psi/FunctionLiterals_ERR.kt | 1 + .../testData/psi/FunctionLiterals_ERR.txt | 24 ++++++++++++ 3 files changed, 40 insertions(+), 24 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 0829a3e9cd4..611d0a8895c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -1003,10 +1003,8 @@ public class JetExpressionParsing extends AbstractJetParsing { // {(a, b) -> ...} { - boolean preferParamsToExpressions = isConfirmedParametersByComma(); - PsiBuilder.Marker rollbackMarker = mark(); - parseFunctionLiteralParametersAndType(); + boolean preferParamsToExpressions = parseFunctionLiteralParametersAndType(); paramsFound = preferParamsToExpressions ? rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : @@ -1129,17 +1127,6 @@ public class JetExpressionParsing extends AbstractJetParsing { parameterList.done(VALUE_PARAMETER_LIST); } - // Check that position is followed by top level comma. It can't be expression and we want it be - // parsed as parameters in function literal - private boolean isConfirmedParametersByComma() { - assert _at(LPAR); - PsiBuilder.Marker lparMarker = mark(); - advance(); // LPAR - int comma = matchTokenStreamPredicate(new FirstBefore(new At(COMMA), new AtSet(ARROW, RPAR))); - lparMarker.rollbackTo(); - return comma > 0; - } - private boolean parseFunctionTypeDotParametersAndType() { PsiBuilder.Marker rollbackMarker = mark(); @@ -1152,12 +1139,7 @@ public class JetExpressionParsing extends AbstractJetParsing { createTruncatedBuilder(lastDot).parseTypeRef(); if (at(DOT)) { advance(); // DOT - - if (at(LPAR)) { - preferParamsToExpressions = isConfirmedParametersByComma(); - } - - parseFunctionLiteralParametersAndType(); + preferParamsToExpressions = parseFunctionLiteralParametersAndType(); } } @@ -1166,9 +1148,10 @@ public class JetExpressionParsing extends AbstractJetParsing { rollbackOrDropAt(rollbackMarker, ARROW); } - private void parseFunctionLiteralParametersAndType() { - parseFunctionLiteralParameterList(); + private boolean parseFunctionLiteralParametersAndType() { + boolean hasCommaInParametersList = parseFunctionLiteralParameterList(); parseOptionalFunctionLiteralType(); + return hasCommaInParametersList; } /* @@ -1186,13 +1169,17 @@ public class JetExpressionParsing extends AbstractJetParsing { } } - /* + /** * "(" (modifiers SimpleName (":" type)?){","} ")" + * + * @return true if at least one comma was found */ - private void parseFunctionLiteralParameterList() { + private boolean parseFunctionLiteralParameterList() { PsiBuilder.Marker list = mark(); expect(LPAR, "Expecting a parameter list in parentheses (...)", TokenSet.create(ARROW, COLON)); + boolean hasComma = false; + myBuilder.disableNewlines(); if (!at(RPAR)) { @@ -1213,6 +1200,8 @@ public class JetExpressionParsing extends AbstractJetParsing { if (!at(COMMA)) break; advance(); // COMMA + hasComma = true; + if (at(RPAR)) { error("Expecting a parameter declaration"); break; @@ -1224,6 +1213,8 @@ public class JetExpressionParsing extends AbstractJetParsing { expect(RPAR, "Expecting ')'", TokenSet.create(ARROW, COLON)); list.done(VALUE_PARAMETER_LIST); + + return hasComma; } /* diff --git a/compiler/testData/psi/FunctionLiterals_ERR.kt b/compiler/testData/psi/FunctionLiterals_ERR.kt index e3d82032282..9ae2b150238 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.kt +++ b/compiler/testData/psi/FunctionLiterals_ERR.kt @@ -18,5 +18,6 @@ fun foo() { {(a, b) } {T.(a, b) } + {(a: Int, )} {a, } } \ No newline at end of file diff --git a/compiler/testData/psi/FunctionLiterals_ERR.txt b/compiler/testData/psi/FunctionLiterals_ERR.txt index 1826a83f59b..89c5bf11c51 100644 --- a/compiler/testData/psi/FunctionLiterals_ERR.txt +++ b/compiler/testData/psi/FunctionLiterals_ERR.txt @@ -370,6 +370,30 @@ JetFile: FunctionLiterals_ERR.kt PsiElement(RBRACE)('}') PsiWhiteSpace('\n ') + FUNCTION_LITERAL_EXPRESSION + FUNCTION_LITERAL + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(COMMA)(',') + PsiErrorElement:Expecting a parameter declaration + + PsiWhiteSpace(' ') + PsiElement(RPAR)(')') + PsiErrorElement:An -> is expected + + BLOCK + + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') FUNCTION_LITERAL_EXPRESSION FUNCTION_LITERAL PsiElement(LBRACE)('{')