diff options
author | Linnea Gräf <nea@nea.moe> | 2025-03-18 21:40:32 +0100 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2025-03-18 21:40:32 +0100 |
commit | 4c5ddd2fddb792afe2816e238e54fd496a6c75c6 (patch) | |
tree | ed6dfe96e698e5717a38dd90721eab441715eedb /src/main/kotlin/util/compatloader/CompatMeta.kt | |
parent | 40ce4f856718d6b0c7fa15cd40a1f6db2f774e6f (diff) | |
download | Firmament-4c5ddd2fddb792afe2816e238e54fd496a6c75c6.tar.gz Firmament-4c5ddd2fddb792afe2816e238e54fd496a6c75c6.tar.bz2 Firmament-4c5ddd2fddb792afe2816e238e54fd496a6c75c6.zip |
fix: Isolate mixins in alternative source sets
Diffstat (limited to 'src/main/kotlin/util/compatloader/CompatMeta.kt')
-rw-r--r-- | src/main/kotlin/util/compatloader/CompatMeta.kt | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/main/kotlin/util/compatloader/CompatMeta.kt b/src/main/kotlin/util/compatloader/CompatMeta.kt new file mode 100644 index 0000000..cf63645 --- /dev/null +++ b/src/main/kotlin/util/compatloader/CompatMeta.kt @@ -0,0 +1,48 @@ +package moe.nea.firmament.util.compatloader + +import java.util.ServiceLoader +import moe.nea.firmament.events.subscription.SubscriptionList +import moe.nea.firmament.init.AutoDiscoveryPlugin +import moe.nea.firmament.util.ErrorUtil + +/** + * Declares the compat meta interface for the current source set. + * This is used by [CompatLoader], [SubscriptionList], and [AutoDiscoveryPlugin]. Annotate a [ICompatMeta] object with + * this. + */ +annotation class CompatMeta + +interface ICompatMetaGen { + fun owns(className: String): Boolean + val meta: ICompatMeta +} + +interface ICompatMeta { + fun shouldLoad(): Boolean + + companion object { + val allMetas = ServiceLoader + .load(ICompatMetaGen::class.java) + .toList() + + fun shouldLoad(className: String): Boolean { + // TODO: replace this with a more performant package lookup + val meta = if (ErrorUtil.aggressiveErrors) { + val fittingMetas = allMetas.filter { it.owns(className) } + require(fittingMetas.size == 1) { "Orphaned or duplicate owned class $className (${fittingMetas.map { it.meta }}). Consider adding a @CompatMeta object." } + fittingMetas.single() + } else { + allMetas.firstOrNull { it.owns(className) } + } + return meta?.meta?.shouldLoad() ?: true + } + } +} + +object CompatHelper { + fun isOwnedByPackage(className: String, vararg packages: String): Boolean { + // TODO: create package lookup structure once + val packageName = className.substringBeforeLast('.') + return packageName in packages + } +} |