[K/N] Throw exception on abstract class instantiation in ObjC
This commit is contained in:
+1
@@ -525,6 +525,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) : Runti
|
|||||||
val Kotlin_ObjCExport_convertUnitToRetained by lazyRtFunction
|
val Kotlin_ObjCExport_convertUnitToRetained by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_GetAssociatedObject by lazyRtFunction
|
val Kotlin_ObjCExport_GetAssociatedObject by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_AbstractMethodCalled by lazyRtFunction
|
val Kotlin_ObjCExport_AbstractMethodCalled by lazyRtFunction
|
||||||
|
val Kotlin_ObjCExport_AbstractClassConstructorCalled by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_RethrowExceptionAsNSError by lazyRtFunction
|
val Kotlin_ObjCExport_RethrowExceptionAsNSError by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_WrapExceptionToNSError by lazyRtFunction
|
val Kotlin_ObjCExport_WrapExceptionToNSError by lazyRtFunction
|
||||||
val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction
|
val Kotlin_ObjCExport_RethrowNSErrorAsException by lazyRtFunction
|
||||||
|
|||||||
+6
@@ -876,6 +876,12 @@ private fun ObjCExportCodeGenerator.generateObjCImp(
|
|||||||
isDirect = !isVirtual,
|
isDirect = !isVirtual,
|
||||||
baseMethod = baseMethod
|
baseMethod = baseMethod
|
||||||
) { args, resultLifetime, exceptionHandler ->
|
) { args, resultLifetime, exceptionHandler ->
|
||||||
|
if (target is IrConstructor && target.constructedClass.isAbstract()) {
|
||||||
|
callFromBridge(
|
||||||
|
context.llvm.Kotlin_ObjCExport_AbstractClassConstructorCalled,
|
||||||
|
listOf(param(0), codegen.typeInfoValue(target.parent as IrClass))
|
||||||
|
)
|
||||||
|
}
|
||||||
val llvmTarget = if (!isVirtual) {
|
val llvmTarget = if (!isVirtual) {
|
||||||
codegen.llvmFunction(target)
|
codegen.llvmFunction(target)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5450,6 +5450,14 @@ if (isAppleTarget(project)) {
|
|||||||
swiftSources = ['framework/stacktraceByLibbacktrace/']
|
swiftSources = ['framework/stacktraceByLibbacktrace/']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frameworkTest("testAbstractInstantiationFramework") {
|
||||||
|
framework('AbstractInstantiation') {
|
||||||
|
sources = ['framework/abstractInstantiation']
|
||||||
|
}
|
||||||
|
swiftSources = ['framework/abstractInstantiation/']
|
||||||
|
expectedExitStatus = 134
|
||||||
|
}
|
||||||
|
|
||||||
frameworkTest("testFrameworkBundleId") {
|
frameworkTest("testFrameworkBundleId") {
|
||||||
def currentTarget = project.target.name
|
def currentTarget = project.target.name
|
||||||
enabled = currentTarget.startsWith("mac")
|
enabled = currentTarget.startsWith("mac")
|
||||||
|
|||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class AbstractBase(val y: Int) {
|
||||||
|
abstract val x: Int
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
import Foundation
|
||||||
|
import AbstractInstantiation
|
||||||
|
|
||||||
|
func testInstantiate() throws {
|
||||||
|
// this is failure test, it shouldn't work
|
||||||
|
let base = AbstractBase(y: 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
class AbstractInstantiationTests : TestProvider {
|
||||||
|
var tests: [TestCase] = []
|
||||||
|
|
||||||
|
init() {
|
||||||
|
providers.append(self)
|
||||||
|
tests = [
|
||||||
|
TestCase(name: "testInstantiate", method: withAutorelease(testInstantiate))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ import Kt
|
|||||||
|
|
||||||
private func test1() throws {
|
private func test1() throws {
|
||||||
let user = Person.User(id: 1)
|
let user = Person.User(id: 1)
|
||||||
let worker = Person.Worker()
|
|
||||||
let employee = Person.WorkerEmployee(id: 2)
|
let employee = Person.WorkerEmployee(id: 2)
|
||||||
let contractor = Person.WorkerContractor(id: 3)
|
let contractor = Person.WorkerContractor(id: 3)
|
||||||
let userAsPerson: Person = user
|
let userAsPerson: Person = user
|
||||||
|
|||||||
@@ -1111,6 +1111,14 @@ extern "C" void Kotlin_ObjCExport_AbstractMethodCalled(id self, SEL selector) {
|
|||||||
class_getName(object_getClass(self)), sel_getName(selector)];
|
class_getName(object_getClass(self)), sel_getName(selector)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void Kotlin_ObjCExport_AbstractClassConstructorCalled(id self, const TypeInfo *clazz) {
|
||||||
|
Class objectClass = object_getClass(self);
|
||||||
|
Class constructorClass = getOrCreateClass(clazz);
|
||||||
|
if (objectClass == constructorClass) {
|
||||||
|
[NSException raise:NSGenericException format:@"Class %s is abstract and can't be instantiated", class_getName(objectClass)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" NSInteger Kotlin_ObjCExport_NSIntegerTypeProvider() {
|
extern "C" NSInteger Kotlin_ObjCExport_NSIntegerTypeProvider() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user