Improve error message for non-overridable methods in framework

This commit is contained in:
Svyatoslav Scherbina
2019-01-14 15:49:13 +03:00
committed by SvyatoslavScherbina
parent fe7685eb03
commit 757449ba9c
2 changed files with 23 additions and 14 deletions
@@ -895,9 +895,9 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
exposedMethods.forEach { 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 presentVtableBridges = mutableSetOf<Int?>(null)
@@ -929,7 +929,11 @@ private fun ObjCExportCodeGenerator.createTypeAdapter(
// Mark it as non-overridable:
baseMethods.distinctBy { namer.getSelector(it) }.forEach { baseMethod ->
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.
+16 -11
View File
@@ -794,6 +794,20 @@ static void insertOrReplace(KStdVector<MethodTableRecord>& methodTable, MethodNa
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) {
Class superClass = class_getSuperclass(clazz);
@@ -852,12 +866,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType) {
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
if (definedSelectors.find(sel_registerName(adapter->selector)) == definedSelectors.end()) continue;
if (adapter->kotlinImpl == nullptr) {
[NSException raise:NSGenericException
format:@"[%s %s] can't be implemented",
class_getName(clazz), adapter->selector];
// TODO: describe the reasons
}
throwIfCantBeOverridden(clazz, adapter);
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(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) {
const KotlinToObjCMethodAdapter* adapter = &typeAdapter->reverseAdapters[i];
if (adapter->kotlinImpl == nullptr) {
[NSException raise:NSGenericException
format:@"[%s %s] can't be implemented",
class_getName(clazz), adapter->selector];
}
throwIfCantBeOverridden(clazz, adapter);
insertOrReplace(methodTable, adapter->nameSignature, const_cast<void*>(adapter->kotlinImpl));
RuntimeAssert(adapter->vtableIndex == -1, "");