From 45cc60c8e99ed75c1c5ed1781c5ba6f54c40dc16 Mon Sep 17 00:00:00 2001 From: Him188 Date: Mon, 9 Aug 2021 23:43:43 +0800 Subject: [PATCH] Fix `loadService` with fallback implementation --- mirai-core-utils/src/androidMain/kotlin/Actuals.kt | 8 +++++--- mirai-core-utils/src/commonMain/kotlin/Services.kt | 5 +++-- mirai-core-utils/src/jvmMain/kotlin/Actuals.kt | 8 +++++--- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/mirai-core-utils/src/androidMain/kotlin/Actuals.kt b/mirai-core-utils/src/androidMain/kotlin/Actuals.kt index d55d56e15..8645198cf 100644 --- a/mirai-core-utils/src/androidMain/kotlin/Actuals.kt +++ b/mirai-core-utils/src/androidMain/kotlin/Actuals.kt @@ -47,17 +47,19 @@ public actual inline fun Throwable.unwrap(): Throwable { public actual fun loadService(clazz: KClass, fallbackImplementation: String?): T { var suppressed: Throwable? = null return ServiceLoader.load(clazz.java).firstOrNull() - ?: runCatching { findCreateInstance(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull() + ?: (if (fallbackImplementation == null) null + else runCatching { findCreateInstance(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull()) ?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply { if (suppressed != null) addSuppressed(suppressed) } } -private fun findCreateInstance(fallbackImplementation: String?): T { +private fun findCreateInstance(fallbackImplementation: String): T { return Class.forName(fallbackImplementation).cast>().kotlin.run { objectInstance ?: createInstance() } } public actual fun loadServiceOrNull(clazz: KClass, fallbackImplementation: String?): T? { return ServiceLoader.load(clazz.java).firstOrNull() - ?: runCatching { findCreateInstance(fallbackImplementation) }.getOrNull() + ?: if (fallbackImplementation == null) return null + else runCatching { findCreateInstance(fallbackImplementation) }.getOrNull() } \ No newline at end of file diff --git a/mirai-core-utils/src/commonMain/kotlin/Services.kt b/mirai-core-utils/src/commonMain/kotlin/Services.kt index a5dfd1c36..1da85f04a 100644 --- a/mirai-core-utils/src/commonMain/kotlin/Services.kt +++ b/mirai-core-utils/src/commonMain/kotlin/Services.kt @@ -17,5 +17,6 @@ public expect fun loadService(clazz: KClass, fallbackImplementa public inline fun loadService(fallbackImplementation: String? = null): T = loadService(T::class, fallbackImplementation) -public inline fun loadService(noinline fallbackImplementation: () -> T): T = - loadServiceOrNull(T::class) ?: fallbackImplementation() \ No newline at end of file +// do not inline: T will be inferred to returning type of `fallbackImplementation` +public fun loadService(clazz: KClass, fallbackImplementation: () -> T): T = + loadServiceOrNull(clazz) ?: fallbackImplementation() \ No newline at end of file diff --git a/mirai-core-utils/src/jvmMain/kotlin/Actuals.kt b/mirai-core-utils/src/jvmMain/kotlin/Actuals.kt index 397e39403..417c334f5 100644 --- a/mirai-core-utils/src/jvmMain/kotlin/Actuals.kt +++ b/mirai-core-utils/src/jvmMain/kotlin/Actuals.kt @@ -35,17 +35,19 @@ public actual inline fun Throwable.unwrap(): Throwable { public actual fun loadService(clazz: KClass, fallbackImplementation: String?): T { var suppressed: Throwable? = null return ServiceLoader.load(clazz.java).firstOrNull() - ?: runCatching { findCreateInstance(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull() + ?: (if (fallbackImplementation == null) null + else runCatching { findCreateInstance(fallbackImplementation) }.onFailure { suppressed = it }.getOrNull()) ?: throw NoSuchElementException("Could not find an implementation for service class ${clazz.qualifiedName}").apply { if (suppressed != null) addSuppressed(suppressed) } } -private fun findCreateInstance(fallbackImplementation: String?): T { +private fun findCreateInstance(fallbackImplementation: String): T { return Class.forName(fallbackImplementation).cast>().kotlin.run { objectInstance ?: createInstance() } } public actual fun loadServiceOrNull(clazz: KClass, fallbackImplementation: String?): T? { return ServiceLoader.load(clazz.java).firstOrNull() - ?: runCatching { findCreateInstance(fallbackImplementation) }.getOrNull() + ?: if (fallbackImplementation == null) return null + else runCatching { findCreateInstance(fallbackImplementation) }.getOrNull() } \ No newline at end of file