f(foo<a, b>(x)) is parsed as a call(call(...))
This commit is contained in:
@@ -58,7 +58,7 @@ elvisOperation
|
|||||||
|
|
||||||
// ATTENTION
|
// ATTENTION
|
||||||
infixFunctionCall
|
infixFunctionCall
|
||||||
: rangeExpression (SimpleName (typeParameters | rangeExpression))*
|
: rangeExpression (SimpleName (typeArguments | rangeExpression))*
|
||||||
;
|
;
|
||||||
|
|
||||||
rangeExpression
|
rangeExpression
|
||||||
@@ -168,7 +168,7 @@ prefixUnaryOperation
|
|||||||
postfixUnaryOperation
|
postfixUnaryOperation
|
||||||
: "++" : "--"
|
: "++" : "--"
|
||||||
: typeArguments? valueArguments
|
: typeArguments? valueArguments
|
||||||
: typeArguments
|
// : typeArguments // TODO:
|
||||||
: arrayAccess
|
: arrayAccess
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,17 @@ import static org.jetbrains.jet.lexer.JetTokens.*;
|
|||||||
*/
|
*/
|
||||||
public class JetExpressionParsing extends AbstractJetParsing {
|
public class JetExpressionParsing extends AbstractJetParsing {
|
||||||
private final JetParsing myJetParsing;
|
private final JetParsing myJetParsing;
|
||||||
|
private static final TokenSet TYPE_ARGUMENT_LIST_STOPPERS = TokenSet.create(
|
||||||
|
INTEGER_LITERAL, LONG_LITERAL, FLOAT_LITERAL, CHARACTER_LITERAL, STRING_LITERAL, RAW_STRING_LITERAL,
|
||||||
|
NAMESPACE_KEYWORD, AS_KEYWORD, TYPE_KEYWORD, CLASS_KEYWORD, THIS_KEYWORD, VAL_KEYWORD, VAR_KEYWORD,
|
||||||
|
FUN_KEYWORD, DECOMPOSER_KEYWORD, EXTENSION_KEYWORD, FOR_KEYWORD, NULL_KEYWORD, TYPEOF_KEYWORD,
|
||||||
|
NEW_KEYWORD, TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD,
|
||||||
|
CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD,
|
||||||
|
MATCH_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, MUL, PLUS, MINUS, EXCL, DIV, PERC, LTEQ,
|
||||||
|
// TODO GTEQ,
|
||||||
|
EQEQEQ, ARROW, DOUBLE_ARROW, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS, QUEST,
|
||||||
|
SEMICOLON, RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, NOT_IN, NOT_IS, HASH, EOL_OR_SEMICOLON
|
||||||
|
);
|
||||||
|
|
||||||
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
|
public JetExpressionParsing(SemanticWhitespaceAwarePsiBuilder builder, JetParsing jetParsing) {
|
||||||
super(builder);
|
super(builder);
|
||||||
@@ -29,7 +40,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
POSTFIX(PLUSPLUS, MINUSMINUS), // valueArguments : arrayAccess
|
POSTFIX(PLUSPLUS, MINUSMINUS), // typeArguments? valueArguments : arrayAccess
|
||||||
|
|
||||||
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // attributes
|
PREFIX(MINUS, PLUS, MINUSMINUS, PLUSPLUS, EXCL) { // attributes
|
||||||
|
|
||||||
@@ -173,6 +184,22 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
} else if (at(LPAR)) {
|
} else if (at(LPAR)) {
|
||||||
parseValueArgumentList();
|
parseValueArgumentList();
|
||||||
expression.done(CALL_EXPRESSION);
|
expression.done(CALL_EXPRESSION);
|
||||||
|
} else if (at(LT)) {
|
||||||
|
// TODO: be more clever: f(foo<a, (a + 1), b>(c)) is not a function call
|
||||||
|
int gtPos = matchTokenStreamPredicate(new FirstBefore(new At(GT), new AtSet(TYPE_ARGUMENT_LIST_STOPPERS, false)) {
|
||||||
|
@Override
|
||||||
|
public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
|
||||||
|
return openAngleBrackets == 1 && openBrackets == 0 && openBraces == 0 && openParentheses == 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (gtPos >= 0) {
|
||||||
|
myJetParsing.parseTypeArgumentList();
|
||||||
|
// if (at(LPAR)) parseValueArgumentList(); TODO : we can do this...
|
||||||
|
parseValueArgumentList();
|
||||||
|
expression.done(CALL_EXPRESSION);
|
||||||
|
} else {
|
||||||
|
expression.drop();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
expression.drop();
|
expression.drop();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1215,7 +1215,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
/*
|
/*
|
||||||
* (optionalProjection type){","}
|
* (optionalProjection type){","}
|
||||||
*/
|
*/
|
||||||
private void parseTypeArgumentList() {
|
public void parseTypeArgumentList() {
|
||||||
if (!at(LT)) return;
|
if (!at(LT)) return;
|
||||||
|
|
||||||
PsiBuilder.Marker list = mark();
|
PsiBuilder.Marker list = mark();
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
|
f(foo<a, (b>(x)))
|
||||||
|
f(foo<a, b>(x))
|
||||||
|
f((foo<a), b>(x))
|
||||||
|
f(foo<a, b)
|
||||||
a + b
|
a + b
|
||||||
a + b * c
|
a + b * c
|
||||||
a + (b * c)
|
a + (b * c)
|
||||||
|
|||||||
@@ -13,6 +13,94 @@ JetFile: Precedence.jet
|
|||||||
BLOCK
|
BLOCK
|
||||||
PsiElement(LBRACE)('{')
|
PsiElement(LBRACE)('{')
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
|
CALL_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('f')
|
||||||
|
VALUE_ARGUMENT_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiElement(COMMA)(',')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
TUPLE
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
TUPLE
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
CALL_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('f')
|
||||||
|
VALUE_ARGUMENT_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
CALL_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
TYPE_ARGUMENT_LIST
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiElement(COMMA)(',')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
TYPE_REFERENCE
|
||||||
|
USER_TYPE
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
VALUE_ARGUMENT_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
CALL_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('f')
|
||||||
|
VALUE_ARGUMENT_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
TUPLE
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(COMMA)(',')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiElement(GT)('>')
|
||||||
|
TUPLE
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
PsiElement(IDENTIFIER)('x')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
|
CALL_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('f')
|
||||||
|
VALUE_ARGUMENT_LIST
|
||||||
|
PsiElement(LPAR)('(')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
BINARY_EXPRESSION
|
||||||
|
PsiElement(IDENTIFIER)('foo')
|
||||||
|
PsiElement(LT)('<')
|
||||||
|
PsiElement(IDENTIFIER)('a')
|
||||||
|
PsiElement(COMMA)(',')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
|
VALUE_ARGUMENT
|
||||||
|
PsiElement(IDENTIFIER)('b')
|
||||||
|
PsiElement(RPAR)(')')
|
||||||
|
PsiWhiteSpace('\n ')
|
||||||
BINARY_EXPRESSION
|
BINARY_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('a')
|
PsiElement(IDENTIFIER)('a')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
|
|||||||
Reference in New Issue
Block a user