Raw FIR: create resolved references for desugared temporary variables
This commit is contained in:
committed by
Mikhail Glukhikh
parent
99994e6c41
commit
458080ca8b
@@ -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 <unary> = argument
|
||||
* argument = <unary>.inc()
|
||||
* ^<unary>
|
||||
* }
|
||||
*
|
||||
* given:
|
||||
* ++argument
|
||||
*
|
||||
* result:
|
||||
* {
|
||||
* val <unary> = argument
|
||||
* argument = <unary>.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("<unary>")
|
||||
statements += generateTemporaryVariable(session, baseExpression, tempName, argument.convert())
|
||||
val temporaryVariable = generateTemporaryVariable(session, baseExpression, tempName, argument.convert())
|
||||
statements += temporaryVariable
|
||||
val resultName = Name.special("<unary-result>")
|
||||
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)
|
||||
|
||||
@@ -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("<range>")
|
||||
statements += generateTemporaryVariable(this@RawFirBuilder.session, expression.loopRange, rangeName, rangeExpression)
|
||||
val iteratorName = Name.special("<iterator>")
|
||||
statements += generateTemporaryVariable(
|
||||
this@RawFirBuilder.session, expression.loopRange, iteratorName,
|
||||
val rangeVal =
|
||||
generateTemporaryVariable(this@RawFirBuilder.session, expression.loopRange, Name.special("<range>"), rangeExpression)
|
||||
statements += rangeVal
|
||||
val iteratorVal = generateTemporaryVariable(
|
||||
this@RawFirBuilder.session, expression.loopRange, Name.special("<iterator>"),
|
||||
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("<destruct>") 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) {
|
||||
|
||||
@@ -32,6 +32,6 @@ FILE: annotated.kt
|
||||
}
|
||||
public? final? fun bar(two: Two): kotlin/Unit {
|
||||
lval <destruct>: <implicit> = two#
|
||||
@Ann() lval x: <implicit> = <destruct>#.component1()
|
||||
@Ann() lval y: <implicit> = <destruct>#.component2()
|
||||
@Ann() lval x: <implicit> = R|<local>/<destruct>|.component1()
|
||||
@Ann() lval y: <implicit> = R|<local>/<destruct>|.component2()
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ FILE: destructuring.kt
|
||||
}
|
||||
public? final? fun foo(some: Some): kotlin/Unit {
|
||||
lval <destruct>: <implicit> = some#
|
||||
lvar x: <implicit> = <destruct>#.component1()
|
||||
lvar y: <implicit> = <destruct>#.component2()
|
||||
lvar z: String = <destruct>#.component3()
|
||||
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# = <unary>#.inc#()
|
||||
<unary>#
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
y# *= Double(2.0)
|
||||
z# = String()
|
||||
}
|
||||
|
||||
+14
-14
@@ -1,25 +1,25 @@
|
||||
FILE: for.kt
|
||||
public? final? fun foo(): kotlin/Unit {
|
||||
lval <range>: <implicit> = Int(1).rangeTo#(Int(10))
|
||||
lval <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
lval i: <implicit> = <iterator>#.next#()
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval i: <implicit> = R|<local>/<iterator>|.next#()
|
||||
println#(i#)
|
||||
}
|
||||
|
||||
}
|
||||
public? final? fun bar(list: List<String>): kotlin/Unit {
|
||||
lval <range>: <implicit> = list#.subList#(Int(0), Int(10))
|
||||
lval <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
lval element: <implicit> = <iterator>#.next#()
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval element: <implicit> = R|<local>/<iterator>|.next#()
|
||||
println#(element#)
|
||||
}
|
||||
|
||||
lval <range>: <implicit> = list#.subList#(Int(10), Int(20))
|
||||
lval <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
lval element: <implicit> = <iterator>#.next#()
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval element: <implicit> = R|<local>/<iterator>|.next#()
|
||||
println#(element#)
|
||||
}
|
||||
|
||||
@@ -46,11 +46,11 @@ FILE: for.kt
|
||||
}
|
||||
public? final? fun baz(set: Set<Some>): kotlin/Unit {
|
||||
lval <range>: <implicit> = set#
|
||||
lval <iterator>: <implicit> = <range>#.iterator#()
|
||||
while(<iterator>#.hasNext#()) {
|
||||
lval <destruct>: <implicit> = <iterator>#.next#()
|
||||
lval x: <implicit> = <destruct>#.component1()
|
||||
lval y: <implicit> = <destruct>#.component2()
|
||||
lval <iterator>: <implicit> = R|<local>/<range>|.iterator#()
|
||||
while(R|<local>/<iterator>|.hasNext#()) {
|
||||
lval <destruct>: <implicit> = R|<local>/<iterator>|.next#()
|
||||
lval x: <implicit> = R|<local>/<destruct>|.component1()
|
||||
lval y: <implicit> = R|<local>/<destruct>|.component2()
|
||||
println#(<strcat>(String(x = ), x#, String( y = ), y#))
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@ FILE: lambda.kt
|
||||
}
|
||||
|
||||
use#(<L> = use@fun <implicit>.<anonymous>(<destruct>: <implicit>): <implicit> {
|
||||
lval x: <implicit> = <destruct>#.component1()
|
||||
lval y: <implicit> = <destruct>#.component2()
|
||||
lval x: <implicit> = R|<local>/<destruct>|.component1()
|
||||
lval y: <implicit> = R|<local>/<destruct>|.component2()
|
||||
x#.plus#(y#)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ FILE: nullability.kt
|
||||
Int(42)
|
||||
}
|
||||
else -> {
|
||||
<elvis>#
|
||||
R|<local>/<elvis>|
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ FILE: nullability.kt
|
||||
throw KotlinNullPointerException#()
|
||||
}
|
||||
else -> {
|
||||
<bangbang>#
|
||||
R|<local>/<bangbang>|
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-21
@@ -3,26 +3,26 @@ FILE: unary.kt
|
||||
lvar x: <implicit> = Int(0)
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = <unary>#.inc#()
|
||||
<unary>#
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = <unary>#.inc#()
|
||||
x# = R|<local>/<unary>|.inc#()
|
||||
x#
|
||||
}
|
||||
|
||||
lval x3: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = <unary>#.dec#()
|
||||
x# = R|<local>/<unary>|.dec#()
|
||||
x#
|
||||
}
|
||||
|
||||
lval x4: <implicit> = {
|
||||
lval <unary>: <implicit> = x#
|
||||
x# = <unary>#.dec#()
|
||||
<unary>#
|
||||
x# = R|<local>/<unary>|.dec#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
when () {
|
||||
@@ -46,30 +46,30 @@ FILE: unary.kt
|
||||
public? final? fun test2(x: X): kotlin/Unit {
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = x#.i#
|
||||
x#.i# = <unary>#.inc#()
|
||||
<unary>#
|
||||
x#.i# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = x#.i#
|
||||
lval <unary-result>: <implicit> = <unary>#.inc#()
|
||||
x#.i# = <unary-result>#
|
||||
<unary-result>#
|
||||
lval <unary-result>: <implicit> = R|<local>/<unary>|.inc#()
|
||||
x#.i# = R|<local>/<unary-result>|
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
}
|
||||
public? final? fun test3(arr: Array<Int>): kotlin/Unit {
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = arr#.get#(Int(0))
|
||||
arr#.set#(Int(0), <unary>#.inc#())
|
||||
<unary>#
|
||||
arr#.set#(Int(0), R|<local>/<unary>|.inc#())
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = arr#.get#(Int(1))
|
||||
lval <unary-result>: <implicit> = <unary>#.inc#()
|
||||
arr#.set#(Int(1), <unary-result>#)
|
||||
<unary-result>#
|
||||
lval <unary-result>: <implicit> = R|<local>/<unary>|.inc#()
|
||||
arr#.set#(Int(1), R|<local>/<unary-result>|)
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
}
|
||||
@@ -85,15 +85,15 @@ FILE: unary.kt
|
||||
public? final? fun test4(y: Y): kotlin/Unit {
|
||||
lval x1: <implicit> = {
|
||||
lval <unary>: <implicit> = y#.arr#.get#(Int(0))
|
||||
y#.arr#.set#(Int(0), <unary>#.inc#())
|
||||
<unary>#
|
||||
y#.arr#.set#(Int(0), R|<local>/<unary>|.inc#())
|
||||
R|<local>/<unary>|
|
||||
}
|
||||
|
||||
lval x2: <implicit> = {
|
||||
lval <unary>: <implicit> = y#.arr#.get#(Int(1))
|
||||
lval <unary-result>: <implicit> = <unary>#.inc#()
|
||||
y#.arr#.set#(Int(1), <unary-result>#)
|
||||
<unary-result>#
|
||||
lval <unary-result>: <implicit> = R|<local>/<unary>|.inc#()
|
||||
y#.arr#.set#(Int(1), R|<local>/<unary-result>|)
|
||||
R|<local>/<unary-result>|
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,13 +3,13 @@ FILE: while.kt
|
||||
lvar k: <implicit> = Int(0)
|
||||
some@while(<(k#, limit#)) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = <unary>#.inc#()
|
||||
<unary>#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
println#(k#)
|
||||
while(==(k#, Int(13))) {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = <unary>#.inc#()
|
||||
<unary>#
|
||||
k# = R|<local>/<unary>|.inc#()
|
||||
R|<local>/<unary>|
|
||||
when () {
|
||||
<(k#, limit#) -> {
|
||||
break@@@[<(k#, limit#)]
|
||||
@@ -35,8 +35,8 @@ FILE: while.kt
|
||||
lvar k: <implicit> = limit#
|
||||
do {
|
||||
lval <unary>: <implicit> = k#
|
||||
k# = <unary>#.dec#()
|
||||
<unary>#
|
||||
k# = R|<local>/<unary>|.dec#()
|
||||
R|<local>/<unary>|
|
||||
println#(k#)
|
||||
}
|
||||
while(>=(k#, Int(0)))
|
||||
|
||||
Reference in New Issue
Block a user