JVM IR: Use raw types in SAM wrappers

This commit is contained in:
Steven Schäfer
2020-10-28 17:39:44 +01:00
committed by Alexander Udalov
parent 999151abac
commit a475fa2a21
10 changed files with 79 additions and 7 deletions
@@ -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");
@@ -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)
)
}
@@ -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");
@@ -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");