[FIR2IR] Approximate types for lambdas before passing to serialization
This commit is contained in:
+34
-4
@@ -21,9 +21,15 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||
import org.jetbrains.kotlin.fir.inferenceContext
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.withReplacedConeType
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeUnsafe
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
@@ -32,6 +38,9 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
@@ -52,16 +61,37 @@ class FirJvmClassCodegen(
|
||||
else -> null
|
||||
}
|
||||
|
||||
private val approximator = object : AbstractTypeApproximator(session.inferenceContext) {
|
||||
override fun createErrorType(message: String): SimpleTypeMarker {
|
||||
return ConeKotlinErrorType(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirTypeRef.approximated(
|
||||
toSuper: Boolean,
|
||||
conf: TypeApproximatorConfiguration = TypeApproximatorConfiguration.PublicDeclaration
|
||||
): FirTypeRef {
|
||||
val approximatedType = if (toSuper)
|
||||
approximator.approximateToSuperType(this.coneTypeUnsafe(), conf)
|
||||
else
|
||||
approximator.approximateToSubType(this.coneTypeUnsafe(), conf)
|
||||
return withReplacedConeType(approximatedType as? ConeKotlinType)
|
||||
}
|
||||
|
||||
private fun FirFunction<*>.copyToFreeAnonymousFunction(): FirAnonymousFunction {
|
||||
val function = this
|
||||
return buildAnonymousFunction {
|
||||
session = function.session
|
||||
origin = FirDeclarationOrigin.Source
|
||||
symbol = FirAnonymousFunctionSymbol()
|
||||
returnTypeRef = function.returnTypeRef
|
||||
receiverTypeRef = function.receiverTypeRef
|
||||
returnTypeRef = function.returnTypeRef.approximated(toSuper = true)
|
||||
receiverTypeRef = function.receiverTypeRef?.approximated(toSuper = false)
|
||||
isLambda = (function as? FirAnonymousFunction)?.isLambda == true
|
||||
valueParameters.addAll(function.valueParameters)
|
||||
valueParameters.addAll(function.valueParameters.map {
|
||||
buildValueParameterCopy(it) {
|
||||
returnTypeRef = it.returnTypeRef.approximated(toSuper = false)
|
||||
}
|
||||
})
|
||||
typeParameters.addAll(function.typeParameters.filterIsInstance<FirTypeParameter>())
|
||||
}
|
||||
}
|
||||
|
||||
+21
@@ -72,3 +72,24 @@ inline fun buildValueParameter(init: FirValueParameterBuilder.() -> Unit): FirVa
|
||||
}
|
||||
return FirValueParameterBuilder().apply(init).build()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
inline fun buildValueParameterCopy(original: FirValueParameter, init: FirValueParameterBuilder.() -> Unit): FirValueParameter {
|
||||
contract {
|
||||
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
val copyBuilder = FirValueParameterBuilder()
|
||||
copyBuilder.source = original.source
|
||||
copyBuilder.session = original.session
|
||||
copyBuilder.resolvePhase = original.resolvePhase
|
||||
copyBuilder.origin = original.origin
|
||||
copyBuilder.returnTypeRef = original.returnTypeRef
|
||||
copyBuilder.name = original.name
|
||||
copyBuilder.symbol = original.symbol
|
||||
copyBuilder.annotations.addAll(original.annotations)
|
||||
copyBuilder.defaultValue = original.defaultValue
|
||||
copyBuilder.isCrossinline = original.isCrossinline
|
||||
copyBuilder.isNoinline = original.isNoinline
|
||||
copyBuilder.isVararg = original.isVararg
|
||||
return copyBuilder.apply(init).build()
|
||||
}
|
||||
|
||||
+1
@@ -245,6 +245,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
||||
|
||||
builder(valueParameter, type = "FirValueParameterImpl") {
|
||||
openBuilder()
|
||||
withCopy()
|
||||
}
|
||||
|
||||
builder(valueParameter, type = "FirDefaultSetterValueParameter") {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||
|
||||
fun <R> foo(f: () -> R): R = f()
|
||||
|
||||
Reference in New Issue
Block a user