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:
Dmitry Petrov
2020-03-30 12:41:48 +03:00
parent e44f12d7b0
commit 24b8495e00
31 changed files with 1296 additions and 68 deletions
@@ -18,15 +18,16 @@ package org.jetbrains.kotlin.backend.common.bridges
import org.jetbrains.kotlin.utils.DFS
import java.util.*
import kotlin.collections.LinkedHashMap
interface FunctionHandle {
val isDeclaration: Boolean
val isAbstract: Boolean
/** On finding concrete super declaration we should distinguish non-abstract java8/js default methods from
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
* class ones (see [findConcreteSuperDeclaration] method in bridges.kt).
* Note that interface methods with body compiled to jvm 8 target are assumed to be non-abstract in bridges method calculation
* (more details in [DescriptorBasedFunctionHandle.isBodyOwner] comment).*/
val mayBeUsedAsSuperImplementation: Boolean
fun getOverridden(): Iterable<FunctionHandle>
@@ -34,18 +35,19 @@ interface FunctionHandle {
val mightBeIncorrectCode: Boolean get() = false
}
data class Bridge<out Signature>(
val from: Signature,
val to: Signature
data class Bridge<out Signature, out Function : FunctionHandle>(
val from: Signature,
val to: Signature,
val originalFunctions: Set<Function>
) {
override fun toString() = "$from -> $to"
}
fun <Function : FunctionHandle, Signature> generateBridges(
function: Function,
signature: (Function) -> Signature
): Set<Bridge<Signature>> {
function: Function,
signature: (Function) -> Signature
): Set<Bridge<Signature, Function>> {
// If it's an abstract function, no bridges are needed: when an implementation will appear in some concrete subclass, all necessary
// bridges will be generated there
if (function.isAbstract) return setOf()
@@ -58,7 +60,7 @@ fun <Function : FunctionHandle, Signature> generateBridges(
val implementation = findConcreteSuperDeclaration(function) ?: return setOf()
val bridgesToGenerate = findAllReachableDeclarations(function).mapTo(LinkedHashSet<Signature>(), signature)
val bridgesToGenerate = findAllReachableDeclarations(function).groupByTo(LinkedHashMap(), signature)
if (fake) {
// If it's a concrete fake override, some of the bridges may be inherited from the super-classes. Specifically, bridges for all
@@ -67,14 +69,20 @@ fun <Function : FunctionHandle, Signature> generateBridges(
@Suppress("UNCHECKED_CAST")
for (overridden in function.getOverridden() as Iterable<Function>) {
if (!overridden.isAbstract) {
bridgesToGenerate.removeAll(findAllReachableDeclarations(overridden).map(signature))
for (reachable in findAllReachableDeclarations(overridden)) {
bridgesToGenerate.remove(signature(reachable))
}
}
}
}
val method = signature(implementation)
bridgesToGenerate.remove(method)
return bridgesToGenerate.map { Bridge(it, method) }.toSet()
return bridgesToGenerate.entries
.map { (overriddenSignature, overriddenFunctions) ->
Bridge(overriddenSignature, method, overriddenFunctions.toSet())
}
.toSet()
}
fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function): MutableSet<Function> {
@@ -95,7 +103,7 @@ fun <Function : FunctionHandle> findAllReachableDeclarations(function: Function)
* The implementation is guaranteed to exist because if it wouldn't, the given function would've been abstract
*/
fun <Function : FunctionHandle> findConcreteSuperDeclaration(function: Function): Function? {
require(!function.isAbstract, { "Only concrete functions have implementations: $function" })
require(!function.isAbstract) { "Only concrete functions have implementations: $function" }
if (function.isDeclaration) return function
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature
): Set<Bridge<Signature>> {
): Set<Bridge<Signature, DescriptorBasedFunctionHandle>> {
return generateBridges(DescriptorBasedFunctionHandle(descriptor), { signature(it.descriptor) })
}
@@ -68,6 +68,7 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import java.util.stream.Collectors;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
@@ -1021,7 +1022,7 @@ public class FunctionCodegen {
boolean isSpecial = SpecialBuiltinMembers.getOverriddenBuiltinReflectingJvmDescriptor(descriptor) != null;
Set<Bridge<Method>> bridgesToGenerate;
Set<Bridge<Method, DescriptorBasedFunctionHandleForJvm>> bridgesToGenerate;
if (!isSpecial) {
bridgesToGenerate =
JvmBridgesImplKt.generateBridgesForFunctionDescriptorForJvm(descriptor, typeMapper::mapAsmMethod, state);
@@ -1030,22 +1031,23 @@ public class FunctionCodegen {
boolean isSpecialBridge =
BuiltinMethodsWithSpecialGenericSignature.getOverriddenBuiltinFunctionWithErasedValueParametersInJava(descriptor) != null;
for (Bridge<Method> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), isSpecialBridge, false);
for (Bridge<Method, DescriptorBasedFunctionHandleForJvm> bridge : bridgesToGenerate) {
generateBridge(origin, descriptor, bridge.getFrom(), bridge.getTo(), getBridgeReturnType(bridge), isSpecialBridge, false);
}
}
}
else {
Set<BridgeForBuiltinSpecial<Method>> specials = BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(
descriptor, typeMapper::mapAsmMethod, state
);
Set<BridgeForBuiltinSpecial<Method>> specials =
BuiltinSpecialBridgesUtil.generateBridgesForBuiltinSpecial(descriptor, typeMapper::mapAsmMethod, state);
if (!specials.isEmpty()) {
PsiElement origin = descriptor.getKind() == DECLARATION ? getSourceFromDescriptor(descriptor) : null;
for (BridgeForBuiltinSpecial<Method> bridge : specials) {
generateBridge(
origin, descriptor, bridge.getFrom(), bridge.getTo(),
bridge.isSpecial(), bridge.isDelegateToSuper());
descriptor.getReturnType(), // TODO
bridge.isSpecial(), bridge.isDelegateToSuper()
);
}
}
@@ -1062,6 +1064,35 @@ public class FunctionCodegen {
}
}
private KotlinType getBridgeReturnType(Bridge<Method, DescriptorBasedFunctionHandleForJvm> bridge) {
// Return type for the bridge affects inline class values boxing/unboxing in bridge.
// Here we take 1st available return type for the bridge.
// In correct cases it doesn't matter what particular return type to use,
// since either all return types are inline class itself,
// or all return types are supertypes of inline class (and can't be inline classes).
for (DescriptorBasedFunctionHandleForJvm handle : bridge.getOriginalFunctions()) {
KotlinType returnType = handle.getDescriptor().getReturnType();
if (returnType != null) {
return returnType;
}
}
if (state.getClassBuilderMode().mightBeIncorrectCode) {
// Don't care, 'Any?' would suffice.
return state.getModule().getBuiltIns().getNullableAnyType();
} else if (bridge.getOriginalFunctions().isEmpty()) {
throw new AssertionError("No overridden functions for the bridge method '" + bridge.getTo() + "'");
} else {
throw new AssertionError(
"No return type for the bridge method '" + bridge.getTo() + "' found in the following overridden functions:\n" +
bridge.getOriginalFunctions().stream()
.map(handle -> handle.getDescriptor().toString())
.collect(Collectors.joining("\n"))
);
}
}
public static boolean isThereOverriddenInKotlinClass(@NotNull CallableMemberDescriptor descriptor) {
return CollectionsKt.any(
getAllOverriddenDescriptors(descriptor),
@@ -1376,6 +1407,7 @@ public class FunctionCodegen {
@NotNull FunctionDescriptor descriptor,
@NotNull Method bridge,
@NotNull Method delegateTo,
@NotNull KotlinType bridgeReturnType,
boolean isSpecialBridge,
boolean isStubDeclarationWithDelegationToSuper
) {
@@ -1452,7 +1484,7 @@ public class FunctionCodegen {
}
KotlinType returnType = descriptor.getReturnType();
StackValue.coerce(delegateTo.getReturnType(), returnType, bridge.getReturnType(), returnType, iv);
StackValue.coerce(delegateTo.getReturnType(), returnType, bridge.getReturnType(), bridgeReturnType, iv);
iv.areturn(bridge.getReturnType());
endVisit(mv, "bridge method", origin);
@@ -200,7 +200,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
}
InstructionAdapter v = codegen.v;
result.put(returnType, v);
result.put(returnType, functionDescriptor.getReturnType(), v);
v.areturn(returnType);
}
@@ -88,6 +88,6 @@ fun <Signature> generateBridgesForFunctionDescriptorForJvm(
descriptor: FunctionDescriptor,
signature: (FunctionDescriptor) -> Signature,
state: GenerationState
): Set<Bridge<Signature>> {
): Set<Bridge<Signature, DescriptorBasedFunctionHandleForJvm>> {
return generateBridges(DescriptorBasedFunctionHandleForJvm(descriptor, state)) { signature(it.descriptor) }
}
@@ -936,10 +936,13 @@ class KotlinTypeMapper @JvmOverloads constructor(
private fun forceBoxedReturnType(descriptor: FunctionDescriptor): Boolean {
if (isBoxMethodForInlineClass(descriptor)) return true
return isJvmPrimitive(descriptor.returnType!!) &&
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitive(it.returnType!!) }
return isJvmPrimitiveOrInlineClass(descriptor.returnType!!) &&
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitiveOrInlineClass(it.returnType!!) }
}
private fun isJvmPrimitiveOrInlineClass(kotlinType: KotlinType) =
KotlinBuiltIns.isPrimitiveType(kotlinType) || kotlinType.isInlineClassType()
private fun isBoxMethodForInlineClass(descriptor: FunctionDescriptor): Boolean {
val containingDeclaration = descriptor.containingDeclaration
return containingDeclaration.isInlineClass() &&
@@ -947,12 +950,6 @@ class KotlinTypeMapper @JvmOverloads constructor(
descriptor.name == InlineClassDescriptorResolver.BOX_METHOD_NAME
}
private fun isJvmPrimitive(kotlinType: KotlinType): Boolean {
if (KotlinBuiltIns.isPrimitiveType(kotlinType)) return true
return kotlinType.isInlineClassType() && !kotlinType.isError && AsmUtil.isPrimitive(mapInlineClassType(kotlinType))
}
fun mapFieldSignature(backingFieldType: KotlinType, propertyDescriptor: PropertyDescriptor): String? {
val sw = BothSignatureWriter(BothSignatureWriter.Mode.TYPE)
@@ -12699,6 +12699,104 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
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 AbstractFirBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
}
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_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)
@@ -0,0 +1,24 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
inline class X(val x: Any)
interface IFoo {
fun foo(): Any
fun bar(): X
}
class TestX : IFoo {
override fun foo(): X = X("O")
override fun bar(): X = X("K")
}
fun box(): String {
val t: IFoo = TestX()
val tFoo = t.foo()
if (tFoo !is X) {
throw AssertionError("X expected: $tFoo")
}
return (t.foo() as X).x.toString() + t.bar().x.toString()
}
@@ -0,0 +1,31 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
interface IFoo {
fun foo(): String
}
inline class ICFoo(val t: IFoo): IFoo {
override fun foo(): String = t.foo()
}
interface IBar {
fun bar(): IFoo
}
object FooOK : IFoo {
override fun foo(): String = "OK"
}
class Test : IBar {
override fun bar(): ICFoo = ICFoo(FooOK)
}
fun box(): String {
val test: IBar = Test()
val bar = test.bar()
if (bar !is ICFoo) {
throw AssertionError("bar: $bar")
}
return bar.foo()
}
@@ -0,0 +1,23 @@
// IGNORE_BACKEND_FIR: JVM_IR
inline class X(val x: Char)
interface IFoo {
fun foo(): Any
fun bar(): X
}
class TestX : IFoo {
override fun foo(): X = X('O')
override fun bar(): X = X('K')
}
fun box(): String {
val t: IFoo = TestX()
val tFoo = t.foo()
if (tFoo !is X) {
throw AssertionError("X expected: $tFoo")
}
return (t.foo() as X).x.toString() + t.bar().x.toString()
}
@@ -0,0 +1,53 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// KJS_WITH_FULL_RUNTIME
// IGNORE_BACKEND: JVM_IR
interface IFooList {
fun foo(): List<String>
}
interface IFooMutableList {
fun foo(): MutableList<String>
}
inline class AL(val t: MutableList<String>) : MutableList<String> {
override val size: Int get() = t.size
override fun get(index: Int): String = t.get(index)
override fun set(index: Int, element: String): String = t.set(index, element)
override fun contains(element: String): Boolean = t.contains(element)
override fun containsAll(elements: Collection<String>): Boolean = t.containsAll(elements)
override fun indexOf(element: String): Int = t.indexOf(element)
override fun isEmpty(): Boolean = t.isEmpty()
override fun iterator(): MutableIterator<String> = t.iterator()
override fun lastIndexOf(element: String): Int = t.lastIndexOf(element)
override fun add(element: String): Boolean = t.add(element)
override fun add(index: Int, element: String) = t.add(index, element)
override fun addAll(index: Int, elements: Collection<String>): Boolean = t.addAll(index, elements)
override fun addAll(elements: Collection<String>): Boolean = t.addAll(elements)
override fun listIterator(): MutableListIterator<String> = t.listIterator()
override fun listIterator(index: Int): MutableListIterator<String> = t.listIterator(index)
override fun clear() { t.clear() }
override fun remove(element: String): Boolean = t.remove(element)
override fun removeAll(elements: Collection<String>): Boolean = t.removeAll(elements)
override fun removeAt(index: Int): String = t.removeAt(index)
override fun retainAll(elements: Collection<String>): Boolean = t.retainAll(elements)
override fun subList(fromIndex: Int, toIndex: Int): MutableList<String> = t.subList(fromIndex, toIndex)
}
class Test : IFooList, IFooMutableList {
val arr = arrayListOf<String>()
override fun foo() = AL(arr)
}
fun box(): String {
val t1: IFooList = Test()
val list1 = t1.foo()
if (list1 !is AL) throw AssertionError("list1: $list1")
val t2: IFooMutableList = Test()
val list2 = t2.foo()
if (list2 !is AL) throw AssertionError("list2: $list2")
return "OK"
}
@@ -0,0 +1,40 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface IQ1
interface IQ2
inline class X(val x: Any): IQ1, IQ2
interface IFoo1 {
fun foo(): IQ1
}
interface IFoo2 {
fun foo(): IQ2
}
class Test : IFoo1, IFoo2 {
override fun foo() = X("OK")
}
fun box(): String {
val t1: IFoo1 = Test()
val x1 = t1.foo()
if (x1 !is X) {
throw AssertionError("x1: X expected: $x1")
}
if (x1.x != "OK") {
throw AssertionError("x1: ${x1.x}")
}
val t2: IFoo2 = Test()
val x2 = t2.foo()
if (x2 !is X) {
throw AssertionError("x2: X expected: $x2")
}
if (x2.x != "OK") {
throw AssertionError("x2: ${x2.x}")
}
return "OK"
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
inline class X(val x: Any)
interface IFoo<T> {
fun foo(): T
fun bar(): X
}
class TestX : IFoo<X> {
override fun foo(): X = X("O")
override fun bar(): X = X("K")
}
fun box(): String {
val t: IFoo<X> = TestX()
val tFoo: Any = t.foo()
if (tFoo !is X) {
throw AssertionError("X expected: $tFoo")
}
return (t.foo() as X).x.toString() + t.bar().x.toString()
}
@@ -0,0 +1,46 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface GFoo<out T> {
fun foo(): T
}
interface IBar {
fun bar(): String
}
interface SFooBar : GFoo<IBar>
inline class X(val x: String) : IBar {
override fun bar(): String = x
}
class Test : SFooBar {
override fun foo() = X("OK")
}
fun box(): String {
val t1: SFooBar = Test()
val foo1 = t1.foo()
if (foo1 !is X) {
throw AssertionError("foo1: $foo1")
}
val bar1 = foo1.bar()
if (bar1 != "OK") {
throw AssertionError("bar1: $bar1")
}
val t2: GFoo<Any> = Test()
val foo2 = t2.foo()
if (foo2 !is IBar) {
throw AssertionError("foo2 !is IBar: $foo2")
}
val bar2 = foo2.bar()
if (bar2 != "OK") {
throw AssertionError("bar2: $bar2")
}
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
return "OK"
}
@@ -0,0 +1,21 @@
// IGNORE_BACKEND_FIR: JVM_IR
inline class X(val x: String)
interface IFoo1<T> {
fun foo(x: T): X
}
interface IFoo2 {
fun foo(x: String): X
}
class Test : IFoo1<String>, IFoo2 {
override fun foo(x: String): X = X(x)
}
fun box(): String {
val t1: IFoo1<String> = Test()
val t2: IFoo2 = Test()
return t1.foo("O").x + t2.foo("K").x
}
@@ -0,0 +1,18 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
inline class ResultOrClosed(val x: Any?)
interface A<T> {
fun foo(): T
}
class B : A<ResultOrClosed> {
override fun foo(): ResultOrClosed = ResultOrClosed("OK")
}
fun box(): String {
val foo: Any = (B() as A<ResultOrClosed>).foo()
if (foo !is ResultOrClosed) throw AssertionError("foo: $foo")
return foo.x.toString()
}
@@ -0,0 +1,24 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
inline class FieldValue(val value: String)
enum class RequestFields {
ENUM_ONE
}
data class RequestInputParameters(
private val backingMap: Map<RequestFields, FieldValue>
) : Map<RequestFields, FieldValue> by backingMap
fun box(): String {
val testMap1 = mapOf(RequestFields.ENUM_ONE to FieldValue("value1"))
val test1 = testMap1[RequestFields.ENUM_ONE]!!
if (test1.value != "value1") throw AssertionError("test1: $test1")
val testMap2 = RequestInputParameters(mapOf(RequestFields.ENUM_ONE to FieldValue("value2")))
val test2 = testMap2[RequestFields.ENUM_ONE]!!
if (test2.value != "value2") throw AssertionError("test2: $test2")
return "OK"
}
@@ -0,0 +1,19 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
inline class NumberInlineClass(val value: Double)
interface TypeAdapter<FROM, TO> {
fun decode(string: FROM): TO
}
class StringToDoubleTypeAdapter : TypeAdapter<String, NumberInlineClass> {
override fun decode(string: String) = NumberInlineClass(string.toDouble())
}
fun box(): String {
val typeAdapter = StringToDoubleTypeAdapter()
val test = typeAdapter.decode("2019")
if (test.value != 2019.0) throw AssertionError("test: $test")
return "OK"
}
@@ -0,0 +1,20 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
inline class NumberInlineClass(val value: Double)
interface TypeAdapter<FROM, TO> {
fun decode(string: FROM): TO
}
class StringToDoubleTypeAdapter : TypeAdapter<String, NumberInlineClass> {
override fun decode(string: String) = NumberInlineClass(string.toDouble())
}
fun box(): String {
val string: String? = "2019"
val typeAdapter = StringToDoubleTypeAdapter()
val test = string?.let(typeAdapter::decode)!!
if (test.value != 2019.0) throw AssertionError("test: $test")
return "OK"
}
@@ -0,0 +1,53 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
interface IQ {
fun ok(): String
}
inline class X(val t: IQ): IQ {
override fun ok(): String = t.ok()
}
interface IFoo1 {
fun foo(): Any
}
interface IFoo2 {
fun foo(): IQ
}
object OK : IQ {
override fun ok(): String = "OK"
}
class Test : IFoo1, IFoo2 {
override fun foo(): X = X(OK)
}
fun box(): String {
val t1: IFoo1 = Test()
val foo1 = t1.foo()
if (foo1 !is IQ) {
throw AssertionError("foo1 !is IQ: $foo1")
}
val ok1 = foo1.ok()
if (ok1 != "OK") {
throw AssertionError("ok1: $ok1")
}
if (foo1 !is X) {
throw AssertionError("foo1 !is X: $foo1")
}
val t2: IFoo2 = Test()
val foo2 = t2.foo()
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
val ok2 = foo2.ok()
if (ok2 != "OK") {
throw AssertionError("ok1: $ok2")
}
return "OK"
}
@@ -0,0 +1,53 @@
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_BACKEND: JVM_IR
interface IQ {
fun ok(): String
}
inline class X(val t: IQ): IQ {
override fun ok(): String = t.ok()
}
interface IFoo1 {
fun foo(): IQ
}
interface IFoo2 {
fun foo(): Any
}
object OK : IQ {
override fun ok(): String = "OK"
}
class Test : IFoo1, IFoo2 {
override fun foo(): X = X(OK)
}
fun box(): String {
val t1: IFoo1 = Test()
val foo1 = t1.foo()
if (foo1 !is X) {
throw AssertionError("foo1 !is X: $foo1")
}
val ok1 = foo1.ok()
if (ok1 != "OK") {
throw AssertionError("ok1: $ok1")
}
val t2: IFoo2 = Test()
val foo2 = t2.foo()
if (foo2 !is IQ) {
throw AssertionError("foo2 !is IQ: $foo2")
}
val ok2 = foo2.ok()
if (ok2 != "OK") {
throw AssertionError("ok2: $ok2")
}
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
return "OK"
}
@@ -0,0 +1,54 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface IBase
interface IQ : IBase {
fun ok(): String
}
inline class X(val t: IQ): IQ {
override fun ok(): String = t.ok()
}
interface IFoo1 {
fun foo(): Any
}
interface IFoo2<T : IBase> {
fun foo(): T
}
object OK : IQ {
override fun ok(): String = "OK"
}
class Test : IFoo1, IFoo2<IQ> {
override fun foo(): X = X(OK)
}
fun box(): String {
val t1: IFoo1 = Test()
val foo1 = t1.foo()
if (foo1 !is IQ) {
throw AssertionError("foo1 !is IQ: $foo1")
}
val ok1 = foo1.ok()
if (ok1 != "OK") {
throw AssertionError("ok1: $ok1")
}
if (foo1 !is X) {
throw AssertionError("foo1 !is X: $foo1")
}
val t2: IFoo2<IQ> = Test()
val foo2 = t2.foo()
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
val ok2 = foo2.ok()
if (ok2 != "OK") {
throw AssertionError("ok1: $ok2")
}
return "OK"
}
@@ -0,0 +1,54 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface IBase
interface IQ : IBase {
fun ok(): String
}
inline class X(val t: IQ): IQ {
override fun ok(): String = t.ok()
}
interface IFoo1<T : IBase> {
fun foo(): T
}
interface IFoo2 {
fun foo(): Any
}
object OK : IQ {
override fun ok(): String = "OK"
}
class Test : IFoo1<IQ>, IFoo2 {
override fun foo(): X = X(OK)
}
fun box(): String {
val t1: IFoo1<IQ> = Test()
val foo1 = t1.foo()
if (foo1 !is X) {
throw AssertionError("foo1 !is X: $foo1")
}
val ok1 = foo1.ok()
if (ok1 != "OK") {
throw AssertionError("ok1: $ok1")
}
val t2: IFoo2 = Test()
val foo2 = t2.foo()
if (foo2 !is IQ) {
throw AssertionError("foo2 !is IQ: $foo2")
}
val ok2 = foo2.ok()
if (ok2 != "OK") {
throw AssertionError("ok2: $ok2")
}
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
return "OK"
}
@@ -0,0 +1,37 @@
// IGNORE_BACKEND_FIR: JVM_IR
interface IFoo1<out T> {
fun foo(): T
}
interface IFoo2<out T> {
fun foo(): T
}
inline class X(val x: String)
class Test : IFoo1<X>, IFoo2<X> {
override fun foo(): X = X("OK")
}
fun box(): String {
val t1: IFoo1<Any> = Test()
val foo1 = t1.foo()
if (foo1 !is X) {
throw AssertionError("foo1 !is X: $foo1")
}
if (foo1.x != "OK") {
throw AssertionError("foo1.x != 'OK': $foo1")
}
val t2: IFoo2<Any> = Test()
val foo2 = t2.foo()
if (foo2 !is X) {
throw AssertionError("foo2 !is X: $foo2")
}
if (foo2.x != "OK") {
throw AssertionError("foo2.x != 'OK': $foo2")
}
return "OK"
}
@@ -13889,6 +13889,104 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
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 AbstractBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, 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)
@@ -52,7 +52,7 @@ class BridgeTest : TestCase() {
return Fun(text)
}
private fun bridge(from: Fun, to: Fun): Bridge<Meth> = Bridge(Meth(from), Meth(to))
private fun bridge(from: Fun, to: Fun): Bridge<Meth, Fun> = Bridge(Meth(from), Meth(to), emptySet())
/**
* Constructs a graph out of the given pairs of vertices. First vertex should be a function in the derived class,
@@ -125,13 +125,17 @@ class BridgeTest : TestCase() {
}
}
private fun doTest(function: Fun, expectedBridges: Set<Bridge<Meth>>) {
private fun doTest(function: Fun, expectedBridges: Set<Bridge<Meth, Fun>>) {
val actualBridges = generateBridges(function, ::Meth)
assert(actualBridges.firstOrNull { it.from == it.to } == null) {
assert(actualBridges.all { it.from != it.to }) {
"A bridge invoking itself was generated, which makes no sense, since it will result in StackOverflowError" +
" once called: $actualBridges"
}
assertEquals(expectedBridges, actualBridges, "Expected and actual bridge sets differ for function $function")
assertEquals(
expectedBridges.map { it.from to it.to },
actualBridges.map { it.from to it.to },
"Expected and actual bridge sets differ for function $function"
)
}
// ------------------------------------------------------------------------------------------------------------------
@@ -13889,6 +13889,104 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
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 AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, 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)
@@ -12699,6 +12699,104 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
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 AbstractIrBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInBoxReturnValueOnOverride() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_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)
@@ -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)
@@ -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)
@@ -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