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.FirProperty
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
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.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||||
@@ -27,6 +28,10 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
|
|||||||
@PrivateForInline
|
@PrivateForInline
|
||||||
internal val parentStack = mutableListOf<IrDeclarationParent>()
|
internal val parentStack = mutableListOf<IrDeclarationParent>()
|
||||||
|
|
||||||
|
@PublishedApi
|
||||||
|
@PrivateForInline
|
||||||
|
internal val scopeStack = mutableListOf<Scope>()
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
@PrivateForInline
|
@PrivateForInline
|
||||||
internal val containingFirClassStack = mutableListOf<FirClass>()
|
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 {
|
inline fun <T : IrDeclarationParent, R> withParent(parent: T, f: T.() -> R): R {
|
||||||
parentStack += parent
|
parentStack += parent
|
||||||
|
if (parent is IrDeclaration) {
|
||||||
|
scopeStack += Scope(parent.symbol)
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return parent.f()
|
return parent.f()
|
||||||
} finally {
|
} finally {
|
||||||
|
if (parent is IrDeclaration) {
|
||||||
|
scopeStack.removeAt(scopeStack.size - 1)
|
||||||
|
}
|
||||||
parentStack.removeAt(parentStack.size - 1)
|
parentStack.removeAt(parentStack.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,6 +80,8 @@ class Fir2IrConversionScope(val configuration: Fir2IrConfiguration) {
|
|||||||
|
|
||||||
fun parentFromStack(): IrDeclarationParent = parentStack.last()
|
fun parentFromStack(): IrDeclarationParent = parentStack.last()
|
||||||
|
|
||||||
|
fun scope(): Scope = scopeStack.last()
|
||||||
|
|
||||||
fun parentAccessorOfPropertyFromStack(propertySymbol: IrPropertySymbol): IrSimpleFunction {
|
fun parentAccessorOfPropertyFromStack(propertySymbol: IrPropertySymbol): IrSimpleFunction {
|
||||||
// It is safe to access an owner of property symbol here, because this function may be called
|
// It is safe to access an owner of property symbol here, because this function may be called
|
||||||
// only from property accessor of corresponding property
|
// only from property accessor of corresponding property
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.backend
|
|||||||
import com.intellij.psi.tree.IElementType
|
import com.intellij.psi.tree.IElementType
|
||||||
import org.jetbrains.kotlin.*
|
import org.jetbrains.kotlin.*
|
||||||
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
|
import org.jetbrains.kotlin.contracts.description.LogicOperationKind
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.isObject
|
import org.jetbrains.kotlin.descriptors.isObject
|
||||||
import org.jetbrains.kotlin.diagnostics.findChildByType
|
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.ClassMemberGenerator
|
||||||
import org.jetbrains.kotlin.fir.backend.generators.OperatorExpressionGenerator
|
import org.jetbrains.kotlin.fir.backend.generators.OperatorExpressionGenerator
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
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.declarations.utils.*
|
||||||
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
import org.jetbrains.kotlin.fir.deserialization.toQualifiedPropertyAccessExpression
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
@@ -1150,24 +1147,18 @@ class Fir2IrVisitor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitElvisExpression(elvisExpression: FirElvisExpression, data: Any?): IrElement {
|
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 ->
|
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 =
|
fun irGetLhsValue(): IrGetValue =
|
||||||
IrGetValueImpl(startOffset, endOffset, irLhsVariable.type, irLhsVariable.symbol)
|
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 notNullType = originalType.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
val irBranches = listOf(
|
val irBranches = listOf(
|
||||||
IrBranchImpl(
|
IrBranchImpl(
|
||||||
@@ -1188,7 +1179,7 @@ class Fir2IrVisitor(
|
|||||||
} else {
|
} else {
|
||||||
Fir2IrImplicitCastInserter.implicitCastOrExpression(
|
Fir2IrImplicitCastInserter.implicitCastOrExpression(
|
||||||
irGetLhsValue(),
|
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 intN(): Int? = null
|
||||||
|
|
||||||
fun test() = intN() ?: 1
|
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:0..23 FUN name:intN visibility:public modality:FINAL <> () returnType:kotlin.Int?
|
||||||
@0:19..23 BLOCK_BODY
|
@0:19..23 BLOCK_BODY
|
||||||
@0:23..23 RETURN type=kotlin.Nothing from='public final fun intN (): kotlin.Int? declared in <root>'
|
@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()
|
fun demo(f: () -> String) = f()
|
||||||
|
|
||||||
// EXPECT_GENERATED_JS: function=test$lambda expect=deadCodeEliminationTestLambda.js
|
// EXPECT_GENERATED_JS: function=test$lambda expect=deadCodeEliminationTestLambda.js
|
||||||
|
|||||||
Reference in New Issue
Block a user