KT-1630 Do not select automatically completion proposal in definition of lambda parameters
#KT-1630 fixed
This commit is contained in:
@@ -1128,27 +1128,20 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
// {(a, b) -> ...}
|
||||
|
||||
{
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
boolean preferParamsToExpressions = isConfirmedParametersByComma();
|
||||
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
parseFunctionLiteralParametersAndType();
|
||||
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
paramsFound = preferParamsToExpressions ?
|
||||
rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
|
||||
rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
|
||||
if (!paramsFound) {
|
||||
// If not found, try a typeRef DOT and then LPAR .. RPAR ARROW
|
||||
// {((A) -> B).(x) -> ... }
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR)));
|
||||
if (lastDot >= 0) {
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
parseFunctionLiteralParametersAndType();
|
||||
}
|
||||
}
|
||||
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
paramsFound = parseFunctionTypeDotParametersAndType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1157,69 +1150,21 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
// {a -> ...}
|
||||
// {a, b -> ...}
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
boolean preferParamsToExpressions = (lookahead(1) == COMMA);
|
||||
parseFunctionLiteralShorthandParameterList();
|
||||
parseOptionalFunctionLiteralType();
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
|
||||
paramsFound = preferParamsToExpressions ?
|
||||
rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
|
||||
rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
if (!paramsFound && atSet(JetParsing.TYPE_REF_FIRST)) {
|
||||
// Try to parse a type DOT valueParameterList ARROW
|
||||
// {A.(b) -> ...}
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RBRACE)));
|
||||
if (lastDot >= 0) { // There is a receiver type
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
}
|
||||
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
parseFunctionLiteralParametersAndType();
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
else {
|
||||
rollbackMarker.rollbackTo();
|
||||
}
|
||||
paramsFound = parseFunctionTypeDotParametersAndType();
|
||||
}
|
||||
// int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(ARROW), new At(RBRACE)) {
|
||||
// @Override
|
||||
// public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
|
||||
// return openBraces == 0;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// boolean doubleArrowPresent = doubleArrowPos >= 0;
|
||||
// if (doubleArrowPresent) {
|
||||
// boolean dontExpectParameters = false;
|
||||
//
|
||||
// int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtOffset(doubleArrowPos)));
|
||||
// if (lastDot >= 0) { // There is a receiver type
|
||||
// createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
//
|
||||
// expect(DOT, "Expecting '.'");
|
||||
//
|
||||
// if (!at(LPAR)) {
|
||||
// int firstLParPos = matchTokenStreamPredicate(new FirstBefore(new At(LPAR), new AtOffset(doubleArrowPos)));
|
||||
//
|
||||
// if (firstLParPos >= 0) {
|
||||
// errorUntilOffset("Expecting '('", firstLParPos);
|
||||
// } else {
|
||||
// errorUntilOffset("To specify a receiver type, use the full notation: {ReceiverType.(parameters) [: ReturnType] -> ...}",
|
||||
// doubleArrowPos);
|
||||
// dontExpectParameters = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (at(LPAR)) {
|
||||
// parseFunctionLiteralParametersAndType();
|
||||
// }
|
||||
// else if (!dontExpectParameters) {
|
||||
// parseFunctionLiteralShorthandParameterList();
|
||||
// }
|
||||
//
|
||||
// expectNoAdvance(ARROW, "Expecting '->'");
|
||||
// }
|
||||
}
|
||||
|
||||
if (!paramsFound) {
|
||||
if (preferBlock) {
|
||||
literal.drop();
|
||||
@@ -1231,6 +1176,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiBuilder.Marker body = mark();
|
||||
parseStatements();
|
||||
body.done(BLOCK);
|
||||
@@ -1252,6 +1198,25 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker,
|
||||
JetToken expected, String expectMessage,
|
||||
IElementType validForDrop) {
|
||||
if (at(expected)) {
|
||||
advance(); // dropAt
|
||||
rollbackMarker.drop();
|
||||
return true;
|
||||
}
|
||||
else if (at(validForDrop)) {
|
||||
rollbackMarker.drop();
|
||||
expect(expected, expectMessage);
|
||||
return true;
|
||||
}
|
||||
|
||||
rollbackMarker.rollbackTo();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* SimpleName{,}
|
||||
*/
|
||||
@@ -1289,9 +1254,45 @@ 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();
|
||||
|
||||
// True when it's confirmed that body of literal can't be simple expressions and we prefer to parse
|
||||
// it to function params if possible.
|
||||
boolean preferParamsToExpressions = false;
|
||||
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR)));
|
||||
if (lastDot >= 0) {
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
|
||||
if (at(LPAR)) {
|
||||
preferParamsToExpressions = isConfirmedParametersByComma();
|
||||
}
|
||||
|
||||
parseFunctionLiteralParametersAndType();
|
||||
}
|
||||
}
|
||||
|
||||
return preferParamsToExpressions ?
|
||||
rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) :
|
||||
rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
|
||||
private void parseFunctionLiteralParametersAndType() {
|
||||
parseFunctionLiteralParameterList();
|
||||
|
||||
parseOptionalFunctionLiteralType();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,4 +15,8 @@ fun foo() {
|
||||
|
||||
{a : b -> f}
|
||||
{T.a : b -> f}
|
||||
|
||||
{(a, b) }
|
||||
{T.(a, b) }
|
||||
{a, }
|
||||
}
|
||||
@@ -326,7 +326,66 @@ JetFile: FunctionLiterals_ERR.jet
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('f')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiErrorElement:Expecting '}'
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n\n ')
|
||||
FUNCTION_LITERAL_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:An -> is expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
<empty list>
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FUNCTION_LITERAL_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('T')
|
||||
PsiElement(DOT)('.')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('a')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_PARAMETER
|
||||
PsiElement(IDENTIFIER)('b')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:An -> is expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
<empty list>
|
||||
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(RBRACE)('}')
|
||||
PsiErrorElement:Expecting '->' or ','
|
||||
<empty list>
|
||||
PsiWhiteSpace('\n')
|
||||
BLOCK
|
||||
<empty list>
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiErrorElement:Expecting '}'
|
||||
<empty list>
|
||||
Reference in New Issue
Block a user