Change annotations parsing in bodies of operators
This change only matters in cases of if/when/for/while having braceless blocks Annotations on them are parsed now as on block-level expressions, i.e. they're attached to the whole expression
This commit is contained in:
@@ -1237,7 +1237,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
/*
|
||||
* statement
|
||||
* : declaration
|
||||
* : annotations expression
|
||||
* : blockLevelExpression
|
||||
* ;
|
||||
*/
|
||||
private void parseStatement(boolean isScriptTopLevel) {
|
||||
@@ -1247,20 +1247,25 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
else if (isScriptTopLevel){
|
||||
PsiBuilder.Marker scriptInitializer = mark();
|
||||
parseStatementLevelExpression();
|
||||
parseBlockLevelExpression();
|
||||
scriptInitializer.done(SCRIPT_INITIALIZER);
|
||||
}
|
||||
else {
|
||||
parseStatementLevelExpression();
|
||||
parseBlockLevelExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseStatementLevelExpression() {
|
||||
/*
|
||||
* blockLevelExpression
|
||||
* : annotations expression
|
||||
* ;
|
||||
*/
|
||||
private void parseBlockLevelExpression() {
|
||||
if (at(AT)) {
|
||||
PsiBuilder.Marker expression = mark();
|
||||
myKotlinParsing.parseAnnotations(DEFAULT);
|
||||
parseStatementLevelExpression();
|
||||
parseBlockLevelExpression();
|
||||
expression.done(ANNOTATED_EXPRESSION);
|
||||
return;
|
||||
}
|
||||
@@ -1424,7 +1429,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
||||
|
||||
private void parseControlStructureBody() {
|
||||
if (!parseAnnotatedLambda(/* preferBlock = */true)) {
|
||||
parseExpression();
|
||||
parseBlockLevelExpression();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,36 @@ fun <T : CharSequence> foo(x: Array<Any>, y: IntArray, block: (T, Int) -> Int) {
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
}
|
||||
|
||||
if (i != 1)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
|
||||
if (i != 2)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
else
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[1] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
|
||||
while (i != 1)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
|
||||
do
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
while (i != 1)
|
||||
|
||||
for (j in 1..100)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
|
||||
when (i) {
|
||||
1 ->
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
}
|
||||
|
||||
val l: () -> Unit = {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||
|
||||
@@ -14,10 +14,35 @@ fun foo() {
|
||||
}
|
||||
|
||||
for (i in 1..100)
|
||||
// annotation is attached to `x4`
|
||||
@ann4
|
||||
x4 += foo4()
|
||||
|
||||
if (1 > 2)
|
||||
@ann41
|
||||
x41 += foo41()
|
||||
|
||||
if (3 > 4)
|
||||
@ann42
|
||||
x42 += foo42()
|
||||
else
|
||||
@ann43
|
||||
x43 += foo43()
|
||||
|
||||
while (true)
|
||||
@ann44
|
||||
x44 += foo44()
|
||||
|
||||
do
|
||||
@ann
|
||||
x45 += foo45()
|
||||
while (true)
|
||||
|
||||
when (1) {
|
||||
1 ->
|
||||
@ann46
|
||||
x46 += foo46()
|
||||
}
|
||||
|
||||
a.filter {
|
||||
@ann5
|
||||
x5 += foo5()
|
||||
|
||||
+232
-18
@@ -150,31 +150,245 @@ JetFile: blockLevelExpressions.kt
|
||||
PsiElement(INTEGER_LITERAL)('100')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiComment(EOL_COMMENT)('// annotation is attached to `x4`')
|
||||
PsiWhiteSpace('\n ')
|
||||
BODY
|
||||
BINARY_EXPRESSION
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann4')
|
||||
PsiWhiteSpace('\n ')
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann4')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x4')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo4')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
THEN
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann41')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo4')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiElement(IDENTIFIER)('x41')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo41')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
IF
|
||||
PsiElement(if)('if')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BINARY_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('3')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(GT)('>')
|
||||
PsiWhiteSpace(' ')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('4')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
THEN
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann42')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x42')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo42')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(else)('else')
|
||||
PsiWhiteSpace('\n ')
|
||||
ELSE
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann43')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x43')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo43')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
WHILE
|
||||
PsiElement(while)('while')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
BODY
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann44')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x44')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo44')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
DO_WHILE
|
||||
PsiElement(do)('do')
|
||||
PsiWhiteSpace('\n ')
|
||||
BODY
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x45')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo45')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(while)('while')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
CONDITION
|
||||
BOOLEAN_CONSTANT
|
||||
PsiElement(true)('true')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
WHEN
|
||||
PsiElement(when)('when')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
WHEN_ENTRY
|
||||
WHEN_CONDITION_WITH_EXPRESSION
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace('\n ')
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('ann46')
|
||||
PsiWhiteSpace('\n ')
|
||||
BINARY_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('x46')
|
||||
PsiWhiteSpace(' ')
|
||||
OPERATION_REFERENCE
|
||||
PsiElement(PLUSEQ)('+=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo46')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n ')
|
||||
DOT_QUALIFIED_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
|
||||
@@ -4,8 +4,13 @@
|
||||
See [Control structures](control-flow.html)
|
||||
*/
|
||||
|
||||
controlStructureBody
|
||||
: block
|
||||
: blockLevelExpression
|
||||
;
|
||||
|
||||
if
|
||||
: "if" "(" expression ")" expression SEMI? ("else" expression)?
|
||||
: "if" "(" expression ")" controlStructureBody SEMI? ("else" controlStructureBody)?
|
||||
;
|
||||
|
||||
try
|
||||
@@ -27,13 +32,13 @@ loop
|
||||
;
|
||||
|
||||
for
|
||||
: "for" "(" annotations (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
|
||||
: "for" "(" annotations (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" controlStructureBody
|
||||
;
|
||||
|
||||
while
|
||||
: "while" "(" expression ")" expression
|
||||
: "while" "(" expression ")" controlStructureBody
|
||||
;
|
||||
|
||||
doWhile
|
||||
: "do" expression "while" "(" expression ")"
|
||||
: "do" controlStructureBody "while" "(" expression ")"
|
||||
;
|
||||
|
||||
@@ -172,6 +172,10 @@ declaration
|
||||
|
||||
statement
|
||||
: declaration
|
||||
: blockLevelExpression
|
||||
;
|
||||
|
||||
blockLevelExpression
|
||||
: annotations expression
|
||||
;
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ when
|
||||
|
||||
// TODO : consider empty after ->
|
||||
whenEntry
|
||||
: whenCondition{","} "->" expression SEMI
|
||||
: "else" "->" expression SEMI
|
||||
: whenCondition{","} "->" controlStructureBody SEMI
|
||||
: "else" "->" controlStructureBody SEMI
|
||||
;
|
||||
|
||||
whenCondition
|
||||
: expression
|
||||
: ("in" | "!in") expression
|
||||
: ("is" | "!is") isRHS
|
||||
;
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user