Fix parser performance: don't do the additional lookahead when looking for the comma in parameters

This commit is contained in:
Nikolay Krasko
2014-12-15 14:58:43 +03:00
parent ba849b5940
commit 421bb57f50
3 changed files with 40 additions and 24 deletions
@@ -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;
}
/*
@@ -18,5 +18,6 @@ fun foo() {
{(a, b) }
{T.(a, b) }
{(a: Int, )}
{a, }
}
@@ -370,6 +370,30 @@ JetFile: FunctionLiterals_ERR.kt
<empty list>
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
<empty list>
PsiWhiteSpace(' ')
PsiElement(RPAR)(')')
PsiErrorElement:An -> is expected
<empty list>
BLOCK
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n ')
FUNCTION_LITERAL_EXPRESSION
FUNCTION_LITERAL
PsiElement(LBRACE)('{')