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
|
* statement
|
||||||
* : declaration
|
* : declaration
|
||||||
* : annotations expression
|
* : blockLevelExpression
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseStatement(boolean isScriptTopLevel) {
|
private void parseStatement(boolean isScriptTopLevel) {
|
||||||
@@ -1247,20 +1247,25 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
}
|
}
|
||||||
else if (isScriptTopLevel){
|
else if (isScriptTopLevel){
|
||||||
PsiBuilder.Marker scriptInitializer = mark();
|
PsiBuilder.Marker scriptInitializer = mark();
|
||||||
parseStatementLevelExpression();
|
parseBlockLevelExpression();
|
||||||
scriptInitializer.done(SCRIPT_INITIALIZER);
|
scriptInitializer.done(SCRIPT_INITIALIZER);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parseStatementLevelExpression();
|
parseBlockLevelExpression();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseStatementLevelExpression() {
|
/*
|
||||||
|
* blockLevelExpression
|
||||||
|
* : annotations expression
|
||||||
|
* ;
|
||||||
|
*/
|
||||||
|
private void parseBlockLevelExpression() {
|
||||||
if (at(AT)) {
|
if (at(AT)) {
|
||||||
PsiBuilder.Marker expression = mark();
|
PsiBuilder.Marker expression = mark();
|
||||||
myKotlinParsing.parseAnnotations(DEFAULT);
|
myKotlinParsing.parseAnnotations(DEFAULT);
|
||||||
parseStatementLevelExpression();
|
parseBlockLevelExpression();
|
||||||
expression.done(ANNOTATED_EXPRESSION);
|
expression.done(ANNOTATED_EXPRESSION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1424,7 +1429,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
|
|
||||||
private void parseControlStructureBody() {
|
private void parseControlStructureBody() {
|
||||||
if (!parseAnnotatedLambda(/* preferBlock = */true)) {
|
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()
|
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 = {
|
val l: () -> Unit = {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
i += block(x[0] as T, "" <!CAST_NEVER_SUCCEEDS!>as<!> Int).toInt()
|
||||||
|
|||||||
@@ -14,10 +14,35 @@ fun foo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (i in 1..100)
|
for (i in 1..100)
|
||||||
// annotation is attached to `x4`
|
|
||||||
@ann4
|
@ann4
|
||||||
x4 += foo4()
|
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 {
|
a.filter {
|
||||||
@ann5
|
@ann5
|
||||||
x5 += foo5()
|
x5 += foo5()
|
||||||
|
|||||||
+232
-18
@@ -150,31 +150,245 @@ JetFile: blockLevelExpressions.kt
|
|||||||
PsiElement(INTEGER_LITERAL)('100')
|
PsiElement(INTEGER_LITERAL)('100')
|
||||||
PsiElement(RPAR)(')')
|
PsiElement(RPAR)(')')
|
||||||
PsiWhiteSpace('\n ')
|
PsiWhiteSpace('\n ')
|
||||||
PsiComment(EOL_COMMENT)('// annotation is attached to `x4`')
|
|
||||||
PsiWhiteSpace('\n ')
|
|
||||||
BODY
|
BODY
|
||||||
BINARY_EXPRESSION
|
ANNOTATED_EXPRESSION
|
||||||
ANNOTATED_EXPRESSION
|
ANNOTATION_ENTRY
|
||||||
ANNOTATION_ENTRY
|
PsiElement(AT)('@')
|
||||||
PsiElement(AT)('@')
|
CONSTRUCTOR_CALLEE
|
||||||
CONSTRUCTOR_CALLEE
|
TYPE_REFERENCE
|
||||||
TYPE_REFERENCE
|
USER_TYPE
|
||||||
USER_TYPE
|
REFERENCE_EXPRESSION
|
||||||
REFERENCE_EXPRESSION
|
PsiElement(IDENTIFIER)('ann4')
|
||||||
PsiElement(IDENTIFIER)('ann4')
|
PsiWhiteSpace('\n ')
|
||||||
PsiWhiteSpace('\n ')
|
BINARY_EXPRESSION
|
||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('x4')
|
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(' ')
|
PsiWhiteSpace(' ')
|
||||||
OPERATION_REFERENCE
|
OPERATION_REFERENCE
|
||||||
PsiElement(PLUSEQ)('+=')
|
PsiElement(GT)('>')
|
||||||
PsiWhiteSpace(' ')
|
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
|
REFERENCE_EXPRESSION
|
||||||
PsiElement(IDENTIFIER)('foo4')
|
PsiElement(IDENTIFIER)('x41')
|
||||||
VALUE_ARGUMENT_LIST
|
PsiWhiteSpace(' ')
|
||||||
PsiElement(LPAR)('(')
|
OPERATION_REFERENCE
|
||||||
PsiElement(RPAR)(')')
|
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 ')
|
PsiWhiteSpace('\n\n ')
|
||||||
DOT_QUALIFIED_EXPRESSION
|
DOT_QUALIFIED_EXPRESSION
|
||||||
REFERENCE_EXPRESSION
|
REFERENCE_EXPRESSION
|
||||||
|
|||||||
@@ -4,8 +4,13 @@
|
|||||||
See [Control structures](control-flow.html)
|
See [Control structures](control-flow.html)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
controlStructureBody
|
||||||
|
: block
|
||||||
|
: blockLevelExpression
|
||||||
|
;
|
||||||
|
|
||||||
if
|
if
|
||||||
: "if" "(" expression ")" expression SEMI? ("else" expression)?
|
: "if" "(" expression ")" controlStructureBody SEMI? ("else" controlStructureBody)?
|
||||||
;
|
;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -27,13 +32,13 @@ loop
|
|||||||
;
|
;
|
||||||
|
|
||||||
for
|
for
|
||||||
: "for" "(" annotations (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
|
: "for" "(" annotations (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" controlStructureBody
|
||||||
;
|
;
|
||||||
|
|
||||||
while
|
while
|
||||||
: "while" "(" expression ")" expression
|
: "while" "(" expression ")" controlStructureBody
|
||||||
;
|
;
|
||||||
|
|
||||||
doWhile
|
doWhile
|
||||||
: "do" expression "while" "(" expression ")"
|
: "do" controlStructureBody "while" "(" expression ")"
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -172,6 +172,10 @@ declaration
|
|||||||
|
|
||||||
statement
|
statement
|
||||||
: declaration
|
: declaration
|
||||||
|
: blockLevelExpression
|
||||||
|
;
|
||||||
|
|
||||||
|
blockLevelExpression
|
||||||
: annotations expression
|
: annotations expression
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ when
|
|||||||
|
|
||||||
// TODO : consider empty after ->
|
// TODO : consider empty after ->
|
||||||
whenEntry
|
whenEntry
|
||||||
: whenCondition{","} "->" expression SEMI
|
: whenCondition{","} "->" controlStructureBody SEMI
|
||||||
: "else" "->" expression SEMI
|
: "else" "->" controlStructureBody SEMI
|
||||||
;
|
;
|
||||||
|
|
||||||
whenCondition
|
whenCondition
|
||||||
: expression
|
: expression
|
||||||
: ("in" | "!in") expression
|
: ("in" | "!in") expression
|
||||||
: ("is" | "!is") isRHS
|
: ("is" | "!is") isRHS
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user