Parse simple callable reference expressions

#KT-1183 In Progress
This commit is contained in:
Alexander Udalov
2013-03-18 15:33:48 +04:00
parent a6e242d166
commit dac0d77e90
5 changed files with 578 additions and 13 deletions
@@ -343,7 +343,36 @@ public class JetExpressionParsing extends AbstractJetParsing {
}
/*
* atomicExpression postfixUnaryOperation?
* callableReference
* : userType? "::" SimpleName
* ;
*/
private boolean parseCallableReferenceExpression() {
PsiBuilder.Marker expression = mark();
if (!at(COLONCOLON)) {
PsiBuilder.Marker typeReference = mark();
myJetParsing.parseUserType();
typeReference.done(TYPE_REFERENCE);
if (!at(COLONCOLON)) {
expression.rollbackTo();
return false;
}
}
advance(); // COLONCOLON
parseSimpleNameExpression();
expression.done(CALLABLE_REFERENCE_EXPRESSION);
return true;
}
/*
* postfixUnaryExpression
* : atomicExpression postfixUnaryOperation*
* : callableReference postfixUnaryOperation*
* ;
*
* postfixUnaryOperation
* : "++" : "--" : "!!"
@@ -354,10 +383,13 @@ public class JetExpressionParsing extends AbstractJetParsing {
* ;
*/
private void parsePostfixExpression() {
// System.out.println("post at " + myBuilder.getTokenText());
PsiBuilder.Marker expression = mark();
parseAtomicExpression();
boolean callableReference = parseCallableReferenceExpression();
if (!callableReference) {
parseAtomicExpression();
}
while (true) {
if (interruptedWithNewLine()) {
break;
@@ -366,7 +398,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseArrayAccess();
expression.done(ARRAY_ACCESS_EXPRESSION);
}
else if (parseCallSuffix()) {
else if (!callableReference && parseCallSuffix()) {
expression.done(CALL_EXPRESSION);
}
else if (at(DOT)) {
@@ -383,13 +415,6 @@ public class JetExpressionParsing extends AbstractJetParsing {
expression.done(SAFE_ACCESS_EXPRESSION);
}
// else if (at(HASH)) {
// advance(); // HASH
//
// expect(IDENTIFIER, "Expecting property or function name");
//
// expression.done(HASH_QUALIFIED_EXPRESSION);
// }
else if (atSet(Precedence.POSTFIX.getOperations())) {
parseOperationReference();
expression.done(POSTFIX_EXPRESSION);
@@ -1452,7 +1452,7 @@ public class JetParsing extends AbstractJetParsing {
* : ("namespace" ".")? simpleUserType{"."}
* ;
*/
private void parseUserType() {
void parseUserType() {
PsiBuilder.Marker userType = mark();
if (at(PACKAGE_KEYWORD)) {
+42
View File
@@ -0,0 +1,42 @@
fun ok() {
A::a
A::a + 1
Map<String, Int>::size
::a
a.b::c
a::b.c
a.b::c.d
a<b>::c
a<b>::c.d
a.b<c>::d
a.b<c>::d.e
a.b<c.d>::e
a.b<c.d>::e.d
a.b<c.d<e.f>>::g.h
a.b.c<d>.e<f>.g::h
a::b()
(a::b)()
a.(b::c)()
a.b::c()
}
fun err0() {
a::b.c::d
}
fun err1() {
A::
}
fun err2() {
A::a::b
}
fun err3() {
::
}
+492
View File
@@ -0,0 +1,492 @@
JetFile: DoubleColon.jet
NAMESPACE_HEADER
<empty list>
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('ok')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n ')
BINARY_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(PLUS)('+')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Map')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('String')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('size')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
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)('c')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
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)('c')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('e')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
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
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('e')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
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
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('e')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
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
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('e')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('f')
PsiElement(GT)('>')
PsiElement(GT)('>')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('g')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('h')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
USER_TYPE
USER_TYPE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('d')
PsiElement(GT)('>')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('e')
TYPE_ARGUMENT_LIST
PsiElement(LT)('<')
TYPE_PROJECTION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('f')
PsiElement(GT)('>')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('g')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('h')
PsiWhiteSpace('\n\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALL_EXPRESSION
PARENTHESIZED
PsiElement(LPAR)('(')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(RPAR)(')')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
CALL_EXPRESSION
PARENTHESIZED
PsiElement(LPAR)('(')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiElement(RPAR)(')')
VALUE_ARGUMENT_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('err0')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
DOT_QUALIFIED_EXPRESSION
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('b')
PsiElement(DOT)('.')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('c')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(COLONCOLON)('::')
PsiElement(IDENTIFIER)('d')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('err1')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(COLONCOLON)('::')
PsiWhiteSpace('\n')
REFERENCE_EXPRESSION
PsiErrorElement:Expecting an identifier
<empty list>
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('err2')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('A')
PsiElement(COLONCOLON)('::')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('a')
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
PsiElement(COLONCOLON)('::')
PsiElement(IDENTIFIER)('b')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('err3')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
CALLABLE_REFERENCE_EXPRESSION
PsiElement(COLONCOLON)('::')
PsiWhiteSpace('\n')
REFERENCE_EXPRESSION
PsiErrorElement:Expecting an identifier
<empty list>
PsiElement(RBRACE)('}')
+6
View File
@@ -99,6 +99,12 @@ prefixUnaryExpression
postfixUnaryExpression
: atomicExpression postfixUnaryOperation*
: callableReference postfixUnaryOperation*
;
// TODO: callSuffix is forbidden after callableReference, since parentheses will be used to provide parameter types
callableReference
: userType? "::" SimpleName
;
// !!! When you add here, remember to update the FIRST set in the parser