From 458080ca8b3764bdca7ccc6d026040db217fd95c Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Thu, 25 Apr 2019 15:50:33 +0300 Subject: [PATCH] Raw FIR: create resolved references for desugared temporary variables --- .../kotlin/fir/builder/ConversionUtils.kt | 46 ++++++++++++++++--- .../kotlin/fir/builder/RawFirBuilder.kt | 17 +++---- .../rawBuilder/expressions/annotated.txt | 4 +- .../rawBuilder/expressions/destructuring.txt | 10 ++-- .../testData/rawBuilder/expressions/for.txt | 28 +++++------ .../rawBuilder/expressions/lambda.txt | 4 +- .../rawBuilder/expressions/nullability.txt | 4 +- .../testData/rawBuilder/expressions/unary.txt | 42 ++++++++--------- .../testData/rawBuilder/expressions/while.txt | 12 ++--- 9 files changed, 100 insertions(+), 67 deletions(-) diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt index b0db9682edd..8b131fb5f82 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/ConversionUtils.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirExplicitThisReference +import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.FirTypeRef @@ -196,7 +197,7 @@ internal fun FirExpression.generateNotNullOrOther( ) branches += FirWhenBranchImpl( session, other.psi, FirElseIfTrueCondition(session, psi), - FirSingleExpressionBlock(session, generateAccessExpression(session, psi, subjectName)) + FirSingleExpressionBlock(session, generateResolvedAccessExpression(session, psi, subjectVariable)) ) } } @@ -343,6 +344,31 @@ internal fun FirExpression.generateContainsOperation( } } + +/** + * given: + * argument++ + * + * result: + * { + * val = argument + * argument = .inc() + * ^ + * } + * + * given: + * ++argument + * + * result: + * { + * val = argument + * argument = .inc() + * ^argument + * } + * + */ + +// TODO: Refactor, support receiver capturing in case of a.b internal fun generateIncrementOrDecrementBlock( session: FirSession, baseExpression: KtUnaryExpression, @@ -356,17 +382,18 @@ internal fun generateIncrementOrDecrementBlock( } return FirBlockImpl(session, baseExpression).apply { val tempName = Name.special("") - statements += generateTemporaryVariable(session, baseExpression, tempName, argument.convert()) + val temporaryVariable = generateTemporaryVariable(session, baseExpression, tempName, argument.convert()) + statements += temporaryVariable val resultName = Name.special("") val resultInitializer = FirFunctionCallImpl(session, baseExpression).apply { this.calleeReference = FirSimpleNamedReference(session, baseExpression.operationReference, callName) - this.explicitReceiver = generateAccessExpression(session, baseExpression, tempName) + this.explicitReceiver = generateResolvedAccessExpression(session, baseExpression, temporaryVariable) } val resultVar = generateTemporaryVariable(session, baseExpression, resultName, resultInitializer) val assignment = argument.generateAssignment( session, baseExpression, if (prefix && argument !is KtSimpleNameExpression) - generateAccessExpression(session, baseExpression, resultName) + generateResolvedAccessExpression(session, baseExpression, resultVar) else resultInitializer, FirOperation.ASSIGN, convert @@ -384,14 +411,14 @@ internal fun generateIncrementOrDecrementBlock( if (argument !is KtSimpleNameExpression) { statements += resultVar appendAssignment() - statements += generateAccessExpression(session, baseExpression, resultName) + statements += generateResolvedAccessExpression(session, baseExpression, resultVar) } else { appendAssignment() statements += generateAccessExpression(session, baseExpression, argument.getReferencedNameAsName()) } } else { appendAssignment() - statements += generateAccessExpression(session, baseExpression, tempName) + statements += generateResolvedAccessExpression(session, baseExpression, temporaryVariable) } } } @@ -401,6 +428,11 @@ internal fun generateAccessExpression(session: FirSession, psi: PsiElement?, nam calleeReference = FirSimpleNamedReference(session, psi, name) } +internal fun generateResolvedAccessExpression(session: FirSession, psi: PsiElement?, variable: FirVariable): FirQualifiedAccessExpression = + FirQualifiedAccessExpressionImpl(session, psi).apply { + calleeReference = FirResolvedCallableReferenceImpl(session, psi, variable.name, variable.symbol) + } + internal fun generateDestructuringBlock( session: FirSession, multiDeclaration: KtDestructuringDeclaration, @@ -418,7 +450,7 @@ internal fun generateDestructuringBlock( statements += FirVariableImpl( session, entry, entry.nameAsSafeName, entry.typeReference.toFirOrImplicitTypeRef(), isVar, - FirComponentCallImpl(session, entry, index + 1, generateAccessExpression(session, entry, container.name)), + FirComponentCallImpl(session, entry, index + 1, generateResolvedAccessExpression(session, entry, container)), FirVariableSymbol(entry.nameAsSafeName) // TODO? ).apply { entry.extractAnnotationsTo(this) diff --git a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 9793c08c429..f0cbf46e23f 100644 --- a/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -1091,21 +1091,22 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { val rangeExpression = expression.loopRange.toFirExpression("No range in for loop") val parameter = expression.loopParameter return FirBlockImpl(session, expression).apply { - val rangeName = Name.special("") - statements += generateTemporaryVariable(this@RawFirBuilder.session, expression.loopRange, rangeName, rangeExpression) - val iteratorName = Name.special("") - statements += generateTemporaryVariable( - this@RawFirBuilder.session, expression.loopRange, iteratorName, + val rangeVal = + generateTemporaryVariable(this@RawFirBuilder.session, expression.loopRange, Name.special(""), rangeExpression) + statements += rangeVal + val iteratorVal = generateTemporaryVariable( + this@RawFirBuilder.session, expression.loopRange, Name.special(""), FirFunctionCallImpl(this@RawFirBuilder.session, expression).apply { calleeReference = FirSimpleNamedReference(this@RawFirBuilder.session, expression, Name.identifier("iterator")) - explicitReceiver = generateAccessExpression(this@RawFirBuilder.session, expression.loopRange, rangeName) + explicitReceiver = generateResolvedAccessExpression(this@RawFirBuilder.session, expression.loopRange, rangeVal) } ) + statements += iteratorVal statements += FirWhileLoopImpl( this@RawFirBuilder.session, expression, FirFunctionCallImpl(this@RawFirBuilder.session, expression).apply { calleeReference = FirSimpleNamedReference(this@RawFirBuilder.session, expression, Name.identifier("hasNext")) - explicitReceiver = generateAccessExpression(this@RawFirBuilder.session, expression, iteratorName) + explicitReceiver = generateResolvedAccessExpression(this@RawFirBuilder.session, expression, iteratorVal) } ).configure { // NB: just body.toFirBlock() isn't acceptable here because we need to add some statements @@ -1121,7 +1122,7 @@ class RawFirBuilder(val session: FirSession, val stubMode: Boolean) { if (multiDeclaration != null) Name.special("") else parameter.nameAsSafeName, FirFunctionCallImpl(this@RawFirBuilder.session, expression).apply { calleeReference = FirSimpleNamedReference(this@RawFirBuilder.session, expression, Name.identifier("next")) - explicitReceiver = generateAccessExpression(this@RawFirBuilder.session, expression, iteratorName) + explicitReceiver = generateResolvedAccessExpression(this@RawFirBuilder.session, expression, iteratorVal) } ) if (multiDeclaration != null) { diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt index 8485bc6a94d..95cee7bdbb9 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/annotated.txt @@ -32,6 +32,6 @@ FILE: annotated.kt } public? final? fun bar(two: Two): kotlin/Unit { lval : = two# - @Ann() lval x: = #.component1() - @Ann() lval y: = #.component2() + @Ann() lval x: = R|/|.component1() + @Ann() lval y: = R|/|.component2() } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt index b3d786a1b22..dd6f4395180 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/destructuring.txt @@ -28,12 +28,12 @@ FILE: destructuring.kt } public? final? fun foo(some: Some): kotlin/Unit { lval : = some# - lvar x: = #.component1() - lvar y: = #.component2() - lvar z: String = #.component3() + lvar x: = R|/|.component1() + lvar y: = R|/|.component2() + lvar z: String = R|/|.component3() lval : = x# - x# = #.inc#() - # + x# = R|/|.inc#() + R|/| y# *= Double(2.0) z# = String() } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt index 52e6dd89a23..ea74e083be1 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/for.txt @@ -1,25 +1,25 @@ FILE: for.kt public? final? fun foo(): kotlin/Unit { lval : = Int(1).rangeTo#(Int(10)) - lval : = #.iterator#() - while(#.hasNext#()) { - lval i: = #.next#() + lval : = R|/|.iterator#() + while(R|/|.hasNext#()) { + lval i: = R|/|.next#() println#(i#) } } public? final? fun bar(list: List): kotlin/Unit { lval : = list#.subList#(Int(0), Int(10)) - lval : = #.iterator#() - while(#.hasNext#()) { - lval element: = #.next#() + lval : = R|/|.iterator#() + while(R|/|.hasNext#()) { + lval element: = R|/|.next#() println#(element#) } lval : = list#.subList#(Int(10), Int(20)) - lval : = #.iterator#() - while(#.hasNext#()) { - lval element: = #.next#() + lval : = R|/|.iterator#() + while(R|/|.hasNext#()) { + lval element: = R|/|.next#() println#(element#) } @@ -46,11 +46,11 @@ FILE: for.kt } public? final? fun baz(set: Set): kotlin/Unit { lval : = set# - lval : = #.iterator#() - while(#.hasNext#()) { - lval : = #.next#() - lval x: = #.component1() - lval y: = #.component2() + lval : = R|/|.iterator#() + while(R|/|.hasNext#()) { + lval : = R|/|.next#() + lval x: = R|/|.component1() + lval y: = R|/|.component2() println#((String(x = ), x#, String( y = ), y#)) } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt index 9817dd99d41..55f54d7c11a 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/lambda.txt @@ -30,8 +30,8 @@ FILE: lambda.kt } use#( = use@fun .(: ): { - lval x: = #.component1() - lval y: = #.component2() + lval x: = R|/|.component1() + lval y: = R|/|.component2() x#.plus#(y#) } ) diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt index 19d62fdd6eb..077f1c780d6 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/nullability.txt @@ -5,7 +5,7 @@ FILE: nullability.kt Int(42) } else -> { - # + R|/| } } @@ -16,7 +16,7 @@ FILE: nullability.kt throw KotlinNullPointerException#() } else -> { - # + R|/| } } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt index c95de571cb8..ad30a1c7f53 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/unary.txt @@ -3,26 +3,26 @@ FILE: unary.kt lvar x: = Int(0) lval x1: = { lval : = x# - x# = #.inc#() - # + x# = R|/|.inc#() + R|/| } lval x2: = { lval : = x# - x# = #.inc#() + x# = R|/|.inc#() x# } lval x3: = { lval : = x# - x# = #.dec#() + x# = R|/|.dec#() x# } lval x4: = { lval : = x# - x# = #.dec#() - # + x# = R|/|.dec#() + R|/| } when () { @@ -46,30 +46,30 @@ FILE: unary.kt public? final? fun test2(x: X): kotlin/Unit { lval x1: = { lval : = x#.i# - x#.i# = #.inc#() - # + x#.i# = R|/|.inc#() + R|/| } lval x2: = { lval : = x#.i# - lval : = #.inc#() - x#.i# = # - # + lval : = R|/|.inc#() + x#.i# = R|/| + R|/| } } public? final? fun test3(arr: Array): kotlin/Unit { lval x1: = { lval : = arr#.get#(Int(0)) - arr#.set#(Int(0), #.inc#()) - # + arr#.set#(Int(0), R|/|.inc#()) + R|/| } lval x2: = { lval : = arr#.get#(Int(1)) - lval : = #.inc#() - arr#.set#(Int(1), #) - # + lval : = R|/|.inc#() + arr#.set#(Int(1), R|/|) + R|/| } } @@ -85,15 +85,15 @@ FILE: unary.kt public? final? fun test4(y: Y): kotlin/Unit { lval x1: = { lval : = y#.arr#.get#(Int(0)) - y#.arr#.set#(Int(0), #.inc#()) - # + y#.arr#.set#(Int(0), R|/|.inc#()) + R|/| } lval x2: = { lval : = y#.arr#.get#(Int(1)) - lval : = #.inc#() - y#.arr#.set#(Int(1), #) - # + lval : = R|/|.inc#() + y#.arr#.set#(Int(1), R|/|) + R|/| } } diff --git a/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt b/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt index c960ba73128..11f9ce8adce 100644 --- a/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt +++ b/compiler/fir/psi2fir/testData/rawBuilder/expressions/while.txt @@ -3,13 +3,13 @@ FILE: while.kt lvar k: = Int(0) some@while(<(k#, limit#)) { lval : = k# - k# = #.inc#() - # + k# = R|/|.inc#() + R|/| println#(k#) while(==(k#, Int(13))) { lval : = k# - k# = #.inc#() - # + k# = R|/|.inc#() + R|/| when () { <(k#, limit#) -> { break@@@[<(k#, limit#)] @@ -35,8 +35,8 @@ FILE: while.kt lvar k: = limit# do { lval : = k# - k# = #.dec#() - # + k# = R|/|.dec#() + R|/| println#(k#) } while(>=(k#, Int(0)))