KT-30419 Box inline classes in return types of covariant overrides
Use boxed version of an inline class in return type position for covariant and generic-specialized overrides. Also fixes KT-35234 and KT-31585.
This commit is contained in:
Generated
+98
@@ -10914,6 +10914,104 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/whenWithSubject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class BoxReturnValueOnOverride extends AbstractIrJsCodegenBoxTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToAny.kt")
|
||||
public void testCovariantOverrideErasedToAny() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToInterface.kt")
|
||||
public void testCovariantOverrideErasedToInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToPrimitive.kt")
|
||||
public void testCovariantOverrideErasedToPrimitive() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToPrimitive.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideListVsMutableList.kt")
|
||||
public void testCovariantOverrideListVsMutableList() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideListVsMutableList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideUnrelatedInterfaces.kt")
|
||||
public void testCovariantOverrideUnrelatedInterfaces() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideUnrelatedInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverride.kt")
|
||||
public void testGenericOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/genericOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverrideSpecialized.kt")
|
||||
public void testGenericOverrideSpecialized() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/genericOverrideSpecialized.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInOverriddenReturnTypes.kt")
|
||||
public void testInlineClassInOverriddenReturnTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/inlineClassInOverriddenReturnTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt28483.kt")
|
||||
public void testKt28483() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt28483.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt31585.kt")
|
||||
public void testKt31585() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt31585.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35234.kt")
|
||||
public void testKt35234() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt35234.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35234a.kt")
|
||||
public void testKt35234a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt35234a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes1a.kt")
|
||||
public void testRelatedReturnTypes1a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes1a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes1b.kt")
|
||||
public void testRelatedReturnTypes1b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes1b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes2a.kt")
|
||||
public void testRelatedReturnTypes2a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes2a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes2b.kt")
|
||||
public void testRelatedReturnTypes2b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes2b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unrelatedGenerics.kt")
|
||||
public void testUnrelatedGenerics() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/unrelatedGenerics.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/callableReferences")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+98
@@ -10979,6 +10979,104 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/whenWithSubject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class BoxReturnValueOnOverride extends AbstractJsCodegenBoxTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToAny.kt")
|
||||
public void testCovariantOverrideErasedToAny() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToAny.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToInterface.kt")
|
||||
public void testCovariantOverrideErasedToInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToInterface.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideErasedToPrimitive.kt")
|
||||
public void testCovariantOverrideErasedToPrimitive() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToPrimitive.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideListVsMutableList.kt")
|
||||
public void testCovariantOverrideListVsMutableList() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideListVsMutableList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("covariantOverrideUnrelatedInterfaces.kt")
|
||||
public void testCovariantOverrideUnrelatedInterfaces() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideUnrelatedInterfaces.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverride.kt")
|
||||
public void testGenericOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/genericOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverrideSpecialized.kt")
|
||||
public void testGenericOverrideSpecialized() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/genericOverrideSpecialized.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineClassInOverriddenReturnTypes.kt")
|
||||
public void testInlineClassInOverriddenReturnTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/inlineClassInOverriddenReturnTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt28483.kt")
|
||||
public void testKt28483() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt28483.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt31585.kt")
|
||||
public void testKt31585() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt31585.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35234.kt")
|
||||
public void testKt35234() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt35234.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35234a.kt")
|
||||
public void testKt35234a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/kt35234a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes1a.kt")
|
||||
public void testRelatedReturnTypes1a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes1a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes1b.kt")
|
||||
public void testRelatedReturnTypes1b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes1b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes2a.kt")
|
||||
public void testRelatedReturnTypes2a() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes2a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("relatedReturnTypes2b.kt")
|
||||
public void testRelatedReturnTypes2b() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/relatedReturnTypes2b.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("unrelatedGenerics.kt")
|
||||
public void testUnrelatedGenerics() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/unrelatedGenerics.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/inlineClasses/callableReferences")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+37
-32
@@ -50,8 +50,8 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
|
||||
private fun copyDefaultMembers(descriptor: ClassDescriptor, model: JsClassModel) {
|
||||
val members = descriptor.unsubstitutedMemberScope
|
||||
.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
|
||||
.mapNotNull { it as? CallableMemberDescriptor }
|
||||
.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
|
||||
.mapNotNull { it as? CallableMemberDescriptor }
|
||||
|
||||
// Traverse fake non-abstract member. Current class does not provide their implementation,
|
||||
// it can be inherited from interface.
|
||||
@@ -93,11 +93,15 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
val targetClass = member.containingDeclaration as ClassDescriptor
|
||||
val fromInterfaceName = context.getNameForDescriptor(fromInterface).ident
|
||||
|
||||
copyMethod(context.getNameForDescriptor(fromClass).ident, fromInterfaceName + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX,
|
||||
fromClass.containingDeclaration as ClassDescriptor, targetClass, model.postDeclarationBlock)
|
||||
copyMethod(fromInterfaceName, context.getNameForDescriptor(member).ident,
|
||||
fromInterface.containingDeclaration as ClassDescriptor, targetClass,
|
||||
model.postDeclarationBlock)
|
||||
copyMethod(
|
||||
context.getNameForDescriptor(fromClass).ident, fromInterfaceName + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX,
|
||||
fromClass.containingDeclaration as ClassDescriptor, targetClass, model.postDeclarationBlock
|
||||
)
|
||||
copyMethod(
|
||||
fromInterfaceName, context.getNameForDescriptor(member).ident,
|
||||
fromInterface.containingDeclaration as ClassDescriptor, targetClass,
|
||||
model.postDeclarationBlock
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -113,8 +117,7 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
if (memberToCopy is FunctionDescriptor && memberToCopy.hasOrInheritsParametersWithDefaultValue()) {
|
||||
val name = context.getNameForDescriptor(member).ident + Namer.DEFAULT_PARAMETER_IMPLEMENTOR_SUFFIX
|
||||
copyMethod(name, name, classToCopyFrom, descriptor, model.postDeclarationBlock)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
copyMember(member, classToCopyFrom, descriptor, model)
|
||||
}
|
||||
}
|
||||
@@ -141,8 +144,7 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
val accessorName = context.getNameForDescriptor(accessor).ident
|
||||
copyMethod(accessorName, accessorName, from, to, model.postDeclarationBlock)
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
copyProperty(name, from, to, model.postDeclarationBlock)
|
||||
}
|
||||
}
|
||||
@@ -182,9 +184,9 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
get() = KotlinBuiltIns.isAny(containingDeclaration as ClassDescriptor) || overriddenDescriptors.any { it.isInheritedFromAny }
|
||||
|
||||
private fun <T : CallableMemberDescriptor> T.findOverriddenDescriptor(
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>,
|
||||
getOriginalDescriptor: T.() -> T,
|
||||
filter: T.() -> Boolean
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>,
|
||||
getOriginalDescriptor: T.() -> T,
|
||||
filter: T.() -> Boolean
|
||||
): T? {
|
||||
val visitedDescriptors = mutableSetOf<T>()
|
||||
val collectedDescriptors = mutableMapOf<T, T>()
|
||||
@@ -195,8 +197,7 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
|
||||
if (original.kind.isReal && !original.isEffectivelyExternal()) {
|
||||
collectedDescriptors.putIfAbsent(original, source)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
overridden.forEach { walk(it, source) }
|
||||
}
|
||||
}
|
||||
@@ -208,8 +209,8 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
}
|
||||
|
||||
private fun <T : CallableMemberDescriptor> Collection<T>.removeRepeated(
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>,
|
||||
getOriginalDescriptor: T.() -> T
|
||||
getTypedOverriddenDescriptors: T.() -> Collection<T>,
|
||||
getOriginalDescriptor: T.() -> T
|
||||
): List<T> {
|
||||
val visitedDescriptors = mutableSetOf<T>()
|
||||
fun walk(descriptor: T) {
|
||||
@@ -234,8 +235,10 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
val sourceName = context.getNameForDescriptor(key).ident
|
||||
val targetName = context.getNameForDescriptor(value).ident
|
||||
if (sourceName != targetName) {
|
||||
val statement = generateDelegateCall(descriptor, key, value, JsThisRef(), context, false,
|
||||
descriptor.source.getPsi())
|
||||
val statement = generateDelegateCall(
|
||||
descriptor, key, value, JsThisRef(), context, false,
|
||||
descriptor.source.getPsi()
|
||||
)
|
||||
model.postDeclarationBlock.statements += statement
|
||||
}
|
||||
}
|
||||
@@ -253,7 +256,7 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateBridge(descriptor: ClassDescriptor, model: JsClassModel, bridge: Bridge<FunctionDescriptor>) {
|
||||
private fun generateBridge(descriptor: ClassDescriptor, model: JsClassModel, bridge: Bridge<FunctionDescriptor, *>) {
|
||||
val fromDescriptor = bridge.from
|
||||
val toDescriptor = bridge.to
|
||||
|
||||
@@ -267,16 +270,18 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
if (fromDescriptor.kind.isReal && fromDescriptor.modality != Modality.ABSTRACT && !toDescriptor.kind.isReal) return
|
||||
}
|
||||
|
||||
model.postDeclarationBlock.statements += generateDelegateCall(descriptor, fromDescriptor, toDescriptor, JsThisRef(),
|
||||
context, false, descriptor.source.getPsi())
|
||||
model.postDeclarationBlock.statements += generateDelegateCall(
|
||||
descriptor, fromDescriptor, toDescriptor, JsThisRef(),
|
||||
context, false, descriptor.source.getPsi()
|
||||
)
|
||||
}
|
||||
|
||||
private fun copyMethod(
|
||||
sourceName: String,
|
||||
targetName: String,
|
||||
sourceDescriptor: ClassDescriptor,
|
||||
targetDescriptor: ClassDescriptor,
|
||||
block: JsBlock
|
||||
sourceName: String,
|
||||
targetName: String,
|
||||
sourceDescriptor: ClassDescriptor,
|
||||
targetDescriptor: ClassDescriptor,
|
||||
block: JsBlock
|
||||
) {
|
||||
if (!context.isFromCurrentModule(targetDescriptor)) return
|
||||
|
||||
@@ -288,10 +293,10 @@ class ClassModelGenerator(val context: TranslationContext) {
|
||||
}
|
||||
|
||||
private fun copyProperty(
|
||||
name: String,
|
||||
sourceDescriptor: ClassDescriptor,
|
||||
targetDescriptor: ClassDescriptor,
|
||||
block: JsBlock
|
||||
name: String,
|
||||
sourceDescriptor: ClassDescriptor,
|
||||
targetDescriptor: ClassDescriptor,
|
||||
block: JsBlock
|
||||
) {
|
||||
if (!context.isFromCurrentModule(targetDescriptor)) return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user