fix: Isolate mixins in alternative source sets
This commit is contained in:
12
src/compat/jade/java/moe/nea/firmament/compat/jade/Compat.kt
Normal file
12
src/compat/jade/java/moe/nea/firmament/compat/jade/Compat.kt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package moe.nea.firmament.compat.jade
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader
|
||||||
|
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
|
||||||
|
@CompatMeta
|
||||||
|
object Compat : ICompatMeta {
|
||||||
|
override fun shouldLoad(): Boolean {
|
||||||
|
return FabricLoader.getInstance().isModLoaded("jade")
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/compat/rei/java/moe/nea/firmament/compat/rei/Compat.kt
Normal file
12
src/compat/rei/java/moe/nea/firmament/compat/rei/Compat.kt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package moe.nea.firmament.compat.rei
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader
|
||||||
|
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
|
||||||
|
@CompatMeta
|
||||||
|
object Compat : ICompatMeta {
|
||||||
|
override fun shouldLoad(): Boolean {
|
||||||
|
return FabricLoader.getInstance().isModLoaded("roughlyenoughitems")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package moe.nea.firmament.compat.gender
|
||||||
|
|
||||||
|
import net.fabricmc.loader.api.FabricLoader
|
||||||
|
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
|
||||||
|
@CompatMeta
|
||||||
|
object Compat : ICompatMeta {
|
||||||
|
override fun shouldLoad(): Boolean {
|
||||||
|
return FabricLoader.getInstance().isModLoaded("wildfire_gender")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
package moe.nea.firmament.init;
|
package moe.nea.firmament.init;
|
||||||
|
|
||||||
|
|
||||||
|
import moe.nea.firmament.util.ErrorUtil;
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@@ -94,7 +97,7 @@ public class AutoDiscoveryPlugin {
|
|||||||
String norm = (className.substring(0, className.length() - ".class".length()))
|
String norm = (className.substring(0, className.length() - ".class".length()))
|
||||||
.replace("\\", "/")
|
.replace("\\", "/")
|
||||||
.replace("/", ".");
|
.replace("/", ".");
|
||||||
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".")) {
|
if (norm.startsWith(getMixinPackage() + ".") && !norm.endsWith(".") && ICompatMeta.Companion.shouldLoad(norm)) {
|
||||||
mixins.add(norm.substring(getMixinPackage().length() + 1));
|
mixins.add(norm.substring(getMixinPackage().length() + 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,6 +128,7 @@ public class AutoDiscoveryPlugin {
|
|||||||
*/
|
*/
|
||||||
public List<String> getMixins() {
|
public List<String> getMixins() {
|
||||||
if (mixins != null) return mixins;
|
if (mixins != null) return mixins;
|
||||||
|
try {
|
||||||
System.out.println("Trying to discover mixins");
|
System.out.println("Trying to discover mixins");
|
||||||
mixins = new ArrayList<>();
|
mixins = new ArrayList<>();
|
||||||
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
|
URL classUrl = getClass().getProtectionDomain().getCodeSource().getLocation();
|
||||||
@@ -137,12 +141,12 @@ public class AutoDiscoveryPlugin {
|
|||||||
if (s.isBlank()) {
|
if (s.isBlank()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
tryDiscoverFromContentFile(new File(s).toURI().toURL());
|
tryDiscoverFromContentFile(new File(s).toURI().toURL());
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
}
|
}
|
||||||
return mixins;
|
return mixins;
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/main/kotlin/Compat.kt
Normal file
11
src/main/kotlin/Compat.kt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package moe.nea.firmament
|
||||||
|
|
||||||
|
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
|
||||||
|
@CompatMeta
|
||||||
|
object Compat : ICompatMeta {
|
||||||
|
override fun shouldLoad(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import moe.nea.firmament.features.mining.PickaxeAbility
|
|||||||
import moe.nea.firmament.features.mining.PristineProfitTracker
|
import moe.nea.firmament.features.mining.PristineProfitTracker
|
||||||
import moe.nea.firmament.features.world.FairySouls
|
import moe.nea.firmament.features.world.FairySouls
|
||||||
import moe.nea.firmament.features.world.Waypoints
|
import moe.nea.firmament.features.world.Waypoints
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
import moe.nea.firmament.util.data.DataHolder
|
import moe.nea.firmament.util.data.DataHolder
|
||||||
|
|
||||||
object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "features", ::Config) {
|
object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "features", ::Config) {
|
||||||
@@ -83,6 +84,7 @@ object FeatureManager : DataHolder<FeatureManager.Config>(serializer(), "feature
|
|||||||
|
|
||||||
fun subscribeEvents() {
|
fun subscribeEvents() {
|
||||||
SubscriptionList.allLists.forEach { list ->
|
SubscriptionList.allLists.forEach { list ->
|
||||||
|
if (ICompatMeta.shouldLoad(list.javaClass.name))
|
||||||
runCatching {
|
runCatching {
|
||||||
list.provideSubscriptions {
|
list.provideSubscriptions {
|
||||||
it.owner.javaClass.classes.forEach {
|
it.owner.javaClass.classes.forEach {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import kotlin.reflect.KClass
|
|||||||
import kotlin.streams.asSequence
|
import kotlin.streams.asSequence
|
||||||
import moe.nea.firmament.Firmament
|
import moe.nea.firmament.Firmament
|
||||||
|
|
||||||
abstract class CompatLoader<T : Any>(val kClass: Class<T>) {
|
open class CompatLoader<T : Any>(val kClass: Class<T>) {
|
||||||
constructor(kClass: KClass<T>) : this(kClass.java)
|
constructor(kClass: KClass<T>) : this(kClass.java)
|
||||||
|
|
||||||
val loader: ServiceLoader<T> = ServiceLoader.load(kClass)
|
val loader: ServiceLoader<T> = ServiceLoader.load(kClass)
|
||||||
|
|||||||
48
src/main/kotlin/util/compatloader/CompatMeta.kt
Normal file
48
src/main/kotlin/util/compatloader/CompatMeta.kt
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package moe.nea.firmament.features.texturepack
|
||||||
|
|
||||||
|
import moe.nea.firmament.util.compatloader.CompatMeta
|
||||||
|
import moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
|
||||||
|
@CompatMeta
|
||||||
|
object Compat : ICompatMeta {
|
||||||
|
override fun shouldLoad(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
63
symbols/src/main/kotlin/process/CompatMetaProcessor.kt
Normal file
63
symbols/src/main/kotlin/process/CompatMetaProcessor.kt
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package moe.nea.firmament.annotations.process
|
||||||
|
|
||||||
|
import com.google.auto.service.AutoService
|
||||||
|
import com.google.devtools.ksp.processing.CodeGenerator
|
||||||
|
import com.google.devtools.ksp.processing.Dependencies
|
||||||
|
import com.google.devtools.ksp.processing.KSPLogger
|
||||||
|
import com.google.devtools.ksp.processing.Resolver
|
||||||
|
import com.google.devtools.ksp.processing.SymbolProcessor
|
||||||
|
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
|
||||||
|
import com.google.devtools.ksp.processing.SymbolProcessorProvider
|
||||||
|
import com.google.devtools.ksp.symbol.KSAnnotated
|
||||||
|
import com.google.devtools.ksp.symbol.KSClassDeclaration
|
||||||
|
import com.google.devtools.ksp.symbol.KSName
|
||||||
|
|
||||||
|
class CompatMetaProcessor(val logger: KSPLogger, val codeGenerator: CodeGenerator, val sourceSetName: String) :
|
||||||
|
SymbolProcessor {
|
||||||
|
override fun process(resolver: Resolver): List<KSAnnotated> {
|
||||||
|
val files = resolver.getAllFiles().toList()
|
||||||
|
val packages = files.mapTo(mutableSetOf()) { it.packageName.asString() }
|
||||||
|
packages.add("moe.nea.firmament.annotations.generated.$sourceSetName")
|
||||||
|
val compatMeta = resolver.getSymbolsWithAnnotation("moe.nea.firmament.util.compatloader.CompatMeta")
|
||||||
|
.singleOrNull() as KSClassDeclaration? ?: return listOf()
|
||||||
|
val dependencies = Dependencies(aggregating = true, *files.toTypedArray())
|
||||||
|
val generatedFileName = "GeneratedCompat${sourceSetName.replaceFirstChar { it.uppercaseChar() }}"
|
||||||
|
val compatFile =
|
||||||
|
codeGenerator.createNewFile(dependencies, "moe.nea.firmament.annotations.generated.$sourceSetName", generatedFileName)
|
||||||
|
.bufferedWriter()
|
||||||
|
compatFile.appendLine("// This file is @generated by SubscribeAnnotationProcessor")
|
||||||
|
compatFile.appendLine("// Do not edit")
|
||||||
|
compatFile.appendLine("package moe.nea.firmament.annotations.generated.$sourceSetName")
|
||||||
|
compatFile.appendLine("class $generatedFileName : moe.nea.firmament.util.compatloader.ICompatMetaGen {")
|
||||||
|
compatFile.appendLine("""
|
||||||
|
override fun owns(className: String): Boolean {
|
||||||
|
return moe.nea.firmament.util.compatloader.CompatHelper.isOwnedByPackage(className, ${
|
||||||
|
packages.joinToString { "\"" + it + "\"" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override val meta: moe.nea.firmament.util.compatloader.ICompatMeta
|
||||||
|
get() = ${compatMeta.qualifiedName!!.asString()}
|
||||||
|
""")
|
||||||
|
compatFile.appendLine("}")
|
||||||
|
compatFile.close()
|
||||||
|
val metaInf = codeGenerator.createNewFileByPath(
|
||||||
|
dependencies,
|
||||||
|
"META-INF/services/moe.nea.firmament.util.compatloader.ICompatMetaGen", extensionName = "")
|
||||||
|
.bufferedWriter()
|
||||||
|
metaInf.append("moe.nea.firmament.annotations.generated.$sourceSetName.")
|
||||||
|
metaInf.appendLine(generatedFileName)
|
||||||
|
metaInf.close()
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@AutoService(SymbolProcessorProvider::class)
|
||||||
|
class Provider : SymbolProcessorProvider {
|
||||||
|
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
|
||||||
|
return CompatMetaProcessor(environment.logger,
|
||||||
|
environment.codeGenerator,
|
||||||
|
environment.options["firmament.sourceset"] ?: "main")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@ class SubscribeAnnotationProcessor(
|
|||||||
val generatedFileName = "AllSubscriptions${sourceSetName.replaceFirstChar { it.uppercaseChar() }}"
|
val generatedFileName = "AllSubscriptions${sourceSetName.replaceFirstChar { it.uppercaseChar() }}"
|
||||||
val subscriptionsFile =
|
val subscriptionsFile =
|
||||||
codeGenerator
|
codeGenerator
|
||||||
.createNewFile(dependencies, "moe.nea.firmament.annotations.generated", generatedFileName)
|
.createNewFile(dependencies, "moe.nea.firmament.annotations.generated.$sourceSetName", generatedFileName)
|
||||||
.bufferedWriter()
|
.bufferedWriter()
|
||||||
subscriptionsFile.apply {
|
subscriptionsFile.apply {
|
||||||
appendLine("// This file is @generated by SubscribeAnnotationProcessor")
|
appendLine("// This file is @generated by SubscribeAnnotationProcessor")
|
||||||
@@ -40,7 +40,7 @@ class SubscribeAnnotationProcessor(
|
|||||||
for (file in subscriptionSet) {
|
for (file in subscriptionSet) {
|
||||||
appendLine("// Dependency: ${file.filePath}")
|
appendLine("// Dependency: ${file.filePath}")
|
||||||
}
|
}
|
||||||
appendLine("package moe.nea.firmament.annotations.generated")
|
appendLine("package moe.nea.firmament.annotations.generated.$sourceSetName")
|
||||||
appendLine()
|
appendLine()
|
||||||
appendLine("import moe.nea.firmament.events.subscription.*")
|
appendLine("import moe.nea.firmament.events.subscription.*")
|
||||||
appendLine()
|
appendLine()
|
||||||
@@ -65,7 +65,7 @@ class SubscribeAnnotationProcessor(
|
|||||||
dependencies,
|
dependencies,
|
||||||
"META-INF/services/moe.nea.firmament.events.subscription.SubscriptionList", extensionName = "")
|
"META-INF/services/moe.nea.firmament.events.subscription.SubscriptionList", extensionName = "")
|
||||||
.bufferedWriter()
|
.bufferedWriter()
|
||||||
metaInf.append("moe.nea.firmament.annotations.generated.")
|
metaInf.append("moe.nea.firmament.annotations.generated.$sourceSetName.")
|
||||||
metaInf.appendLine(generatedFileName)
|
metaInf.appendLine(generatedFileName)
|
||||||
metaInf.close()
|
metaInf.close()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user