From 7842e6ca43053a70f225d54f107f49e35ea6f087 Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 13 May 2019 20:16:42 +0300 Subject: [PATCH] Fix #2830, #2959 --- .../tests/framework/values/values.kt | 16 +++++++++++ .../tests/framework/values/values.swift | 12 ++++++++ runtime/src/main/cpp/ObjCExport.mm | 28 +++++++++---------- 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/backend.native/tests/framework/values/values.kt b/backend.native/tests/framework/values/values.kt index 70f553ffb11..ecbee1009f1 100644 --- a/backend.native/tests/framework/values/values.kt +++ b/backend.native/tests/framework/values/values.kt @@ -354,4 +354,20 @@ class GH2931 { class GH2945(var errno: Int) { fun testErrnoInSelector(p: Int, errno: Int) = p + errno +} + +class GH2830 { + interface I + private class PrivateImpl : I + + fun getI(): Any = PrivateImpl() +} + +class GH2959 { + interface I { + val id: Int + } + private class PrivateImpl(override val id: Int) : I + + fun getI(id: Int): List = listOf(PrivateImpl(id)) } \ No newline at end of file diff --git a/backend.native/tests/framework/values/values.swift b/backend.native/tests/framework/values/values.swift index dd9d4faca28..1ade50e6e69 100644 --- a/backend.native/tests/framework/values/values.swift +++ b/backend.native/tests/framework/values/values.swift @@ -536,6 +536,16 @@ func testGH2945() throws { try assertEquals(actual: 7, expected: gh2945.testErrnoInSelector(p: 3, errno: 4)) } +// See https://github.com/JetBrains/kotlin-native/issues/2830 +func testGH2830() throws { + try assertTrue(GH2830().getI() is GH2830I) +} + +// See https://github.com/JetBrains/kotlin-native/issues/2959 +func testGH2959() throws { + try assertEquals(actual: GH2959().getI(id: 2959)[0].id, expected: 2959) +} + // See https://github.com/JetBrains/kotlin-native/issues/2931 func testGH2931() throws { for i in 0..<50000 { @@ -597,6 +607,8 @@ class ValuesTests : TestProvider { TestCase(name: "TestSwiftOverride", method: withAutorelease(testSwiftOverride)), TestCase(name: "TestKotlinOverride", method: withAutorelease(testKotlinOverride)), TestCase(name: "TestGH2945", method: withAutorelease(testGH2945)), + TestCase(name: "TestGH2830", method: withAutorelease(testGH2830)), + TestCase(name: "TestGH2959", method: withAutorelease(testGH2959)), TestCase(name: "TestGH2931", method: withAutorelease(testGH2931)), ] } diff --git a/runtime/src/main/cpp/ObjCExport.mm b/runtime/src/main/cpp/ObjCExport.mm index 9d8a74a398d..9ee2a083493 100644 --- a/runtime/src/main/cpp/ObjCExport.mm +++ b/runtime/src/main/cpp/ObjCExport.mm @@ -326,18 +326,21 @@ static const ObjCTypeAdapter* getTypeAdapter(const TypeInfo* typeInfo) { return typeInfo->writableInfo_->objCExport.typeAdapter; } -static Protocol* getProtocolForInterface(const TypeInfo* interfaceInfo) { +static void addProtocolForAdapter(Class clazz, const ObjCTypeAdapter* protocolAdapter) { + Protocol* protocol = objc_getProtocol(protocolAdapter->objCName); + if (protocol != nullptr) { + class_addProtocol(clazz, protocol); + class_addProtocol(object_getClass(clazz), protocol); + } else { + // TODO: construct the protocol in compiler instead, because this case can't be handled easily. + } +} + +static void addProtocolForInterface(Class clazz, const TypeInfo* interfaceInfo) { const ObjCTypeAdapter* protocolAdapter = getTypeAdapter(interfaceInfo); if (protocolAdapter != nullptr) { - Protocol* protocol = objc_getProtocol(protocolAdapter->objCName); - if (protocol != nullptr) { - return protocol; - } else { - // TODO: construct the protocol in compiler instead, because this case can't be handled easily. - } + addProtocolForAdapter(clazz, protocolAdapter); } - - return nullptr; } static const TypeInfo* getOrCreateTypeInfo(Class clazz); @@ -372,11 +375,7 @@ static void initializeClass(Class clazz) { if (isClassForPackage) return; for (int i = 0; i < typeInfo->implementedInterfacesCount_; ++i) { - Protocol* protocol = getProtocolForInterface(typeInfo->implementedInterfaces_[i]); - if (protocol != nullptr) { - class_addProtocol(clazz, protocol); - class_addProtocol(object_getClass(clazz), protocol); - } + addProtocolForInterface(clazz, typeInfo->implementedInterfaces_[i]); } } @@ -1013,6 +1012,7 @@ static Class createClass(const TypeInfo* typeInfo, Class superClass) { const ObjCTypeAdapter* typeAdapter = getTypeAdapter(interface); if (typeAdapter != nullptr) { addVirtualAdapters(result, typeAdapter); + addProtocolForAdapter(result, typeAdapter); } } }