JVM IR: Use raw types in SAM wrappers
This commit is contained in:
committed by
Alexander Udalov
parent
999151abac
commit
a475fa2a21
Generated
+5
@@ -4344,6 +4344,11 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperPrivateFinalSyntheticField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperRawTypes.kt")
|
||||
public void testSamWrapperRawTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperRawTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperSyntheticFlags.kt")
|
||||
public void testSamWrapperSyntheticFlags() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperSyntheticFlags.kt");
|
||||
|
||||
+4
-1
@@ -66,6 +66,9 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
|
||||
abstract fun getSuperTypeForWrapper(typeOperand: IrType): IrType
|
||||
|
||||
protected open fun getWrappedFunctionType(klass: IrClass): IrType =
|
||||
klass.defaultType
|
||||
|
||||
abstract val IrType.needEqualsHashCodeMethods: Boolean
|
||||
|
||||
open val inInlineFunctionScope get() = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
|
||||
@@ -161,7 +164,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
|
||||
context.ir.symbols.suspendFunctionN(superMethod.valueParameters.size + extensionReceiversCount).owner
|
||||
else
|
||||
context.ir.symbols.functionN(superMethod.valueParameters.size + extensionReceiversCount).owner
|
||||
val wrappedFunctionType = wrappedFunctionClass.defaultType
|
||||
val wrappedFunctionType = getWrappedFunctionType(wrappedFunctionClass)
|
||||
|
||||
val subclass = context.irFactory.buildClass {
|
||||
name = wrapperName
|
||||
|
||||
@@ -51,11 +51,14 @@ class JvmBackendContext(
|
||||
irModuleFragment: IrModuleFragment,
|
||||
private val symbolTable: SymbolTable,
|
||||
val phaseConfig: PhaseConfig,
|
||||
// If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class
|
||||
// annotated with @JvmPackageName, the correct name is recorded here.
|
||||
val classNameOverride: MutableMap<IrClass, JvmClassName>,
|
||||
val generatorExtensions: JvmGeneratorExtensions,
|
||||
val serializerFactory: MetadataSerializerFactory
|
||||
) : CommonBackendContext {
|
||||
// If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class
|
||||
// annotated with @JvmPackageName, the correct name is recorded here.
|
||||
val classNameOverride: MutableMap<IrClass, JvmClassName>
|
||||
get() = generatorExtensions.classNameOverride
|
||||
|
||||
override val transformedFunction: MutableMap<IrFunctionSymbol, IrSimpleFunctionSymbol>
|
||||
get() = TODO("not implemented")
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory
|
||||
) {
|
||||
val context = JvmBackendContext(
|
||||
state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment,
|
||||
symbolTable, phaseConfig, extensions.classNameOverride, serializerFactory
|
||||
symbolTable, phaseConfig, extensions, serializerFactory
|
||||
)
|
||||
/* JvmBackendContext creates new unbound symbols, have to resolve them. */
|
||||
ExternalDependenciesGenerator(symbolTable, irProviders, state.languageVersionSettings).generateUnboundSymbolsAsDependencies()
|
||||
|
||||
@@ -17,8 +17,8 @@ import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_COMPLETION_PARAM
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_CREATE_METHOD_NAME
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
|
||||
@@ -17,8 +17,8 @@ import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -377,3 +378,19 @@ fun collectVisibleTypeParameters(scopeOwner: IrTypeParametersContainer): Set<IrT
|
||||
}
|
||||
.flatMap { it.typeParameters }
|
||||
.toSet()
|
||||
|
||||
fun IrClassSymbol.rawType(context: JvmBackendContext): IrSimpleType {
|
||||
// On the IR backend we represent raw types as star projected types with a special synthetic annotation.
|
||||
// See `TypeTranslator.translateTypeAnnotations`.
|
||||
val rawTypeAnnotation = IrConstructorCallImpl.fromSymbolOwner(
|
||||
context.generatorExtensions.rawTypeAnnotationConstructor!!.constructedClassType,
|
||||
context.generatorExtensions.rawTypeAnnotationConstructor.symbol
|
||||
)
|
||||
|
||||
return IrSimpleTypeImpl(
|
||||
this,
|
||||
hasQuestionMark = false,
|
||||
arguments = owner.typeParameters.map { IrStarProjectionImpl },
|
||||
annotations = listOf(rawTypeAnnotation)
|
||||
)
|
||||
}
|
||||
|
||||
+5
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.backend.common.lower.SingleAbstractMethodLowering
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound
|
||||
import org.jetbrains.kotlin.backend.jvm.ir.rawType
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||
@@ -42,6 +44,9 @@ private class JvmSingleAbstractMethodLowering(context: JvmBackendContext) : Sing
|
||||
override fun getSuperTypeForWrapper(typeOperand: IrType): IrType =
|
||||
typeOperand.erasedUpperBound.defaultType
|
||||
|
||||
override fun getWrappedFunctionType(klass: IrClass): IrType =
|
||||
klass.symbol.rawType(context as JvmBackendContext)
|
||||
|
||||
private val IrType.isKotlinFunInterface: Boolean
|
||||
get() = getClass()?.origin != IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
// FILE: J.java
|
||||
|
||||
public class J {
|
||||
public interface F {
|
||||
public int call(String x)
|
||||
}
|
||||
|
||||
public static void g(F r) {
|
||||
r.call(null);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun nonInlineFun() {
|
||||
val f: (String?) -> Int = { s -> 0 }
|
||||
J.g(f)
|
||||
}
|
||||
|
||||
inline fun inlineFun() {
|
||||
val f: (String?) -> Int = { s -> 0 }
|
||||
J.g(f)
|
||||
}
|
||||
|
||||
// There should be no generic information in the SAM wrappers.
|
||||
// 0 declaration: void <init>\(kotlin.jvm.functions.Function1<.*, .*>\)
|
||||
// 0 declaration: function extends kotlin.jvm.functions.Function1<.*, .*>
|
||||
// 2 private final synthetic Lkotlin/jvm/functions/Function1; function
|
||||
// 2 <init>\(Lkotlin/jvm/functions/Function1;\)V
|
||||
@@ -4416,6 +4416,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperPrivateFinalSyntheticField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperRawTypes.kt")
|
||||
public void testSamWrapperRawTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperRawTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperSyntheticFlags.kt")
|
||||
public void testSamWrapperSyntheticFlags() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperSyntheticFlags.kt");
|
||||
|
||||
+5
@@ -4344,6 +4344,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperPrivateFinalSyntheticField.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperRawTypes.kt")
|
||||
public void testSamWrapperRawTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperRawTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samWrapperSyntheticFlags.kt")
|
||||
public void testSamWrapperSyntheticFlags() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/sam/samWrapperSyntheticFlags.kt");
|
||||
|
||||
Reference in New Issue
Block a user