[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.FirDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
|
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.serialization.FirElementSerializer
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
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.IrClass
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrField
|
import org.jetbrains.kotlin.ir.declarations.IrField
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
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.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
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.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
|
|
||||||
@@ -52,16 +61,37 @@ class FirJvmClassCodegen(
|
|||||||
else -> null
|
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 {
|
private fun FirFunction<*>.copyToFreeAnonymousFunction(): FirAnonymousFunction {
|
||||||
val function = this
|
val function = this
|
||||||
return buildAnonymousFunction {
|
return buildAnonymousFunction {
|
||||||
session = function.session
|
session = function.session
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
symbol = FirAnonymousFunctionSymbol()
|
symbol = FirAnonymousFunctionSymbol()
|
||||||
returnTypeRef = function.returnTypeRef
|
returnTypeRef = function.returnTypeRef.approximated(toSuper = true)
|
||||||
receiverTypeRef = function.receiverTypeRef
|
receiverTypeRef = function.receiverTypeRef?.approximated(toSuper = false)
|
||||||
isLambda = (function as? FirAnonymousFunction)?.isLambda == true
|
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>())
|
typeParameters.addAll(function.typeParameters.filterIsInstance<FirTypeParameter>())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -72,3 +72,24 @@ inline fun buildValueParameter(init: FirValueParameterBuilder.() -> Unit): FirVa
|
|||||||
}
|
}
|
||||||
return FirValueParameterBuilder().apply(init).build()
|
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") {
|
builder(valueParameter, type = "FirValueParameterImpl") {
|
||||||
openBuilder()
|
openBuilder()
|
||||||
|
withCopy()
|
||||||
}
|
}
|
||||||
|
|
||||||
builder(valueParameter, type = "FirDefaultSetterValueParameter") {
|
builder(valueParameter, type = "FirDefaultSetterValueParameter") {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
// !DIAGNOSTICS: -DEBUG_INFO_SMARTCAST
|
||||||
|
|
||||||
fun <R> foo(f: () -> R): R = f()
|
fun <R> foo(f: () -> R): R = f()
|
||||||
|
|||||||
Reference in New Issue
Block a user