JVM IR: support inline classes with private constructors from other modules

#KT-44723 Fixed
This commit is contained in:
Alexander Udalov
2021-03-19 21:01:09 +01:00
parent dac218dc39
commit b5f9b1dfc0
12 changed files with 204 additions and 14 deletions
@@ -6683,6 +6683,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -6752,6 +6764,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -58,8 +58,8 @@ class IrLazyClass(
ArrayList<IrDeclaration>().also {
typeTranslator.buildWithScope(this) {
generateChildStubs(descriptor.constructors, it)
generateMemberStubs(descriptor.defaultType.memberScope, it)
generateMemberStubs(descriptor.staticScope, it)
generateChildStubs(descriptor.defaultType.memberScope.getContributedDescriptors(), it)
generateChildStubs(descriptor.staticScope.getContributedDescriptors(), it)
}
}.also {
it.forEach {
@@ -68,6 +68,22 @@ class IrLazyClass(
}
}
private fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, declarations: MutableList<IrDeclaration>) {
descriptors.mapNotNullTo(declarations) { descriptor ->
if (shouldBuildStub(descriptor)) stubGenerator.generateMemberStub(descriptor) else null
}
}
private fun shouldBuildStub(descriptor: DeclarationDescriptor): Boolean =
descriptor !is DeclarationDescriptorWithVisibility ||
!DescriptorVisibilities.isPrivate(descriptor.visibility) ||
// Always build lazy IR stubs for inline class primary constructors.
// This is needed because primary constructors of inline classes can be private, and prior to 1.5.0, there was no way
// to determine the inline class representation other than by loading the single value parameter of the primary constructor
// (corresponding metadata entry was added in 1.5.0). Backend still tries to load inline class representation in this way
// to support compilation against inline classes compiled with 1.4.30 or earlier.
(descriptor is ConstructorDescriptor && isInline)
override var typeParameters: List<IrTypeParameter> by lazyVar(stubGenerator.lock) {
descriptor.declaredTypeParameters.mapTo(arrayListOf()) {
stubGenerator.generateOrGetTypeParameterStub(it)
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.KotlinType
import kotlin.properties.ReadWriteProperty
@@ -36,17 +35,6 @@ interface IrLazyDeclarationBase : IrDeclaration {
isHidden = false, isAssignable = false
)
fun generateMemberStubs(memberScope: MemberScope, container: MutableList<IrDeclaration>) {
generateChildStubs(memberScope.getContributedDescriptors(), container)
}
fun generateChildStubs(descriptors: Collection<DeclarationDescriptor>, declarations: MutableList<IrDeclaration>) {
descriptors.mapNotNullTo(declarations) { descriptor ->
if (descriptor is DeclarationDescriptorWithVisibility && DescriptorVisibilities.isPrivate(descriptor.visibility)) null
else stubGenerator.generateMemberStub(descriptor)
}
}
fun createLazyAnnotations(): ReadWriteProperty<Any?, List<IrConstructorCall>> = lazyVar(stubGenerator.lock) {
descriptor.annotations.mapNotNull(typeTranslator.constantValueGenerator::generateAnnotationConstructorCall).toMutableList()
}
@@ -0,0 +1,14 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// MODULE: lib
// USE_OLD_INLINE_CLASSES_MANGLING_SCHEME
// FILE: A.kt
inline class A private constructor(val value: String) {
constructor(c: Char) : this(c + "K")
}
// MODULE: main(lib)
// FILE: B.kt
fun box(): String = A('O').value
@@ -0,0 +1,16 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
// MODULE: lib
// USE_OLD_INLINE_CLASSES_MANGLING_SCHEME
// FILE: A.kt
inline class A private constructor(private val value: String) {
constructor(c: Char) : this(c + "K")
val publicValue: String get() = value
}
// MODULE: main(lib)
// FILE: B.kt
fun box(): String = A('O').publicValue
@@ -0,0 +1,12 @@
// WITH_RUNTIME
// MODULE: lib
// FILE: A.kt
inline class A private constructor(val value: String) {
constructor(c: Char) : this(c + "K")
}
// MODULE: main(lib)
// FILE: B.kt
fun box(): String = A('O').value
@@ -0,0 +1,14 @@
// WITH_RUNTIME
// MODULE: lib
// FILE: A.kt
inline class A private constructor(private val value: String) {
constructor(c: Char) : this(c + "K")
val publicValue: String get() = value
}
// MODULE: main(lib)
// FILE: B.kt
fun box(): String = A('O').publicValue
@@ -6683,6 +6683,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -6752,6 +6764,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -6683,6 +6683,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -6752,6 +6764,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -548,6 +548,18 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -617,6 +629,18 @@ public class JvmIrAgainstOldBoxTestGenerated extends AbstractJvmIrAgainstOldBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -548,6 +548,18 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -617,6 +629,18 @@ public class JvmOldAgainstIrBoxTestGenerated extends AbstractJvmOldAgainstIrBoxT
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateCompanionObjectValInDifferentModule.kt");
}
@Test
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructor.kt");
}
@Test
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/oldMangling/privateConstructorWithPrivateField.kt");
}
@Test
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
@@ -4460,6 +4460,16 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateCompanionObjectValInDifferentModule.kt");
}
@TestMetadata("privateConstructor.kt")
public void testPrivateConstructor() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructor.kt");
}
@TestMetadata("privateConstructorWithPrivateField.kt")
public void testPrivateConstructorWithPrivateField() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateConstructorWithPrivateField.kt");
}
@TestMetadata("privateTopLevelValInDifferentModule.kt")
public void testPrivateTopLevelValInDifferentModule() throws Exception {
runTest("compiler/testData/codegen/box/compileKotlinAgainstKotlin/inlineClasses/privateTopLevelValInDifferentModule.kt");