[FIR] Desugar increment/decrement in body resolve phase
The expression needs to be resolved first to determine if there is a receiver that needs to be extracted to a temporary variable. Also, the special case for prefix increment/decrement on local variable without delegates requires resolution to check if the variable is local. ^KT-56771 Fixed ^KT-56659 Fixed
This commit is contained in:
committed by
Space Team
parent
5ecf9cce25
commit
3b9724d20e
@@ -1,6 +1,9 @@
|
||||
while(CMP(<, R|<local>/x|.R|kotlin/Int.compareTo|(Int(2)))) {
|
||||
[BODY_RESOLVE] lval <unary>: R|kotlin/Int| = R|<local>/x|
|
||||
R|<local>/x| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
[BODY_RESOLVE] lval <unary>: R|kotlin/Int| = R|<local>/x|
|
||||
R|<local>/x| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
[BODY_RESOLVE] lval z: R|kotlin/Int| = R|<local>/y|
|
||||
}
|
||||
|
||||
+12
@@ -357,6 +357,18 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/IncorrectCharacterLiterals.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnFullyQualified.kt")
|
||||
public void testIncrementDecrementOnFullyQualified() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnFullyQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnObject.kt")
|
||||
public void testIncrementDecrementOnObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InferNullabilityInThenBlock.kt")
|
||||
public void testInferNullabilityInThenBlock() throws Exception {
|
||||
|
||||
+30
-15
@@ -81,9 +81,12 @@ FILE: CanBeValChecker.kt
|
||||
when () {
|
||||
R|<local>/flag| -> {
|
||||
while(CMP(>, R|<local>/a|.R|kotlin/Int.compareTo|(Int(0)))) {
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -111,17 +114,23 @@ FILE: CanBeValChecker.kt
|
||||
lvar v2: R|kotlin/Int| = Int(2)
|
||||
lvar v3: R|kotlin/Int| = Int(3)
|
||||
R|<local>/v1| = Int(1)
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/v2|
|
||||
R|<local>/v2| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/v2|
|
||||
R|<local>/v2| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
R|kotlin/io/print|(R|<local>/v3|)
|
||||
}
|
||||
public final fun test(): R|kotlin/Unit| {
|
||||
lvar a: R|kotlin/Int| = Int(0)
|
||||
while(CMP(>, R|<local>/a|.R|kotlin/Int.compareTo|(Int(0)))) {
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -143,16 +152,22 @@ FILE: CanBeValChecker.kt
|
||||
public final fun cycles(): R|kotlin/Unit| {
|
||||
lvar a: R|kotlin/Int| = Int(10)
|
||||
while(CMP(>, R|<local>/a|.R|kotlin/Int.compareTo|(Int(0)))) {
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.dec|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lvar b: R|kotlin/Int|
|
||||
while(CMP(<, R|<local>/a|.R|kotlin/Int.compareTo|(Int(10)))) {
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = R|<local>/a|
|
||||
R|<local>/a| = R|<local>/<unary>|.R|kotlin/Int.inc|()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
R|<local>/b| = R|<local>/a|
|
||||
}
|
||||
|
||||
|
||||
+12
@@ -357,6 +357,18 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/IncorrectCharacterLiterals.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnFullyQualified.kt")
|
||||
public void testIncrementDecrementOnFullyQualified() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnFullyQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnObject.kt")
|
||||
public void testIncrementDecrementOnObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InferNullabilityInThenBlock.kt")
|
||||
public void testInferNullabilityInThenBlock() throws Exception {
|
||||
|
||||
+12
@@ -357,6 +357,18 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/IncorrectCharacterLiterals.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnFullyQualified.kt")
|
||||
public void testIncrementDecrementOnFullyQualified() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnFullyQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnObject.kt")
|
||||
public void testIncrementDecrementOnObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InferNullabilityInThenBlock.kt")
|
||||
public void testInferNullabilityInThenBlock() throws Exception {
|
||||
|
||||
@@ -469,7 +469,7 @@ fun checkTypeMismatch(
|
||||
context
|
||||
)
|
||||
}
|
||||
source.kind is KtFakeSourceElementKind.DesugaredIncrementOrDecrement -> {
|
||||
source.kind is KtFakeSourceElementKind.DesugaredIncrementOrDecrement || assignment?.source?.kind is KtFakeSourceElementKind.DesugaredIncrementOrDecrement -> {
|
||||
if (!lValueType.isNullable && rValueType.isNullable) {
|
||||
val tempType = rValueType
|
||||
rValueType = lValueType
|
||||
|
||||
+18
@@ -26873,6 +26873,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -49043,12 +49049,24 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -26873,6 +26873,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -49043,12 +49049,24 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+1
-3
@@ -27,9 +27,7 @@ FILE: destructuring.kt
|
||||
lvar x: <implicit> = R|<local>/<destruct>|.component1#()
|
||||
lvar y: <implicit> = R|<local>/<destruct>|.component2#()
|
||||
lvar z: String = R|<local>/<destruct>|.component3#()
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
x#++
|
||||
*=(y#, Double(2.0))
|
||||
z# = String()
|
||||
}
|
||||
|
||||
Vendored
+8
-44
@@ -1,23 +1,8 @@
|
||||
FILE: safeCallsWithUnaryOperators.kt
|
||||
public? final? fun foo(): R|kotlin/Unit| {
|
||||
a#?.{ {
|
||||
lval <receiver>: <implicit> = $subj$
|
||||
lval <unary>: <implicit> = R|<local>/<receiver>|.b#
|
||||
R|<local>/<receiver>|.b# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
}
|
||||
a#?.{ $subj$.b# }?.{ {
|
||||
lval <receiver>: <implicit> = $subj$
|
||||
lval <unary>: <implicit> = R|<local>/<receiver>|.c#
|
||||
R|<local>/<receiver>|.c# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
}
|
||||
lval <receiver>: <implicit> = a#?.{ $subj$.b# }
|
||||
lval <unary>: <implicit> = R|<local>/<receiver>|.c#
|
||||
R|<local>/<receiver>|.c# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
a#?.{ $subj$.b# }++
|
||||
a#?.{ $subj$.b# }?.{ $subj$.c# }++
|
||||
a#?.{ $subj$.b# }.c#++
|
||||
a#?.{ {
|
||||
lval <array>: <implicit> = $subj$.b#
|
||||
lval <index_0>: <implicit> = IntegerLiteral(0)
|
||||
@@ -60,30 +45,12 @@ FILE: safeCallsWithUnaryOperators.kt
|
||||
lval <unary>: <implicit> = R|<local>/<array>|.get#(R|<local>/<index_0>|)
|
||||
R|<local>/<array>|.set#(R|<local>/<index_0>|, R|<local>/<unary>|.inc#())
|
||||
R|<local>/<unary>|
|
||||
lval <receiver>: <implicit> = a#?.{ $subj$.b# }
|
||||
lval <unary>: <implicit> = R|<local>/<receiver>|.d#()
|
||||
R|<local>/<receiver>|.d#() = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
a#?.{ $subj$.b# }.d#()++
|
||||
}
|
||||
public? final? fun foo2(): R|kotlin/Unit| {
|
||||
a#?.{ {
|
||||
lval <receiver>: <implicit> = $subj$
|
||||
lval <unary-result>: <implicit> = R|<local>/<receiver>|.b#.inc#()
|
||||
R|<local>/<receiver>|.b# = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
}
|
||||
a#?.{ $subj$.b# }?.{ {
|
||||
lval <receiver>: <implicit> = $subj$
|
||||
lval <unary-result>: <implicit> = R|<local>/<receiver>|.c#.inc#()
|
||||
R|<local>/<receiver>|.c# = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
}
|
||||
lval <receiver>: <implicit> = a#?.{ $subj$.b# }
|
||||
lval <unary-result>: <implicit> = R|<local>/<receiver>|.c#.inc#()
|
||||
R|<local>/<receiver>|.c# = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
++a#?.{ $subj$.b# }
|
||||
++a#?.{ $subj$.b# }?.{ $subj$.c# }
|
||||
++a#?.{ $subj$.b# }.c#
|
||||
a#?.{ {
|
||||
lval <array>: <implicit> = $subj$.b#
|
||||
lval <index_0>: <implicit> = IntegerLiteral(0)
|
||||
@@ -126,8 +93,5 @@ FILE: safeCallsWithUnaryOperators.kt
|
||||
lval <unary-result>: <implicit> = R|<local>/<array>|.get#(R|<local>/<index_0>|).inc#()
|
||||
R|<local>/<array>|.set#(R|<local>/<index_0>|, R|<local>/<unary-result>|)
|
||||
R|<local>/<unary-result>|
|
||||
lval <receiver>: <implicit> = a#?.{ $subj$.b# }
|
||||
lval <unary-result>: <implicit> = R|<local>/<receiver>|.d#().inc#()
|
||||
R|<local>/<receiver>|.d#() = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
++a#?.{ $subj$.b# }.d#()
|
||||
}
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
FILE: unary.kt
|
||||
public? final? fun test(): R|kotlin/Unit| {
|
||||
lvar x: <implicit> = IntegerLiteral(0)
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
x# = x#.inc#()
|
||||
x#
|
||||
}
|
||||
|
||||
lval x3: <implicit> = {
|
||||
x# = x#.dec#()
|
||||
x#
|
||||
}
|
||||
|
||||
lval x4: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = R|<local>/<unary>|.dec#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x1: <implicit> = x#++
|
||||
lval x2: <implicit> = ++x#
|
||||
lval x3: <implicit> = --x#
|
||||
lval x4: <implicit> = x#--
|
||||
when () {
|
||||
==(x#, IntegerLiteral(0)).not#() -> {
|
||||
println#(String(000))
|
||||
@@ -40,20 +22,8 @@ FILE: unary.kt
|
||||
|
||||
}
|
||||
public? final? fun test2(x: X): R|kotlin/Unit| {
|
||||
lval x1: <implicit> = {
|
||||
lval <receiver>: <implicit> = x#
|
||||
lval <unary>: <implicit> = R|<local>/<receiver>|.i#
|
||||
R|<local>/<receiver>|.i# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <receiver>: <implicit> = x#
|
||||
lval <unary-result>: <implicit> = R|<local>/<receiver>|.i#.inc#()
|
||||
R|<local>/<receiver>|.i# = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
lval x1: <implicit> = x#.i#++
|
||||
lval x2: <implicit> = ++x#.i#
|
||||
}
|
||||
public? final? fun test3(arr: Array<Int>): R|kotlin/Unit| {
|
||||
lval x1: <implicit> = {
|
||||
|
||||
@@ -2,14 +2,10 @@ FILE: while.kt
|
||||
public? final? fun foo(limit: Int): R|kotlin/Unit| {
|
||||
lvar k: <implicit> = IntegerLiteral(0)
|
||||
some@while(CMP(<, k#.compareTo#(limit#))) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
k#++
|
||||
println#(k#)
|
||||
while(==(k#, IntegerLiteral(13))) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
k#++
|
||||
when () {
|
||||
CMP(<, k#.compareTo#(limit#)) -> {
|
||||
break@@@[CMP(<, k#.compareTo#(limit#))]
|
||||
@@ -30,9 +26,7 @@ FILE: while.kt
|
||||
public? final? fun bar(limit: Int): R|kotlin/Unit| {
|
||||
lvar k: <implicit> = limit#
|
||||
do {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = R|<local>/<unary>|.dec#()
|
||||
R|<local>/<unary>|
|
||||
k#--
|
||||
println#(k#)
|
||||
}
|
||||
while(CMP(>=, k#.compareTo#(IntegerLiteral(0))))
|
||||
|
||||
+6
-127
@@ -510,17 +510,6 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
diagnostic = ConeSimpleDiagnostic("Inc/dec without operand", DiagnosticKind.Syntax)
|
||||
}
|
||||
|
||||
if (unwrappedReceiver.elementType == DOT_QUALIFIED_EXPRESSION || unwrappedReceiver.elementType == SAFE_ACCESS_EXPRESSION) {
|
||||
return generateIncrementOrDecrementBlockForQualifiedAccess(
|
||||
wholeExpression,
|
||||
operationReference,
|
||||
unwrappedReceiver,
|
||||
callName,
|
||||
prefix,
|
||||
convert
|
||||
)
|
||||
}
|
||||
|
||||
if (unwrappedReceiver.elementType == ARRAY_ACCESS_EXPRESSION) {
|
||||
return generateIncrementOrDecrementBlockForArrayAccess(
|
||||
wholeExpression,
|
||||
@@ -532,43 +521,13 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
)
|
||||
}
|
||||
|
||||
return buildBlock {
|
||||
return buildIncrementDecrementExpression {
|
||||
val baseSource = wholeExpression?.toFirSourceElement()
|
||||
val desugaredSource = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
source = desugaredSource
|
||||
|
||||
val convertedReceiver = unwrappedReceiver.convert()
|
||||
|
||||
putIncrementOrDecrementStatements(
|
||||
convertedReceiver,
|
||||
operationReference,
|
||||
callName,
|
||||
prefix,
|
||||
unwrappedReceiver.takeIf { it.elementType == REFERENCE_EXPRESSION }?.getReferencedNameAsName(),
|
||||
desugaredSource,
|
||||
) { resultInitializer: FirExpression, resultVar: FirVariable ->
|
||||
val assignment = unwrappedReceiver.generateAssignment(
|
||||
desugaredSource,
|
||||
null,
|
||||
if (prefix && unwrappedReceiver.elementType != REFERENCE_EXPRESSION)
|
||||
generateResolvedAccessExpression(source, resultVar)
|
||||
else
|
||||
resultInitializer,
|
||||
FirOperation.ASSIGN,
|
||||
resultInitializer.annotations,
|
||||
null
|
||||
) {
|
||||
// We want the DesugaredAssignmentValueReferenceExpression on the LHS to point to the same receiver instance
|
||||
// as in the initializer, therefore don't create a new instance here if the argument is the receiver.
|
||||
if (this == unwrappedReceiver) convertedReceiver else convert()
|
||||
}
|
||||
|
||||
if (assignment is FirBlock) {
|
||||
statements += assignment.statements
|
||||
} else {
|
||||
statements += assignment
|
||||
}
|
||||
}
|
||||
source = baseSource
|
||||
operationSource = operationReference?.toFirSourceElement()
|
||||
operationName = callName
|
||||
isPrefix = prefix
|
||||
expression = unwrappedReceiver.convert()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -672,86 +631,6 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* given:
|
||||
* a.b++
|
||||
*
|
||||
* result:
|
||||
* {
|
||||
* val <receiver> = a
|
||||
* val <unary> = <receiver>.b
|
||||
* <receiver>.b = <unary>.inc()
|
||||
* ^<unary>
|
||||
* }
|
||||
*
|
||||
* given:
|
||||
* ++a.b
|
||||
*
|
||||
* result:
|
||||
* {
|
||||
* val <receiver> = a
|
||||
* val <unary-result> = <receiver>.b.inc()
|
||||
* <receiver>.b = <unary-result>
|
||||
* ^<unary-result>
|
||||
* }
|
||||
*
|
||||
*/
|
||||
@OptIn(FirContractViolation::class)
|
||||
private fun generateIncrementOrDecrementBlockForQualifiedAccess(
|
||||
wholeExpression: T,
|
||||
operationReference: T?,
|
||||
receiverForOperation: T, // a.b
|
||||
callName: Name,
|
||||
prefix: Boolean,
|
||||
convert: T.() -> FirExpression
|
||||
): FirExpression {
|
||||
return buildBlockProbablyUnderSafeCall(
|
||||
receiverForOperation,
|
||||
convert,
|
||||
receiverForOperation.toFirSourceElement(),
|
||||
) { qualifiedFir ->
|
||||
val receiverFir = (qualifiedFir as? FirQualifiedAccessExpression)?.explicitReceiver ?: buildErrorExpression {
|
||||
source = receiverForOperation.toFirSourceElement()
|
||||
diagnostic = ConeSimpleDiagnostic("Qualified expression without selector", DiagnosticKind.Syntax)
|
||||
}
|
||||
|
||||
val baseSource = wholeExpression?.toFirSourceElement()
|
||||
val desugaredSource = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
source = desugaredSource
|
||||
|
||||
val argumentReceiverVariable = generateTemporaryVariable(
|
||||
baseModuleData,
|
||||
desugaredSource,
|
||||
SpecialNames.RECEIVER,
|
||||
initializer = receiverFir,
|
||||
).also { statements += it }
|
||||
|
||||
val receiverSource = receiverFir.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
val firArgument = generateResolvedAccessExpression(receiverSource, argumentReceiverVariable).let { receiver ->
|
||||
qualifiedFir.also { if (it is FirQualifiedAccessExpression) it.replaceExplicitReceiver(receiver) }
|
||||
}
|
||||
|
||||
putIncrementOrDecrementStatements(
|
||||
firArgument, operationReference, callName, prefix,
|
||||
nameIfSimpleReference = null, desugaredSource
|
||||
) { resultInitializer: FirExpression, resultVar: FirVariable ->
|
||||
if (firArgument !is FirQualifiedAccessExpression) return@putIncrementOrDecrementStatements
|
||||
statements += buildVariableAssignment {
|
||||
source = desugaredSource
|
||||
lValue = buildDesugaredAssignmentValueReferenceExpression {
|
||||
expressionRef = FirExpressionRef<FirExpression>().apply { bind(firArgument) }
|
||||
source = firArgument.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
}
|
||||
rValue = if (prefix) {
|
||||
generateResolvedAccessExpression(source, resultVar)
|
||||
} else {
|
||||
resultInitializer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* given:
|
||||
* a[b, c]++
|
||||
|
||||
+7
@@ -160,6 +160,13 @@ abstract class FirAbstractBodyResolveTransformerDispatcher(
|
||||
return expressionsTransformer.transformAssignmentOperatorStatement(assignmentOperatorStatement, data)
|
||||
}
|
||||
|
||||
override fun transformIncrementDecrementExpression(
|
||||
incrementDecrementExpression: FirIncrementDecrementExpression,
|
||||
data: ResolutionMode
|
||||
): FirStatement {
|
||||
return expressionsTransformer.transformIncrementDecrementExpression(incrementDecrementExpression, data)
|
||||
}
|
||||
|
||||
override fun transformEqualityOperatorCall(
|
||||
equalityOperatorCall: FirEqualityOperatorCall,
|
||||
data: ResolutionMode
|
||||
|
||||
+123
-20
@@ -21,13 +21,10 @@ import org.jetbrains.kotlin.fir.extensions.assignAltererExtensions
|
||||
import org.jetbrains.kotlin.fir.extensions.expressionResolutionExtensions
|
||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||
import org.jetbrains.kotlin.fir.references.*
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildExplicitSuperReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.references.builder.*
|
||||
import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.*
|
||||
import org.jetbrains.kotlin.fir.expressions.unwrapSmartcastExpression
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.FirStubInferenceSession
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
@@ -678,6 +675,124 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(FirContractViolation::class)
|
||||
override fun transformIncrementDecrementExpression(
|
||||
incrementDecrementExpression: FirIncrementDecrementExpression,
|
||||
data: ResolutionMode
|
||||
): FirStatement {
|
||||
incrementDecrementExpression.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
val originalExpression = incrementDecrementExpression.expression.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||
val expression = when (originalExpression) {
|
||||
is FirSafeCallExpression -> originalExpression.selector as? FirExpression ?: buildErrorExpression {
|
||||
source = originalExpression.source
|
||||
diagnostic = ConeSimpleDiagnostic("Safe call selector expected to be an expression here", DiagnosticKind.Syntax)
|
||||
}
|
||||
else -> originalExpression
|
||||
}
|
||||
|
||||
val desugaredSource = incrementDecrementExpression.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
|
||||
fun generateTemporaryVariable(name: Name, initializer: FirExpression): FirProperty = generateTemporaryVariable(
|
||||
moduleData = session.moduleData,
|
||||
source = desugaredSource,
|
||||
name = name,
|
||||
initializer = initializer,
|
||||
typeRef = initializer.typeRef.copyWithNewSource(desugaredSource),
|
||||
)
|
||||
|
||||
fun buildAndResolveOperatorCall(receiver: FirExpression): FirFunctionCall = buildFunctionCall {
|
||||
source = incrementDecrementExpression.operationSource
|
||||
explicitReceiver = receiver
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
val referenceSourceKind = when {
|
||||
incrementDecrementExpression.isPrefix -> KtFakeSourceElementKind.DesugaredPrefixNameReference
|
||||
else -> KtFakeSourceElementKind.DesugaredPostfixNameReference
|
||||
}
|
||||
source = incrementDecrementExpression.operationSource?.fakeElement(referenceSourceKind)
|
||||
name = incrementDecrementExpression.operationName
|
||||
}
|
||||
origin = FirFunctionCallOrigin.Operator
|
||||
}.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
fun buildAndResolveVariableAssignment(rValue: FirExpression): FirVariableAssignment = buildVariableAssignment {
|
||||
source = desugaredSource
|
||||
lValue = buildDesugaredAssignmentValueReferenceExpression {
|
||||
source = ((expression as? FirErrorExpression)?.expression ?: expression).source
|
||||
?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement)
|
||||
expressionRef = FirExpressionRef<FirExpression>().apply { bind(expression.unwrapSmartcastExpression()) }
|
||||
}
|
||||
this.rValue = rValue
|
||||
}.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
val block = buildBlock {
|
||||
source = desugaredSource
|
||||
annotations += incrementDecrementExpression.annotations
|
||||
|
||||
(expression as? FirQualifiedAccessExpression)?.explicitReceiver
|
||||
// If a receiver x exists, write it to a temporary variable to prevent multiple calls to it.
|
||||
// Exceptions: ResolvedQualifiers and ThisReceivers as they can't have side effects when called.
|
||||
?.takeIf { it is FirQualifiedAccessExpression && it !is FirThisReceiverExpression }
|
||||
?.let { receiver ->
|
||||
// val <receiver> = x
|
||||
statements += generateTemporaryVariable(SpecialNames.RECEIVER, receiver).also { property ->
|
||||
// Change the expression from x.a to <receiver>.a
|
||||
val newReceiverAccess =
|
||||
property.toQualifiedAccess(fakeSource = receiver.source?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement))
|
||||
|
||||
if (expression.explicitReceiver == expression.dispatchReceiver) {
|
||||
expression.replaceDispatchReceiver(newReceiverAccess)
|
||||
} else {
|
||||
expression.replaceExtensionReceiver(newReceiverAccess)
|
||||
}
|
||||
expression.replaceExplicitReceiver(newReceiverAccess)
|
||||
}
|
||||
}
|
||||
|
||||
if (incrementDecrementExpression.isPrefix) {
|
||||
val targetProperty = expression.calleeReference?.toResolvedPropertySymbol()?.fir
|
||||
val operatorCall = buildAndResolveOperatorCall(expression)
|
||||
|
||||
// Special case for prefix inc/dec on local variable without delegate where unary-result variable generation is skipped.
|
||||
if (targetProperty?.isLocal == true && targetProperty.delegate == null) {
|
||||
// a = a.inc()
|
||||
statements += buildAndResolveVariableAssignment(operatorCall)
|
||||
// ^a
|
||||
statements += targetProperty.toQualifiedAccess(fakeSource = desugaredSource, typeRef = noExpectedType)
|
||||
// If inc() returns a subtype of its receiver type, the variable access should be smart-casted.
|
||||
.transform<FirStatement, ResolutionMode>(transformer, withExpectedType(operatorCall.typeRef.coneType))
|
||||
} else {
|
||||
val unaryResultVariable = generateTemporaryVariable(SpecialNames.UNARY_RESULT, operatorCall)
|
||||
|
||||
// val <unary-result> = a.inc()
|
||||
statements += unaryResultVariable
|
||||
// a = <unary-result>
|
||||
statements += buildAndResolveVariableAssignment(unaryResultVariable.toQualifiedAccess(fakeSource = desugaredSource))
|
||||
// ^<unary-result>
|
||||
statements += unaryResultVariable.toQualifiedAccess(fakeSource = desugaredSource)
|
||||
}
|
||||
} else {
|
||||
val unaryVariable = generateTemporaryVariable(SpecialNames.UNARY, expression)
|
||||
|
||||
// val <unary> = a
|
||||
statements += unaryVariable
|
||||
// a = <unary>.inc()
|
||||
statements += buildAndResolveVariableAssignment(buildAndResolveOperatorCall(unaryVariable.toQualifiedAccess()))
|
||||
// ^<unary>
|
||||
statements += unaryVariable.toQualifiedAccess()
|
||||
}
|
||||
}.apply {
|
||||
replaceTypeRef((statements.last() as FirExpression).typeRef.copyWithNewSource(null))
|
||||
}
|
||||
|
||||
return if (originalExpression is FirSafeCallExpression) {
|
||||
originalExpression.replaceSelector(block)
|
||||
originalExpression
|
||||
} else {
|
||||
block
|
||||
}
|
||||
}
|
||||
|
||||
override fun transformEqualityOperatorCall(
|
||||
equalityOperatorCall: FirEqualityOperatorCall,
|
||||
data: ResolutionMode
|
||||
@@ -891,14 +1006,6 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
): FirStatement = whileAnalysing(session, variableAssignment) {
|
||||
variableAssignment.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
val isDesugaredIncrementDecrement = variableAssignment.source?.kind == KtFakeSourceElementKind.DesugaredIncrementOrDecrement
|
||||
|
||||
// Expressions like `++a` are desugared into `a = a.inc()` where the LHS is a FirDesugaredAssignmentValueReferenceExpression
|
||||
// that's pointing to the not yet resolved `a` on the RHS. For the resolution to work, the RHS must therefore be resolved first.
|
||||
if (isDesugaredIncrementDecrement) {
|
||||
variableAssignment.transformRValue(transformer, ResolutionMode.ContextIndependent)
|
||||
}
|
||||
|
||||
variableAssignment.transformLValue(transformer, ResolutionMode.AssignmentLValue(variableAssignment))
|
||||
|
||||
val resolvedReference = variableAssignment.calleeReference
|
||||
@@ -926,14 +1033,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
||||
}
|
||||
}
|
||||
|
||||
val result = if (!isDesugaredIncrementDecrement) {
|
||||
variableAssignment.transformRValue(
|
||||
transformer,
|
||||
withExpectedType(variableAssignment.lValue.typeRef, expectedTypeMismatchIsReportedInChecker = true),
|
||||
)
|
||||
} else {
|
||||
variableAssignment
|
||||
}
|
||||
val result = variableAssignment.transformRValue(
|
||||
transformer,
|
||||
withExpectedType(variableAssignment.lValue.typeRef, expectedTypeMismatchIsReportedInChecker = true),
|
||||
)
|
||||
|
||||
(result as? FirVariableAssignment)?.let { dataFlowAnalyzer.exitVariableAssignment(it) }
|
||||
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
abstract class FirIncrementDecrementExpression : FirExpression() {
|
||||
abstract override val source: KtSourceElement?
|
||||
abstract override val typeRef: FirTypeRef
|
||||
abstract override val annotations: List<FirAnnotation>
|
||||
abstract val isPrefix: Boolean
|
||||
abstract val operationName: Name
|
||||
abstract val expression: FirExpression
|
||||
abstract val operationSource: KtSourceElement?
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitIncrementDecrementExpression(this, data)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
|
||||
transformer.transformIncrementDecrementExpression(this, data) as E
|
||||
|
||||
abstract override fun replaceTypeRef(newTypeRef: FirTypeRef)
|
||||
|
||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||
|
||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirIncrementDecrementExpression
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.builder
|
||||
|
||||
import kotlin.contracts.*
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.FirExpressionBuilder
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirIncrementDecrementExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
@FirBuilderDsl
|
||||
class FirIncrementDecrementExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBuilder {
|
||||
override var source: KtSourceElement? = null
|
||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||
var isPrefix: Boolean by kotlin.properties.Delegates.notNull<Boolean>()
|
||||
lateinit var operationName: Name
|
||||
lateinit var expression: FirExpression
|
||||
var operationSource: KtSourceElement? = null
|
||||
|
||||
override fun build(): FirIncrementDecrementExpression {
|
||||
return FirIncrementDecrementExpressionImpl(
|
||||
source,
|
||||
annotations.toMutableOrEmpty(),
|
||||
isPrefix,
|
||||
operationName,
|
||||
expression,
|
||||
operationSource,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("Modification of 'typeRef' has no impact for FirIncrementDecrementExpressionBuilder", level = DeprecationLevel.HIDDEN)
|
||||
override var typeRef: FirTypeRef
|
||||
get() = throw IllegalStateException()
|
||||
set(_) {
|
||||
throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildIncrementDecrementExpression(init: FirIncrementDecrementExpressionBuilder.() -> Unit): FirIncrementDecrementExpression {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
return FirIncrementDecrementExpressionBuilder().apply(init).build()
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("DuplicatedCode")
|
||||
|
||||
package org.jetbrains.kotlin.fir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.MutableOrEmptyList
|
||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
* DO NOT MODIFY IT MANUALLY
|
||||
*/
|
||||
|
||||
internal class FirIncrementDecrementExpressionImpl(
|
||||
override val source: KtSourceElement?,
|
||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||
override val isPrefix: Boolean,
|
||||
override val operationName: Name,
|
||||
override var expression: FirExpression,
|
||||
override val operationSource: KtSourceElement?,
|
||||
) : FirIncrementDecrementExpression() {
|
||||
override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null)
|
||||
|
||||
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
|
||||
typeRef.accept(visitor, data)
|
||||
annotations.forEach { it.accept(visitor, data) }
|
||||
expression.accept(visitor, data)
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirIncrementDecrementExpressionImpl {
|
||||
typeRef = typeRef.transform(transformer, data)
|
||||
transformAnnotations(transformer, data)
|
||||
expression = expression.transform(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirIncrementDecrementExpressionImpl {
|
||||
annotations.transformInplace(transformer, data)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun replaceTypeRef(newTypeRef: FirTypeRef) {
|
||||
typeRef = newTypeRef
|
||||
}
|
||||
|
||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||
annotations = newAnnotations.toMutableOrEmpty()
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAssignmentOperatorStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
@@ -214,6 +215,8 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
|
||||
|
||||
override fun visitAssignmentOperatorStatement(assignmentOperatorStatement: FirAssignmentOperatorStatement, data: D): R = visitStatement(assignmentOperatorStatement, data)
|
||||
|
||||
override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: D): R = visitExpression(incrementDecrementExpression, data)
|
||||
|
||||
override fun visitAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall, data: D): R = visitStatement(augmentedArraySetCall, data)
|
||||
|
||||
override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression, data: D): R = visitExpression(classReferenceExpression, data)
|
||||
|
||||
@@ -82,6 +82,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAssignmentOperatorStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
@@ -214,6 +215,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
|
||||
|
||||
override fun visitAssignmentOperatorStatement(assignmentOperatorStatement: FirAssignmentOperatorStatement) = visitStatement(assignmentOperatorStatement)
|
||||
|
||||
override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression) = visitExpression(incrementDecrementExpression)
|
||||
|
||||
override fun visitAugmentedArraySetCall(augmentedArraySetCall: FirAugmentedArraySetCall) = visitStatement(augmentedArraySetCall)
|
||||
|
||||
override fun visitClassReferenceExpression(classReferenceExpression: FirClassReferenceExpression) = visitExpression(classReferenceExpression)
|
||||
|
||||
@@ -82,6 +82,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAssignmentOperatorStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
@@ -463,6 +464,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformElement(assignmentOperatorStatement, data)
|
||||
}
|
||||
|
||||
open fun transformIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: D): FirStatement {
|
||||
return transformElement(incrementDecrementExpression, data)
|
||||
}
|
||||
|
||||
open fun transformEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: D): FirStatement {
|
||||
return transformElement(equalityOperatorCall, data)
|
||||
}
|
||||
@@ -1039,6 +1044,10 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
|
||||
return transformAssignmentOperatorStatement(assignmentOperatorStatement, data)
|
||||
}
|
||||
|
||||
final override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: D): FirStatement {
|
||||
return transformIncrementDecrementExpression(incrementDecrementExpression, data)
|
||||
}
|
||||
|
||||
final override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: D): FirStatement {
|
||||
return transformEqualityOperatorCall(equalityOperatorCall, data)
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAssignmentOperatorStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
@@ -310,6 +311,8 @@ abstract class FirVisitor<out R, in D> {
|
||||
|
||||
open fun visitAssignmentOperatorStatement(assignmentOperatorStatement: FirAssignmentOperatorStatement, data: D): R = visitElement(assignmentOperatorStatement, data)
|
||||
|
||||
open fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: D): R = visitElement(incrementDecrementExpression, data)
|
||||
|
||||
open fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: D): R = visitElement(equalityOperatorCall, data)
|
||||
|
||||
open fun visitWhenExpression(whenExpression: FirWhenExpression, data: D): R = visitElement(whenExpression, data)
|
||||
|
||||
@@ -82,6 +82,7 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirComparisonExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirTypeOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAssignmentOperatorStatement
|
||||
import org.jetbrains.kotlin.fir.expressions.FirIncrementDecrementExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirEqualityOperatorCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenBranch
|
||||
@@ -462,6 +463,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitElement(assignmentOperatorStatement)
|
||||
}
|
||||
|
||||
open fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression) {
|
||||
visitElement(incrementDecrementExpression)
|
||||
}
|
||||
|
||||
open fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall) {
|
||||
visitElement(equalityOperatorCall)
|
||||
}
|
||||
@@ -1038,6 +1043,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
|
||||
visitAssignmentOperatorStatement(assignmentOperatorStatement)
|
||||
}
|
||||
|
||||
final override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression, data: Nothing?) {
|
||||
visitIncrementDecrementExpression(incrementDecrementExpression)
|
||||
}
|
||||
|
||||
final override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Nothing?) {
|
||||
visitEqualityOperatorCall(equalityOperatorCall)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir
|
||||
|
||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.KtSourceElement
|
||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fakeElement
|
||||
@@ -14,7 +15,7 @@ import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
@@ -25,15 +26,17 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun FirVariable.toQualifiedAccess(): FirQualifiedAccessExpression = buildPropertyAccessExpression {
|
||||
val fakeSource = this@toQualifiedAccess.source?.fakeElement(KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess)
|
||||
fun FirVariable.toQualifiedAccess(
|
||||
fakeSource: KtSourceElement? = source?.fakeElement(KtFakeSourceElementKind.ReferenceInAtomicQualifiedAccess),
|
||||
typeRef: FirTypeRef = returnTypeRef
|
||||
): FirQualifiedAccessExpression = buildPropertyAccessExpression {
|
||||
source = fakeSource
|
||||
calleeReference = buildResolvedNamedReference {
|
||||
source = fakeSource
|
||||
name = this@toQualifiedAccess.name
|
||||
resolvedSymbol = this@toQualifiedAccess.symbol
|
||||
}
|
||||
typeRef = this@toQualifiedAccess.returnTypeRef
|
||||
this.typeRef = typeRef
|
||||
}
|
||||
|
||||
fun generateTemporaryVariable(
|
||||
@@ -42,7 +45,7 @@ fun generateTemporaryVariable(
|
||||
name: Name,
|
||||
initializer: FirExpression,
|
||||
typeRef: FirTypeRef? = null,
|
||||
extractedAnnotations: Collection<FirAnnotation>? = null,
|
||||
extractedAnnotations: Collection<FirAnnotation>? = null
|
||||
): FirProperty =
|
||||
buildProperty {
|
||||
this.source = source
|
||||
@@ -56,7 +59,7 @@ fun generateTemporaryVariable(
|
||||
symbol = FirPropertySymbol(name)
|
||||
isVar = false
|
||||
isLocal = true
|
||||
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
|
||||
status = FirResolvedDeclarationStatusImpl(Visibilities.Local, Modality.FINAL, EffectiveVisibility.Local)
|
||||
if (extractedAnnotations != null) {
|
||||
// LT extracts annotations ahead.
|
||||
// PSI extracts annotations on demand. Use a similar util in [PsiConversionUtils]
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import java.util.*
|
||||
|
||||
class FirRenderer(
|
||||
@@ -1022,6 +1023,14 @@ class FirRenderer(
|
||||
print(")")
|
||||
}
|
||||
|
||||
override fun visitIncrementDecrementExpression(incrementDecrementExpression: FirIncrementDecrementExpression) {
|
||||
annotationRenderer?.render(incrementDecrementExpression)
|
||||
val operator = if (incrementDecrementExpression.operationName == OperatorNameConventions.INC) "++" else "--"
|
||||
if (incrementDecrementExpression.isPrefix) print(operator)
|
||||
incrementDecrementExpression.expression.accept(visitor)
|
||||
if (!incrementDecrementExpression.isPrefix) print(operator)
|
||||
}
|
||||
|
||||
override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall) {
|
||||
annotationRenderer?.render(equalityOperatorCall)
|
||||
print(equalityOperatorCall.operation.operator)
|
||||
|
||||
+1
@@ -104,6 +104,7 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
||||
val comparisonExpression by element(Expression, expression)
|
||||
val typeOperatorCall by element(Expression, expression, call)
|
||||
val assignmentOperatorStatement by element(Expression, statement)
|
||||
val incrementDecrementExpression by element(Expression, expression)
|
||||
val equalityOperatorCall by element(Expression, expression, call)
|
||||
val whenExpression by element(Expression, expression, resolvable)
|
||||
val whenBranch by element(Expression)
|
||||
|
||||
+2
@@ -317,6 +317,8 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
|
||||
|
||||
impl(assignmentOperatorStatement)
|
||||
|
||||
impl(incrementDecrementExpression)
|
||||
|
||||
impl(equalityOperatorCall) {
|
||||
default("typeRef", "FirImplicitBooleanTypeRef(null)")
|
||||
useTypes(implicitBooleanTypeRefType)
|
||||
|
||||
+7
@@ -254,6 +254,13 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("rightArgument", expression).withTransform()
|
||||
}
|
||||
|
||||
incrementDecrementExpression.configure {
|
||||
+booleanField("isPrefix")
|
||||
+field("operationName", nameType)
|
||||
+field("expression", expression)
|
||||
+field("operationSource", sourceElementType, nullable = true)
|
||||
}
|
||||
|
||||
equalityOperatorCall.configure {
|
||||
+field("operation", operationType)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
|
||||
public var inc: Int = 0
|
||||
|
||||
public var propInc: Int = 0
|
||||
@@ -26,4 +29,4 @@ fun box(): String {
|
||||
if (propDec != -1) return "fail in prefix decrement: ${propDec} != -1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// IGNORE_BACKEND_K1: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
// IGNORE_BACKEND: WASM
|
||||
// SKIP_NODE_JS
|
||||
|
||||
public var inc: Int = 0
|
||||
|
||||
public var propInc: Int = 0
|
||||
get() {++inc; return field}
|
||||
set(a: Int) {
|
||||
++inc
|
||||
field = a
|
||||
}
|
||||
|
||||
public var dec: Int = 0
|
||||
|
||||
public var propDec: Int = 0
|
||||
get() { --dec; return field}
|
||||
set(a: Int) {
|
||||
--dec
|
||||
field = a
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
++propInc
|
||||
if (inc != 2) return "fail in prefix increment: ${inc} != 2"
|
||||
if (propInc != 1) return "fail in prefix increment: ${propInc} != 1"
|
||||
|
||||
--propDec
|
||||
if (dec != -2) return "fail in prefix decrement: ${dec} != -2"
|
||||
if (propDec != -1) return "fail in prefix decrement: ${propDec} != -1"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
|
||||
class A {
|
||||
companion object {
|
||||
private var r: Int = 1;
|
||||
@@ -70,4 +73,4 @@ fun box() : String {
|
||||
if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4getR4") return "fail 4: $p4 ${A.holder}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
// IGNORE_BACKEND_K1: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
// IGNORE_BACKEND: WASM
|
||||
// SKIP_NODE_JS
|
||||
|
||||
class A {
|
||||
companion object {
|
||||
private var r: Int = 1;
|
||||
|
||||
fun test(): Int {
|
||||
r++
|
||||
++r
|
||||
return r
|
||||
}
|
||||
|
||||
var holder: String = ""
|
||||
|
||||
var r2: Int = 1
|
||||
get() {
|
||||
holder += "getR2"
|
||||
return field
|
||||
}
|
||||
|
||||
fun test2() : Int {
|
||||
r2++
|
||||
++r2
|
||||
return r2
|
||||
}
|
||||
|
||||
var r3: Int = 1
|
||||
set(p: Int) {
|
||||
holder += "setR3"
|
||||
field = p
|
||||
}
|
||||
|
||||
fun test3() : Int {
|
||||
r3++
|
||||
++r3
|
||||
return r3
|
||||
}
|
||||
|
||||
var r4: Int = 1
|
||||
get() {
|
||||
holder += "getR4"
|
||||
return field
|
||||
}
|
||||
set(p: Int) {
|
||||
holder += "setR4"
|
||||
field = p
|
||||
}
|
||||
|
||||
fun test4() : Int {
|
||||
r4++
|
||||
holder += ":"
|
||||
++r4
|
||||
return r4
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = A.test()
|
||||
if (p != 3) return "fail 1: $p"
|
||||
|
||||
val p2 = A.test2()
|
||||
var holderValue = A.holder
|
||||
if (p2 != 3 || holderValue != "getR2getR2getR2") return "fail 2: $p2 ${holderValue}"
|
||||
|
||||
A.holder = ""
|
||||
val p3 = A.test3()
|
||||
if (p3 != 3 || A.holder != "setR3setR3") return "fail 3: $p3 ${A.holder}"
|
||||
|
||||
A.holder = ""
|
||||
val p4 = A.test4()
|
||||
if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4") return "fail 4: $p4 ${A.holder}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+4
-1
@@ -1,3 +1,6 @@
|
||||
// IGNORE_BACKEND_K2: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
|
||||
object A {
|
||||
private var r: Int = 1;
|
||||
|
||||
@@ -68,4 +71,4 @@ fun box() : String {
|
||||
if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4getR4") return "fail 4: $p4 ${A.holder}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
// IGNORE_BACKEND_K1: ANY
|
||||
// Behavior changed in K2, see KT-42077
|
||||
// IGNORE_BACKEND: WASM
|
||||
// SKIP_NODE_JS
|
||||
|
||||
object A {
|
||||
private var r: Int = 1;
|
||||
|
||||
fun test() : Int {
|
||||
r++
|
||||
++r
|
||||
return r
|
||||
}
|
||||
|
||||
var holder: String = ""
|
||||
|
||||
var r2: Int = 1
|
||||
get() {
|
||||
holder += "getR2"
|
||||
return field
|
||||
}
|
||||
|
||||
fun test2() : Int {
|
||||
r2++
|
||||
++r2
|
||||
return r2
|
||||
}
|
||||
|
||||
var r3: Int = 1
|
||||
set(p: Int) {
|
||||
holder += "setR3"
|
||||
field = p
|
||||
}
|
||||
|
||||
fun test3() : Int {
|
||||
r3++
|
||||
++r3
|
||||
return r3
|
||||
}
|
||||
|
||||
var r4: Int = 1
|
||||
get() {
|
||||
holder += "getR4"
|
||||
return field
|
||||
}
|
||||
set(p: Int) {
|
||||
holder += "setR4"
|
||||
field = p
|
||||
}
|
||||
|
||||
fun test4() : Int {
|
||||
r4++
|
||||
holder += ":"
|
||||
++r4
|
||||
return r4
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = A.test()
|
||||
if (p != 3) return "fail 1: $p"
|
||||
|
||||
val p2 = A.test2()
|
||||
val holderValue = A.holder
|
||||
if (p2 != 3 || holderValue != "getR2getR2getR2") return "fail 2: $p2 ${holderValue}"
|
||||
|
||||
A.holder = ""
|
||||
val p3 = A.test3()
|
||||
if (p3 != 3 || A.holder != "setR3setR3") return "fail 3: $p3 ${A.holder}"
|
||||
|
||||
A.holder = ""
|
||||
val p4 = A.test4()
|
||||
if (p4 != 3 || A.holder != "getR4setR4:getR4setR4getR4") return "fail 4: $p4 ${A.holder}"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
+4
-4
@@ -22,9 +22,9 @@ class WrongIncDec() {
|
||||
|
||||
fun testWrongIncDec() {
|
||||
var x = WrongIncDec()
|
||||
<!RESULT_TYPE_MISMATCH!>x++<!>
|
||||
x<!RESULT_TYPE_MISMATCH!>++<!>
|
||||
<!RESULT_TYPE_MISMATCH!>++x<!>
|
||||
<!RESULT_TYPE_MISMATCH!>x--<!>
|
||||
x<!RESULT_TYPE_MISMATCH!>--<!>
|
||||
<!RESULT_TYPE_MISMATCH!>--x<!>
|
||||
}
|
||||
|
||||
@@ -41,6 +41,6 @@ fun testUnitIncDec() {
|
||||
<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!>x
|
||||
x = x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>
|
||||
x = x<!INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!>
|
||||
x = <!INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>x
|
||||
x = <!INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!>x
|
||||
x = <!INC_DEC_SHOULD_NOT_RETURN_UNIT, INC_DEC_SHOULD_NOT_RETURN_UNIT!>++<!>x
|
||||
x = <!INC_DEC_SHOULD_NOT_RETURN_UNIT, INC_DEC_SHOULD_NOT_RETURN_UNIT!>--<!>x
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ class Test() {
|
||||
|
||||
fun testIncompleteSyntax() {
|
||||
val s = "s"
|
||||
<!UNRESOLVED_REFERENCE!>++<!>s.<!SYNTAX!><!>
|
||||
<!UNRESOLVED_REFERENCE!>++<!><!VARIABLE_EXPECTED!>s<!>.<!SYNTAX!><!>
|
||||
}
|
||||
|
||||
fun testVariables() {
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// SKIP_TXT
|
||||
// FIR_IDENTICAL
|
||||
|
||||
package foo.bar
|
||||
|
||||
var baz = 1
|
||||
|
||||
fun test() {
|
||||
foo.bar.baz++
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-56659
|
||||
|
||||
object AAA { operator fun inc(): AAA = this }
|
||||
|
||||
fun test1() {
|
||||
<!VARIABLE_EXPECTED!>AAA<!>++
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
++<!VARIABLE_EXPECTED!>AAA<!>
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
var x = AAA
|
||||
x = <!VARIABLE_EXPECTED!>AAA<!>++
|
||||
}
|
||||
|
||||
fun test4() {
|
||||
var x = AAA
|
||||
x = ++<!VARIABLE_EXPECTED!>AAA<!>
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// SKIP_TXT
|
||||
// ISSUE: KT-56659
|
||||
|
||||
object AAA { operator fun inc(): AAA = this }
|
||||
|
||||
fun test1() {
|
||||
<!VAL_REASSIGNMENT!>AAA<!>++
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
++<!VAL_REASSIGNMENT!>AAA<!>
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = AAA
|
||||
x = <!VAL_REASSIGNMENT!>AAA<!>++
|
||||
}
|
||||
|
||||
fun test4() {
|
||||
var <!ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE!>x<!> = AAA
|
||||
x = ++<!VAL_REASSIGNMENT!>AAA<!>
|
||||
}
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
// !LANGUAGE: +ForbidExtensionCallsOnInlineFunctionalParameters
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -VAL_REASSIGNMENT -UNUSED_CHANGED_VALUE -VARIABLE_EXPECTED
|
||||
|
||||
inline operator fun <T, V> Function1<T, V>.unaryPlus() = this
|
||||
operator fun <T, V> Function1<T, V>.unaryMinus() = this
|
||||
inline operator fun <T, V> Function1<T, V>.inc() = this
|
||||
operator fun <T, V> Function1<T, V>.dec() = this
|
||||
|
||||
inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.unaryPlus(){}
|
||||
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.unaryMinus(){}
|
||||
inline operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.inc() = this
|
||||
operator fun <T, V> @ExtensionFunctionType Function2<T, T, V>.dec() = this
|
||||
|
||||
inline fun <T, V> inlineFunWithInvoke(s: (p: T) -> V, ext: T.(p: T) -> V) {
|
||||
+<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>++
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>s<!>--
|
||||
<!USAGE_IS_NOT_INLINABLE!>--<!><!USAGE_IS_NOT_INLINABLE!>s<!>
|
||||
+<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
-<!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>++
|
||||
<!USAGE_IS_NOT_INLINABLE!>++<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
<!USAGE_IS_NOT_INLINABLE!>ext<!>--
|
||||
<!USAGE_IS_NOT_INLINABLE!>--<!><!USAGE_IS_NOT_INLINABLE!>ext<!>
|
||||
}
|
||||
|
||||
inline fun <T, V> Function1<T, V>.inlineFunWithInvoke() {
|
||||
+this
|
||||
-this
|
||||
this++
|
||||
++this
|
||||
this--
|
||||
--this
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +ForbidExtensionCallsOnInlineFunctionalParameters
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -NOTHING_TO_INLINE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -VAL_REASSIGNMENT -UNUSED_CHANGED_VALUE -VARIABLE_EXPECTED
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ open class A {
|
||||
fun foo() {
|
||||
<!UNRESOLVED_REFERENCE!>topLevelFun<!>()
|
||||
<!UNRESOLVED_REFERENCE!>topLevelFun<!>(1)
|
||||
<!UNRESOLVED_REFERENCE!>topLevelProperty<!><!UNRESOLVED_REFERENCE!>++<!>
|
||||
<!UNRESOLVED_REFERENCE!>topLevelProperty<!><!UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE, UNRESOLVED_REFERENCE!>++<!>
|
||||
"".<!UNRESOLVED_REFERENCE!>topLevelExtensionFun<!>()
|
||||
1.<!UNRESOLVED_REFERENCE!>topLevelExtensionFun<!>()
|
||||
"".<!UNRESOLVED_REFERENCE!>topLevelExtensionProperty<!>
|
||||
|
||||
Vendored
+12
-6
@@ -30,16 +30,22 @@ FILE: unsafeAssignmentExtra.fir.kt
|
||||
lval value: R|Foo<kotlin/Int>| = R|/myBuilder|<R|kotlin/Int|>(<L> = myBuilder@fun R|Foo<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <inline=NoInline> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.b: R|kotlin/Array<Stub (chain inference): TypeVariable(T)>|>|.R|SubstitutionOverride<kotlin/Array.set: R|kotlin/Unit|>|(Int(0), Int(123))
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(45)
|
||||
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: inc, [kotlin/inc, kotlin/inc]>#()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: inc, [kotlin/inc, kotlin/inc]>#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
R|/bar|(::R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
|
||||
when () {
|
||||
(this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| is R|kotlin/Int|) -> {
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = Int(67)
|
||||
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: dec, [kotlin/dec, kotlin/dec]>#()
|
||||
R|<local>/<unary>|
|
||||
{
|
||||
lval <unary>: R|kotlin/Int| = this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|
|
||||
this@R|special/anonymous|.R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>| = R|<local>/<unary>|.<Ambiguity: dec, [kotlin/dec, kotlin/dec]>#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
R|/bar|(::R|SubstitutionOverride</Foo.a: R|Stub (chain inference): TypeVariable(T)|>|)
|
||||
}
|
||||
}
|
||||
|
||||
+24
-21
@@ -185,22 +185,24 @@ FILE fqName:<root> fileName:/unaryOperators.kt
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:kotlin.Int) returnType:<root>.Result
|
||||
$receiver: VALUE_PARAMETER name:$this$with type:kotlin.Int
|
||||
BLOCK_BODY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun inc (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_1: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_1: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun inc (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_2: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
BLOCK type=<root>.Result origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun inc (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_1: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_1: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_2: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
BLOCK type=<root>.Result origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun inc (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_2: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_2: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
CALL 'public final fun unaryMinus (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
@@ -209,14 +211,15 @@ FILE fqName:<root> fileName:/unaryOperators.kt
|
||||
CALL 'public final fun unaryPlus (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun dec (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_3: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): <root>.Result declared in <root>.box'
|
||||
GET_VAR 'val tmp_3: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
BLOCK type=<root>.Result origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:<root>.Result [val]
|
||||
GET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=<root>.Result origin=null
|
||||
SET_VAR 'var result: <root>.Result [var] declared in <root>.box' type=kotlin.Unit origin=EQ
|
||||
CALL 'public final fun dec (_context_receiver_0: kotlin.Int): <root>.Result [operator] declared in <root>' type=<root>.Result origin=null
|
||||
$receiver: GET_VAR 'val tmp_3: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
_context_receiver_0: GET_VAR '$this$with: kotlin.Int declared in <root>.box.<anonymous>' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_3: <root>.Result [val] declared in <root>.box.<anonymous>' type=<root>.Result origin=null
|
||||
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in <root>'
|
||||
WHEN type=kotlin.String origin=IF
|
||||
BRANCH
|
||||
|
||||
+15
-9
@@ -72,17 +72,23 @@ operator fun Result.dec(_context_receiver_0: Int): Result {
|
||||
fun box(): String {
|
||||
var result: Result = Result(i = 0)
|
||||
with<Int, Result>(receiver = 1, block = local fun Int.<anonymous>(): Result {
|
||||
val <unary>: Result = result
|
||||
result = <unary>.inc(_context_receiver_0 = $this$with)
|
||||
<unary> /*~> Unit */
|
||||
val <unary>: Result = result
|
||||
result = <unary>.inc(_context_receiver_0 = $this$with)
|
||||
<unary> /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <unary>: Result = result
|
||||
result = <unary>.inc(_context_receiver_0 = $this$with)
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <unary>: Result = result
|
||||
result = <unary>.inc(_context_receiver_0 = $this$with)
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
result.unaryMinus(_context_receiver_0 = $this$with) /*~> Unit */
|
||||
result.unaryPlus(_context_receiver_0 = $this$with) /*~> Unit */
|
||||
val <unary>: Result = result
|
||||
result = <unary>.dec(_context_receiver_0 = $this$with)
|
||||
return <unary>
|
||||
return { // BLOCK
|
||||
val <unary>: Result = result
|
||||
result = <unary>.dec(_context_receiver_0 = $this$with)
|
||||
<unary>
|
||||
}
|
||||
}
|
||||
) /*~> Unit */
|
||||
return when {
|
||||
|
||||
+6
-5
@@ -104,16 +104,17 @@ FILE fqName:<root> fileName:/breakContinueInLoopHeader.kt
|
||||
WHILE label=Outer origin=WHILE_LOOP
|
||||
condition: CONST Boolean type=kotlin.Boolean value=true
|
||||
body: BLOCK type=kotlin.Unit origin=null
|
||||
SET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Unit origin=PREFIX_INCR
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
SET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Unit origin=PREFIX_INCR
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Int origin=null
|
||||
GET_VAR 'var i: kotlin.Int [var] declared in <root>.test5' type=kotlin.Int origin=null
|
||||
VAR name:j type:kotlin.Int [var]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
DO_WHILE label=Inner origin=DO_WHILE_LOOP
|
||||
body: COMPOSITE type=kotlin.Unit origin=DO_WHILE_LOOP
|
||||
body: BLOCK type=kotlin.Int origin=null
|
||||
SET_VAR 'var j: kotlin.Int [var] declared in <root>.test5' type=kotlin.Unit origin=PREFIX_INCR
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'var j: kotlin.Int [var] declared in <root>.test5' type=kotlin.Int origin=null
|
||||
|
||||
+8
-6
@@ -65,14 +65,16 @@ fun test4(ss: List<String>?) {
|
||||
fun test5() {
|
||||
var i: Int = 0
|
||||
Outer@ while (true) { // BLOCK
|
||||
i = i.inc()
|
||||
i /*~> Unit */
|
||||
{ // BLOCK
|
||||
i = i.inc()
|
||||
i
|
||||
} /*~> Unit */
|
||||
var j: Int = 0
|
||||
{ // BLOCK
|
||||
Inner@ do// COMPOSITE {
|
||||
j = j.inc()
|
||||
j
|
||||
// } while (when {
|
||||
Inner@ do{ // BLOCK
|
||||
j = j.inc()
|
||||
j
|
||||
} while (when {
|
||||
greaterOrEqual(arg0 = j, arg1 = 3) -> false
|
||||
else -> break@Inner
|
||||
})
|
||||
|
||||
@@ -111,11 +111,12 @@ FILE fqName:<root> fileName:/breakContinueInWhen.kt
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
DO_WHILE label=null origin=DO_WHILE_LOOP
|
||||
body: COMPOSITE type=kotlin.Unit origin=DO_WHILE_LOOP
|
||||
SET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Unit origin=PREFIX_INCR
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
SET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Unit origin=PREFIX_INCR
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
|
||||
GET_VAR 'var k: kotlin.Int [var] declared in <root>.testContinueDoWhile' type=kotlin.Int origin=null
|
||||
WHEN type=kotlin.Unit origin=WHEN
|
||||
BRANCH
|
||||
if: CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
|
||||
|
||||
@@ -60,8 +60,10 @@ fun testContinueDoWhile() {
|
||||
var s: String = ""
|
||||
{ // BLOCK
|
||||
do// COMPOSITE {
|
||||
k = k.inc()
|
||||
k /*~> Unit */
|
||||
{ // BLOCK
|
||||
k = k.inc()
|
||||
k
|
||||
} /*~> Unit */
|
||||
when {
|
||||
greater(arg0 = k, arg1 = 2) -> continue
|
||||
}
|
||||
|
||||
+27
-30
@@ -141,39 +141,36 @@ FILE fqName:<root> fileName:/complexAugmentedAssignment.kt
|
||||
GET_VAR 'val tmp_3: kotlin.Int [val] declared in <root>.test1' type=kotlin.Int origin=null
|
||||
FUN name:test2 visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:<root>.X1 [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x1> (): kotlin.Int declared in <root>.X1' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_4: <root>.X1 [val] declared in <root>.test2' type=<root>.X1 origin=null
|
||||
CALL 'public final fun <set-x1> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_4: <root>.X1 [val] declared in <root>.test2' type=<root>.X1 origin=null
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:<root>.X1.X2 [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x2> (): kotlin.Int declared in <root>.X1.X2' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_6: <root>.X1.X2 [val] declared in <root>.test2' type=<root>.X1.X2 origin=null
|
||||
CALL 'public final fun <set-x2> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1.X2' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_6: <root>.X1.X2 [val] declared in <root>.test2' type=<root>.X1.X2 origin=null
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x1> (): kotlin.Int declared in <root>.X1' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1
|
||||
CALL 'public final fun <set-x1> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1' type=kotlin.Unit origin=EQ
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X1 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_7: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:<root>.X1.X2.X3 [val]
|
||||
GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2.X3
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x3> (): kotlin.Int declared in <root>.X1.X2.X3' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_8: <root>.X1.X2.X3 [val] declared in <root>.test2' type=<root>.X1.X2.X3 origin=null
|
||||
CALL 'public final fun <set-x3> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1.X2.X3' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_8: <root>.X1.X2.X3 [val] declared in <root>.test2' type=<root>.X1.X2.X3 origin=null
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_9: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x2> (): kotlin.Int declared in <root>.X1.X2' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2
|
||||
CALL 'public final fun <set-x2> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1.X2' type=kotlin.Unit origin=EQ
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X2 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_9: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-x3> (): kotlin.Int declared in <root>.X1.X2.X3' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2.X3
|
||||
CALL 'public final fun <set-x3> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>.X1.X2.X3' type=kotlin.Unit origin=EQ
|
||||
$this: GET_OBJECT 'CLASS OBJECT name:X3 modality:FINAL visibility:public superTypes:[kotlin.Any]' type=<root>.X1.X2.X3
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_6: kotlin.Int [val] declared in <root>.test2' type=kotlin.Int origin=null
|
||||
CLASS CLASS name:B modality:FINAL visibility:public superTypes:[kotlin.Any]
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.B
|
||||
CONSTRUCTOR visibility:public <> (s:kotlin.Int) returnType:<root>.B [primary]
|
||||
|
||||
+15
-12
@@ -54,18 +54,21 @@ fun test1(a: IntArray) {
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
val <receiver>: X1 = X1
|
||||
val <unary>: Int = <receiver>.<get-x1>()
|
||||
<receiver>.<set-x1>(<set-?> = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
val <receiver>: X2 = X2
|
||||
val <unary>: Int = <receiver>.<get-x2>()
|
||||
<receiver>.<set-x2>(<set-?> = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
val <receiver>: X3 = X3
|
||||
val <unary>: Int = <receiver>.<get-x3>()
|
||||
<receiver>.<set-x3>(<set-?> = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <unary>: Int = X1.<get-x1>()
|
||||
X1.<set-x1>(<set-?> = <unary>.inc())
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <unary>: Int = X2.<get-x2>()
|
||||
X2.<set-x2>(<set-?> = <unary>.inc())
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <unary>: Int = X3.<get-x3>()
|
||||
X3.<set-x3>(<set-?> = <unary>.inc())
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
}
|
||||
|
||||
class B {
|
||||
|
||||
@@ -67,58 +67,48 @@ FILE fqName:<root> fileName:/incrementDecrement.kt
|
||||
BLOCK_BODY
|
||||
VAR name:p1 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testPropPrefix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testPropPrefix' type=kotlin.Int origin=null
|
||||
VAR name:p2 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val]
|
||||
CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: GET_VAR 'val tmp_3: kotlin.Int [val] declared in <root>.testPropPrefix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_3: kotlin.Int [val] declared in <root>.testPropPrefix' type=kotlin.Int origin=null
|
||||
FUN name:testPropPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:p1 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_2: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
VAR name:p2 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in <root>' type=kotlin.Int origin=GET_PROPERTY
|
||||
CALL 'public final fun <set-p> (<set-?>: kotlin.Int): kotlin.Unit declared in <root>' type=kotlin.Unit origin=EQ
|
||||
<set-?>: GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.testPropPostfix' type=kotlin.Int origin=null
|
||||
FUN name:testArrayPrefix visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:a1 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.IntArray [val]
|
||||
CALL 'public final fun <get-arr> (): kotlin.IntArray declared in <root>' type=kotlin.IntArray origin=GET_PROPERTY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_3: kotlin.IntArray [val] declared in <root>.testArrayPrefix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'val tmp_3: kotlin.IntArray [val] declared in <root>.testArrayPrefix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_4: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
value: GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_5: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
VAR name:a2 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.IntArray [val]
|
||||
CALL 'public final fun <get-arr> (): kotlin.IntArray declared in <root>' type=kotlin.IntArray origin=GET_PROPERTY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Int [val]
|
||||
CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_6: kotlin.IntArray [val] declared in <root>.testArrayPrefix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_7: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
@@ -127,25 +117,25 @@ FILE fqName:<root> fileName:/incrementDecrement.kt
|
||||
index: GET_VAR 'val tmp_7: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
value: GET_VAR 'val tmp_8: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_8: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
FUN name:testArrayPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:a1 type:kotlin.Int [val]
|
||||
VAR name:a2 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:kotlin.IntArray [val]
|
||||
CALL 'public final fun <get-arr> (): kotlin.IntArray declared in <root>' type=kotlin.IntArray origin=GET_PROPERTY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Int [val]
|
||||
CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in <root>.testArrayPostfix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in <root>.testArrayPrefix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in <root>.testArrayPostfix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_11: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_11: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
VAR name:a2 type:kotlin.Int [val]
|
||||
$this: GET_VAR 'val tmp_9: kotlin.IntArray [val] declared in <root>.testArrayPrefix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_10: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
value: GET_VAR 'val tmp_11: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_11: kotlin.Int [val] declared in <root>.testArrayPrefix' type=kotlin.Int origin=null
|
||||
FUN name:testArrayPostfix visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:a1 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_12 type:kotlin.IntArray [val]
|
||||
CALL 'public final fun <get-arr> (): kotlin.IntArray declared in <root>' type=kotlin.IntArray origin=GET_PROPERTY
|
||||
@@ -158,6 +148,22 @@ FILE fqName:<root> fileName:/incrementDecrement.kt
|
||||
CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'val tmp_12: kotlin.IntArray [val] declared in <root>.testArrayPostfix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_13: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
value: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_14: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_14: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
VAR name:a2 type:kotlin.Int [val]
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_15 type:kotlin.IntArray [val]
|
||||
CALL 'public final fun <get-arr> (): kotlin.IntArray declared in <root>' type=kotlin.IntArray origin=GET_PROPERTY
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_16 type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_17 type:kotlin.Int [val]
|
||||
CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in kotlin.IntArray' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_15: kotlin.IntArray [val] declared in <root>.testArrayPostfix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_16: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in kotlin.IntArray' type=kotlin.Unit origin=null
|
||||
$this: GET_VAR 'val tmp_15: kotlin.IntArray [val] declared in <root>.testArrayPostfix' type=kotlin.IntArray origin=null
|
||||
index: GET_VAR 'val tmp_16: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
value: CALL 'public final fun dec (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_17: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_17: kotlin.Int [val] declared in <root>.testArrayPostfix' type=kotlin.Int origin=null
|
||||
|
||||
@@ -35,12 +35,14 @@ fun testVarPostfix() {
|
||||
|
||||
fun testPropPrefix() {
|
||||
val p1: Int = { // BLOCK
|
||||
<set-p>(<set-?> = <get-p>().inc())
|
||||
<get-p>()
|
||||
val <unary-result>: Int = <get-p>().inc()
|
||||
<set-p>(<set-?> = <unary-result>)
|
||||
<unary-result>
|
||||
}
|
||||
val p2: Int = { // BLOCK
|
||||
<set-p>(<set-?> = <get-p>().dec())
|
||||
<get-p>()
|
||||
val <unary-result>: Int = <get-p>().dec()
|
||||
<set-p>(<set-?> = <unary-result>)
|
||||
<unary-result>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +53,9 @@ fun testPropPostfix() {
|
||||
<unary>
|
||||
}
|
||||
val p2: Int = { // BLOCK
|
||||
<set-p>(<set-?> = <get-p>().dec())
|
||||
<get-p>()
|
||||
val <unary-result>: Int = <get-p>().dec()
|
||||
<set-p>(<set-?> = <unary-result>)
|
||||
<unary-result>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-10
@@ -9,17 +9,18 @@ FILE fqName:<root> fileName:/javaSyntheticGenericPropertyAccess.kt
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'j: <root>.J<F of <root>.test> declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
x: CONST Int type=kotlin.Int value=1
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.J<F of <root>.test> [val]
|
||||
GET_VAR 'j: <root>.J<F of <root>.test> declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val]
|
||||
CALL 'public open fun getFoo (): kotlin.Int declared in <root>.J' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_0: <root>.J<F of <root>.test> [val] declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_0: <root>.J<F of <root>.test> [val] declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.J<F of <root>.test> [val]
|
||||
GET_VAR 'j: <root>.J<F of <root>.test> declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val]
|
||||
CALL 'public open fun getFoo (): kotlin.Int declared in <root>.J' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_0: <root>.J<F of <root>.test> [val] declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_0: <root>.J<F of <root>.test> [val] declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'j: <root>.J<F of <root>.test> declared in <root>.test' type=<root>.J<F of <root>.test> origin=null
|
||||
x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
|
||||
+6
-4
@@ -1,9 +1,11 @@
|
||||
fun <F : Any?> test(j: J<F>) {
|
||||
j.getFoo() /*~> Unit */
|
||||
j.setFoo(x = 1)
|
||||
val <receiver>: J<F> = j
|
||||
val <unary>: Int = <receiver>.getFoo()
|
||||
<receiver>.setFoo(x = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <receiver>: J<F> = j
|
||||
val <unary>: Int = <receiver>.getFoo()
|
||||
<receiver>.setFoo(x = <unary>.inc())
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
j.setFoo(x = j.getFoo().plus(other = 1))
|
||||
}
|
||||
|
||||
+11
-10
@@ -8,17 +8,18 @@ FILE fqName:<root> fileName:/javaSyntheticPropertyAccess.kt
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'j: <root>.J declared in <root>.test' type=<root>.J origin=null
|
||||
x: CONST Int type=kotlin.Int value=1
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.J [val]
|
||||
GET_VAR 'j: <root>.J declared in <root>.test' type=<root>.J origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val]
|
||||
CALL 'public open fun getFoo (): kotlin.Int declared in <root>.J' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_0: <root>.J [val] declared in <root>.test' type=<root>.J origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_0: <root>.J [val] declared in <root>.test' type=<root>.J origin=null
|
||||
x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:<root>.J [val]
|
||||
GET_VAR 'j: <root>.J declared in <root>.test' type=<root>.J origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val]
|
||||
CALL 'public open fun getFoo (): kotlin.Int declared in <root>.J' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR 'val tmp_0: <root>.J [val] declared in <root>.test' type=<root>.J origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'val tmp_0: <root>.J [val] declared in <root>.test' type=<root>.J origin=null
|
||||
x: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_1: kotlin.Int [val] declared in <root>.test' type=kotlin.Int origin=null
|
||||
CALL 'public open fun setFoo (x: kotlin.Int): kotlin.Unit declared in <root>.J' type=kotlin.Unit origin=EQ
|
||||
$this: GET_VAR 'j: <root>.J declared in <root>.test' type=<root>.J origin=null
|
||||
x: CALL 'public final fun plus (other: kotlin.Int): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
|
||||
+6
-4
@@ -1,9 +1,11 @@
|
||||
fun test(j: J) {
|
||||
j.getFoo() /*~> Unit */
|
||||
j.setFoo(x = 1)
|
||||
val <receiver>: J = j
|
||||
val <unary>: Int = <receiver>.getFoo()
|
||||
<receiver>.setFoo(x = <unary>.inc())
|
||||
<unary> /*~> Unit */
|
||||
{ // BLOCK
|
||||
val <receiver>: J = j
|
||||
val <unary>: Int = <receiver>.getFoo()
|
||||
<receiver>.setFoo(x = <unary>.inc())
|
||||
<unary>
|
||||
} /*~> Unit */
|
||||
j.setFoo(x = j.getFoo().plus(other = 1))
|
||||
}
|
||||
|
||||
+17
-19
@@ -74,44 +74,42 @@ FILE fqName:test fileName:/safeCallWithIncrementDecrement.kt
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:test.C [val]
|
||||
GET_VAR 'val tmp_1: test.C? [val] declared in test.testProperty' type=test.C? origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY
|
||||
$receiver: GET_VAR 'val tmp_2: test.C [val] declared in test.testProperty' type=test.C origin=null
|
||||
$receiver: GET_VAR 'val tmp_1: test.C? [val] declared in test.testProperty' type=test.C? origin=null
|
||||
CALL 'public final fun <set-p> (value: kotlin.Int): kotlin.Unit declared in test' type=kotlin.Unit origin=EQ
|
||||
$receiver: GET_VAR 'val tmp_2: test.C [val] declared in test.testProperty' type=test.C origin=null
|
||||
$receiver: GET_VAR 'val tmp_1: test.C? [val] declared in test.testProperty' type=test.C? origin=null
|
||||
value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_3: kotlin.Int [val] declared in test.testProperty' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_3: kotlin.Int [val] declared in test.testProperty' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_2: kotlin.Int [val] declared in test.testProperty' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_2: kotlin.Int [val] declared in test.testProperty' type=kotlin.Int origin=null
|
||||
FUN name:testArrayAccess visibility:public modality:FINAL <> (nc:test.C?) returnType:kotlin.Unit
|
||||
VALUE_PARAMETER name:nc index:0 type:test.C?
|
||||
BLOCK_BODY
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
BLOCK type=kotlin.Int? origin=SAFE_CALL
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:test.C? [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:test.C? [val]
|
||||
GET_VAR 'nc: test.C? declared in test.testArrayAccess' type=test.C? origin=null
|
||||
WHEN type=kotlin.Int? origin=null
|
||||
BRANCH
|
||||
if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
arg0: GET_VAR 'val tmp_4: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null
|
||||
arg0: GET_VAR 'val tmp_3: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null
|
||||
arg1: CONST Null type=kotlin.Nothing? value=null
|
||||
then: CONST Null type=kotlin.Nothing? value=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: BLOCK type=kotlin.Int origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_4 type:kotlin.Int [val]
|
||||
CALL 'public final fun <get-p> (): kotlin.Int declared in test' type=kotlin.Int origin=GET_PROPERTY
|
||||
$receiver: GET_VAR 'val tmp_4: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val]
|
||||
$receiver: GET_VAR 'val tmp_3: test.C? [val] declared in test.testArrayAccess' type=test.C? origin=null
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_5 type:kotlin.Int [val]
|
||||
CONST Int type=kotlin.Int value=0
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Int [val]
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_6 type:kotlin.Int [val]
|
||||
CALL 'public final fun get (index: kotlin.Int): kotlin.Int [operator] declared in test' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_5: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
index: GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_4: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
index: GET_VAR 'val tmp_5: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
CALL 'public final fun set (index: kotlin.Int, value: kotlin.Int): kotlin.Unit [operator] declared in test' type=kotlin.Unit origin=null
|
||||
$receiver: GET_VAR 'val tmp_5: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
index: GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
$receiver: GET_VAR 'val tmp_4: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
index: GET_VAR 'val tmp_5: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
value: CALL 'public final fun inc (): kotlin.Int [operator] declared in kotlin.Int' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_7: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_7: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
$this: GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
GET_VAR 'val tmp_6: kotlin.Int [val] declared in test.testArrayAccess' type=kotlin.Int origin=null
|
||||
|
||||
+2
-3
@@ -39,9 +39,8 @@ fun testProperty(nc: C?) {
|
||||
when {
|
||||
EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null
|
||||
else -> { // BLOCK
|
||||
val <receiver>: C = tmp1_safe_receiver
|
||||
val <unary>: Int = <receiver>.<get-p>()
|
||||
<receiver>.<set-p>(value = <unary>.inc())
|
||||
val <unary>: Int = tmp1_safe_receiver.<get-p>()
|
||||
tmp1_safe_receiver.<set-p>(value = <unary>.inc())
|
||||
<unary>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ FILE fqName:<root> fileName:/whileDoWhile.kt
|
||||
arg1: CONST Int type=kotlin.Int value=15
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
DO_WHILE label=null origin=DO_WHILE_LOOP
|
||||
body: COMPOSITE type=kotlin.Unit origin=DO_WHILE_LOOP
|
||||
body: BLOCK type=kotlin.Int origin=POSTFIX_INCR
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.Int [val]
|
||||
GET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Int origin=null
|
||||
SET_VAR 'var x: kotlin.Int [var] declared in <root>.test' type=kotlin.Unit origin=POSTFIX_INCR
|
||||
|
||||
@@ -24,11 +24,11 @@ fun test() {
|
||||
} while (less(arg0 = x, arg1 = 15))
|
||||
}
|
||||
{ // BLOCK
|
||||
do// COMPOSITE {
|
||||
val <unary>: Int = x
|
||||
x = <unary>.inc()
|
||||
<unary>
|
||||
// } while (less(arg0 = x, arg1 = 20))
|
||||
do{ // BLOCK
|
||||
val <unary>: Int = x
|
||||
x = <unary>.inc()
|
||||
<unary>
|
||||
} while (less(arg0 = x, arg1 = 20))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -543,7 +543,7 @@ FILE fqName:<root> fileName:/ArrayMap.kt
|
||||
BLOCK_BODY
|
||||
BLOCK type=kotlin.Unit origin=null
|
||||
DO_WHILE label=null origin=DO_WHILE_LOOP
|
||||
body: COMPOSITE type=kotlin.Unit origin=DO_WHILE_LOOP
|
||||
body: BLOCK type=kotlin.Int origin=POSTFIX_INCR
|
||||
VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.Int [val]
|
||||
CALL 'private final fun <get-index> (): kotlin.Int declared in <root>.ArrayMapImpl.iterator.<no name provided>' type=kotlin.Int origin=GET_PROPERTY
|
||||
$this: GET_VAR '<this>: <root>.ArrayMapImpl.iterator.<no name provided><T of <root>.ArrayMapImpl> declared in <root>.ArrayMapImpl.iterator.<no name provided>.computeNext' type=<root>.ArrayMapImpl.iterator.<no name provided><T of <root>.ArrayMapImpl> origin=null
|
||||
|
||||
@@ -224,11 +224,11 @@ internal class ArrayMapImpl<T : Any> : ArrayMap<T> {
|
||||
|
||||
protected override fun computeNext() {
|
||||
{ // BLOCK
|
||||
do// COMPOSITE {
|
||||
val <unary>: Int = <this>.<get-index>()
|
||||
<this>.<set-index>(<set-?> = <unary>.inc())
|
||||
<unary>
|
||||
// } while (when {
|
||||
do{ // BLOCK
|
||||
val <unary>: Int = <this>.<get-index>()
|
||||
<this>.<set-index>(<set-?> = <unary>.inc())
|
||||
<unary>
|
||||
} while (when {
|
||||
less(arg0 = <this>.<get-index>(), arg1 = <this>.<get-data>().<get-size>()) -> EQEQ(arg0 = <this>.<get-data>().get(index = <this>.<get-index>()), arg1 = null)
|
||||
else -> false
|
||||
})
|
||||
|
||||
Generated
+12
@@ -357,6 +357,18 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/IncorrectCharacterLiterals.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnFullyQualified.kt")
|
||||
public void testIncrementDecrementOnFullyQualified() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnFullyQualified.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incrementDecrementOnObject.kt")
|
||||
public void testIncrementDecrementOnObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/incrementDecrementOnObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("InferNullabilityInThenBlock.kt")
|
||||
public void testInferNullabilityInThenBlock() throws Exception {
|
||||
|
||||
+18
@@ -25913,6 +25913,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -46811,12 +46817,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -26873,6 +26873,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -49043,12 +49049,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+15
@@ -21801,6 +21801,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/rangeFromCollection.kt");
|
||||
@@ -37903,11 +37908,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/inheritedPropertyInClassObject.kt");
|
||||
|
||||
+2
-2
@@ -5,7 +5,7 @@
|
||||
|
||||
fun case1() {
|
||||
var a = Case1()
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>++a<!>
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>++<!>a
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ class B() {}
|
||||
|
||||
fun case2() {
|
||||
var a = Case2()
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>++a<!>
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>++<!>a
|
||||
}
|
||||
|
||||
class Case2() : C() {
|
||||
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
|
||||
// TESTCASE NUMBER: 1
|
||||
|
||||
fun case1() {
|
||||
var a = Case1()
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>--a<!>
|
||||
}
|
||||
|
||||
|
||||
class Case1() {
|
||||
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): B {
|
||||
TODO()
|
||||
}
|
||||
}
|
||||
|
||||
class B() {}
|
||||
|
||||
// TESTCASE NUMBER: 2
|
||||
|
||||
fun case2() {
|
||||
var a = Case2()
|
||||
val res: Any? = <!RESULT_TYPE_MISMATCH!>--a<!>
|
||||
}
|
||||
|
||||
class Case2() : C() {
|
||||
var i = 0
|
||||
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun dec(): C {
|
||||
TODO()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class C() {}
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
// SKIP_TXT
|
||||
// FIR_IDENTICAL
|
||||
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
|
||||
+18
@@ -20821,6 +20821,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -34723,12 +34729,24 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -20839,6 +20839,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -34909,12 +34915,24 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -20839,6 +20839,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -34909,12 +34915,24 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -20839,6 +20839,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -34909,12 +34915,24 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -23762,6 +23762,12 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -38492,12 +38498,24 @@ public class K2NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTes
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
+18
@@ -23540,6 +23540,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
@@ -38012,12 +38018,24 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
|
||||
Generated
+15
@@ -18449,6 +18449,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDec.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("prefixIncDecFir.kt")
|
||||
public void testPrefixIncDecFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/prefixIncDecFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("rangeFromCollection.kt")
|
||||
public void testRangeFromCollection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/intrinsics/rangeFromCollection.kt");
|
||||
@@ -31263,11 +31268,21 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInClassObjectFir.kt")
|
||||
public void testIncInClassObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInClassObjectFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInObject.kt")
|
||||
public void testIncInObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("incInObjectFir.kt")
|
||||
public void testIncInObjectFir() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/incInObjectFir.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inheritedPropertyInClassObject.kt")
|
||||
public void testInheritedPropertyInClassObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/statics/inheritedPropertyInClassObject.kt");
|
||||
|
||||
Reference in New Issue
Block a user