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:
+21
-13
@@ -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);
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
Generated
+98
@@ -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)
|
||||
|
||||
compiler/testData/codegen/box/inlineClasses/boxReturnValueOnOverride/covariantOverrideErasedToAny.kt
Vendored
+24
@@ -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()
|
||||
}
|
||||
+31
@@ -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()
|
||||
}
|
||||
+23
@@ -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()
|
||||
}
|
||||
+53
@@ -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"
|
||||
}
|
||||
+40
@@ -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"
|
||||
}
|
||||
+24
@@ -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()
|
||||
}
|
||||
Vendored
+46
@@ -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"
|
||||
}
|
||||
+21
@@ -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
|
||||
}
|
||||
+18
@@ -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()
|
||||
}
|
||||
+24
@@ -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"
|
||||
}
|
||||
+19
@@ -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"
|
||||
}
|
||||
+20
@@ -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"
|
||||
}
|
||||
Vendored
+53
@@ -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"
|
||||
}
|
||||
Vendored
+53
@@ -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"
|
||||
}
|
||||
Vendored
+54
@@ -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"
|
||||
}
|
||||
Vendored
+54
@@ -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"
|
||||
}
|
||||
+37
@@ -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"
|
||||
}
|
||||
+98
@@ -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"
|
||||
)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
+98
@@ -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)
|
||||
|
||||
+98
@@ -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)
|
||||
|
||||
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