Improve error message for non-overridable methods in framework
This commit is contained in:
committed by
SvyatoslavScherbina
parent
fe7685eb03
commit
757449ba9c
+7
-3
@@ -895,9 +895,9 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
|||||||
|
|
||||||
exposedMethods.forEach { method ->
|
exposedMethods.forEach { method ->
|
||||||
val baseMethods = mapper.getBaseMethods(method)
|
val baseMethods = mapper.getBaseMethods(method)
|
||||||
val hasSelectorClash = baseMethods.map { namer.getSelector(it) }.distinct().size > 1
|
val hasSelectorAmbiguity = baseMethods.map { namer.getSelector(it) }.distinct().size > 1
|
||||||
|
|
||||||
if (method.isOverridable && !hasSelectorClash) {
|
if (method.isOverridable && !hasSelectorAmbiguity) {
|
||||||
val baseMethod = baseMethods.first()
|
val baseMethod = baseMethods.first()
|
||||||
|
|
||||||
val presentVtableBridges = mutableSetOf<Int?>(null)
|
val presentVtableBridges = mutableSetOf<Int?>(null)
|
||||||
@@ -929,7 +929,11 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
|
|||||||
// Mark it as non-overridable:
|
// Mark it as non-overridable:
|
||||||
baseMethods.distinctBy { namer.getSelector(it) }.forEach { baseMethod ->
|
baseMethods.distinctBy { namer.getSelector(it) }.forEach { baseMethod ->
|
||||||
reverseAdapters += KotlinToObjCMethodAdapter(
|
reverseAdapters += KotlinToObjCMethodAdapter(
|
||||||
namer.getSelector(baseMethod), -1, -1, NullPointer(int8Type))
|
namer.getSelector(baseMethod),
|
||||||
|
-1,
|
||||||
|
vtableIndex = if (hasSelectorAmbiguity) -2 else -1, // Describes the reason.
|
||||||
|
kotlinImpl = NullPointer(int8Type)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: some fake-overrides can be skipped.
|
// TODO: some fake-overrides can be skipped.
|
||||||
|
|||||||
@@ -794,6 +794,20 @@ static void insertOrReplace(KStdVector<MethodTableRecord>& methodTable, MethodNa
|
|||||||
methodTable.insert(methodTable.begin(), record);
|
methodTable.insert(methodTable.begin(), record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void throwIfCantBeOverridden(Class clazz, const KotlinToObjCMethodAdapter* adapter) {
|
||||||
|
if (adapter->kotlinImpl == nullptr) {
|
||||||
|
NSString* reason;
|
||||||
|
switch (adapter->vtableIndex) {
|
||||||
|
case -1: reason = @"it is final"; break;
|
||||||
|
case -2: reason = @"original Kotlin method has more than one selector"; break;
|
||||||
|
default: reason = @""; break;
|
||||||
|
}
|
||||||
|
[NSException raise:NSGenericException
|
||||||
|
format:@"[%s %s] can't be overridden: %@",
|
||||||
|
class_getName(clazz), adapter->selector, reason];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType) {
|
static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType) {
|
||||||
Class superClass = class_getSuperclass(clazz);
|
Class superClass = class_getSuperclass(clazz);
|
||||||
|
|
||||||
@@ -852,12 +866,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType) {
|
|||||||
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
|
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
|
||||||
if (definedSelectors.find(sel_registerName(adapter->selector)) == definedSelectors.end()) continue;
|
if (definedSelectors.find(sel_registerName(adapter->selector)) == definedSelectors.end()) continue;
|
||||||
|
|
||||||
if (adapter->kotlinImpl == nullptr) {
|
throwIfCantBeOverridden(clazz, adapter);
|
||||||
[NSException raise:NSGenericException
|
|
||||||
format:@"[%s %s] can't be implemented",
|
|
||||||
class_getName(clazz), adapter->selector];
|
|
||||||
// TODO: describe the reasons
|
|
||||||
}
|
|
||||||
|
|
||||||
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
||||||
if (adapter->vtableIndex != -1) vtable[adapter->vtableIndex] = adapter->kotlinImpl;
|
if (adapter->vtableIndex != -1) vtable[adapter->vtableIndex] = adapter->kotlinImpl;
|
||||||
@@ -870,11 +879,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType) {
|
|||||||
|
|
||||||
for (int i = 0; i < typeAdapter->reverseAdapterNum; ++i) {
|
for (int i = 0; i < typeAdapter->reverseAdapterNum; ++i) {
|
||||||
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
|
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
|
||||||
if (adapter->kotlinImpl == nullptr) {
|
throwIfCantBeOverridden(clazz, adapter);
|
||||||
[NSException raise:NSGenericException
|
|
||||||
format:@"[%s %s] can't be implemented",
|
|
||||||
class_getName(clazz), adapter->selector];
|
|
||||||
}
|
|
||||||
|
|
||||||
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
|
||||||
RuntimeAssert(adapter->vtableIndex == -1, "");
|
RuntimeAssert(adapter->vtableIndex == -1, "");
|
||||||
|
|||||||
Reference in New Issue
Block a user