FIR2IR: use elvis temporary variable name closer to PSI2IR
Related to KT-61983
This commit is contained in:
committed by
Space Team
parent
dcfc20f1ff
commit
13ae4abe52
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
@@ -27,6 +28,10 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
|
||||
@PrivateForInline
|
||||
internal val parentStack = mutableListOf<IrDeclarationParent>()
|
||||
|
||||
@PublishedApi
|
||||
@PrivateForInline
|
||||
internal val scopeStack = mutableListOf<Scope>()
|
||||
|
||||
@PublishedApi
|
||||
@PrivateForInline
|
||||
internal val containingFirClassStack = mutableListOf<FirClass>()
|
||||
@@ -37,9 +42,15 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
|
||||
|
||||
inline fun <T : IrDeclarationParent, R> withParent(parent: T, f: T.() -> R): R {
|
||||
parentStack += parent
|
||||
if (parent is IrDeclaration) {
|
||||
scopeStack += Scope(parent.symbol)
|
||||
}
|
||||
try {
|
||||
return parent.f()
|
||||
} finally {
|
||||
if (parent is IrDeclaration) {
|
||||
scopeStack.removeAt(scopeStack.size - 1)
|
||||
}
|
||||
parentStack.removeAt(parentStack.size - 1)
|
||||
}
|
||||
}
|
||||
@@ -69,6 +80,8 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
|
||||
|
||||
fun parentFromStack(): IrDeclarationParent = parentStack.last()
|
||||
|
||||
fun scope(): Scope = scopeStack.last()
|
||||
|
||||
fun parentAccessorOfPropertyFromStack(propertySymbol: IrPropertySymbol): IrSimpleFunction {
|
||||
// It is safe to access an owner of property symbol here, because this function may be called
|
||||
// only from property accessor of corresponding property
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.backend
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.*
|
||||
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.isObject
|
||||
import org.jetbrains.kotlin.diagnostics.findChildByType
|
||||
@@ -16,8 +15,6 @@ import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.backend.generators.ClassMemberGenerator
|
||||
import org.jetbrains.kotlin.fir.backend.generators.OperatorExpressionGenerator
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -1150,24 +1147,18 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitElvisExpression(elvisExpression: FirElvisExpression, data: Any?): IrElement {
|
||||
val firLhsVariable = buildProperty {
|
||||
source = elvisExpression.source
|
||||
moduleData = session.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = elvisExpression.lhs.resolvedType.toFirResolvedTypeRef()
|
||||
name = Name.special("<elvis>")
|
||||
initializer = elvisExpression.lhs
|
||||
symbol = FirPropertySymbol(name)
|
||||
isVar = false
|
||||
isLocal = true
|
||||
status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL)
|
||||
}
|
||||
val irLhsVariable = firLhsVariable.accept(this, null) as IrVariable
|
||||
return elvisExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
val irLhsVariable = conversionScope.scope().createTemporaryVariable(
|
||||
irExpression = elvisExpression.lhs.accept(this, null) as IrExpression,
|
||||
nameHint = "elvis_lhs",
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset
|
||||
)
|
||||
|
||||
fun irGetLhsValue(): IrGetValue =
|
||||
IrGetValueImpl(startOffset, endOffset, irLhsVariable.type, irLhsVariable.symbol)
|
||||
|
||||
val originalType = firLhsVariable.returnTypeRef.coneType
|
||||
val originalType = elvisExpression.lhs.resolvedType
|
||||
val notNullType = originalType.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||
val irBranches = listOf(
|
||||
IrBranchImpl(
|
||||
@@ -1188,7 +1179,7 @@ class Fir2IrVisitor(
|
||||
} else {
|
||||
Fir2IrImplicitCastInserter.implicitCastOrExpression(
|
||||
irGetLhsValue(),
|
||||
firLhsVariable.returnTypeRef.resolvedTypeFromPrototype(notNullType).toIrType()
|
||||
originalType.toFirResolvedTypeRef().resolvedTypeFromPrototype(notNullType).toIrType()
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
@0:0..3:0 FILE fqName:<root> fileName:/elvis.kt
|
||||
@0:0..23 FUN name:intN visibility:public modality:FINAL <> () returnType:kotlin.Int?
|
||||
@0:19..23 BLOCK_BODY
|
||||
@0:23..23 RETURN type=kotlin.Nothing from='public final fun intN (): kotlin.Int? declared in <root>'
|
||||
@0:19..23 CONST Null type=kotlin.Nothing? value=null
|
||||
@2:0..24 FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Int
|
||||
@2:13..24 BLOCK_BODY
|
||||
@2:24..24 RETURN type=kotlin.Nothing from='public final fun test (): kotlin.Int declared in <root>'
|
||||
@2:13..24 BLOCK type=kotlin.Int origin=ELVIS
|
||||
@2:13..24 VAR IR_TEMPORARY_VARIABLE name:<elvis> type:kotlin.Int? [val]
|
||||
@2:13..19 CALL 'public final fun intN (): kotlin.Int? declared in <root>' type=kotlin.Int? origin=null
|
||||
@2:13..24 WHEN type=kotlin.Int origin=null
|
||||
@2:13..24 BRANCH
|
||||
@2:13..24 CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ
|
||||
@2:13..24 GET_VAR 'val <elvis>: kotlin.Int? [val] declared in <root>.test' type=kotlin.Int? origin=null
|
||||
@2:13..24 CONST Null type=kotlin.Nothing? value=null
|
||||
@2:23..24 CONST Int type=kotlin.Int value=1
|
||||
@2:13..24 BRANCH
|
||||
@2:13..24 CONST Boolean type=kotlin.Boolean value=true
|
||||
@2:13..24 GET_VAR 'val <elvis>: kotlin.Int? [val] declared in <root>.test' type=kotlin.Int? origin=null
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
fun intN(): Int? = null
|
||||
|
||||
fun test() = intN() ?: 1
|
||||
|
||||
// FIR_IDENTICAL
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@0:0..3:0 FILE fqName:<root> fileName:/elvis.kt
|
||||
@0:0..5:0 FILE fqName:<root> fileName:/elvis.kt
|
||||
@0:0..23 FUN name:intN visibility:public modality:FINAL <> () returnType:kotlin.Int?
|
||||
@0:19..23 BLOCK_BODY
|
||||
@0:23..23 RETURN type=kotlin.Nothing from='public final fun intN (): kotlin.Int? declared in <root>'
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// IGNORE_BACKEND_K2: JS_IR, JS_IR_ES6
|
||||
// FIR works fine, however it generates another names for the temporary variables, therefore ignore it
|
||||
|
||||
fun demo(f: () -> String) = f()
|
||||
|
||||
// EXPECT_GENERATED_JS: function=test$lambda expect=deadCodeEliminationTestLambda.js
|
||||
|
||||
Reference in New Issue
Block a user