Mixin icon indicating copy to clipboard operation
Mixin copied to clipboard

Fix error when a mixin missing a target has an inner class

Open Chocohead opened this issue 1 year ago • 7 comments

When a mixin has multiple target classes and at least one is missing, as well as at least one inner class to merge into the targets, Mixin would previously throw an error when applying the mixin to any target.

Using the following mixin:

@Mixin(value = {Target.class}, targets = "com.chocohead.test.Missing")
abstract class MissingTargetMixin {
	class Inner {
	}
}

would produce the following log upon trying to load Target:

[DEBUG] [FabricLoader/Mixin]: Preparing tests.mixins.json (1)
[WARN] [FabricLoader/Mixin]: Error loading class: com/chocohead/test/Missing (java.lang.ClassNotFoundException: com/chocohead/test/Missing)
[WARN] [FabricLoader/Mixin]: @Mixin target com.chocohead.test.Missing was not found tests.mixins.json:MissingTargetMixin from mod test-mod
[WARN] [FabricLoader/Mixin]: Error loading class: com/chocohead/test/Missing (java.lang.ClassNotFoundException: com/chocohead/test/Missing)
[DEBUG] [FabricLoader/Mixin]: Inner class com/chocohead/test/mixin/MissingTargetMixin$Inner in com/chocohead/test/mixin/MissingTargetMixin on com/chocohead/test/target/Target gets unique name com/chocohead/test/target/Target$Inner$95f9752e1a2243388dc678dfab05f815
[WARN] [FabricLoader/Mixin]: Error loading class: com/chocohead/test/Missing (java.lang.ClassNotFoundException: com/chocohead/test/Missing)
[ERROR] [FabricLoader/Mixin]: Prepare error for tests.mixins.json:MissingTargetMixin from mod test-mod during activity: [Prepare inner classes]
org.spongepowered.asm.mixin.transformer.throwables.MixinPreProcessorException: Prepare error for tests.mixins.json:MissingTargetMixin from mod test-mod during activity: [Prepare inner classes]
	at org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.prepare(MixinPreProcessorStandard.java:197)
	at org.spongepowered.asm.mixin.transformer.MixinInfo$State.validateChanges(MixinInfo.java:442)
	at org.spongepowered.asm.mixin.transformer.MixinInfo$State.validate(MixinInfo.java:342)
	at org.spongepowered.asm.mixin.transformer.MixinInfo.validate(MixinInfo.java:913)
	at org.spongepowered.asm.mixin.transformer.MixinConfig.postInitialise(MixinConfig.java:884)
	at org.spongepowered.asm.mixin.transformer.MixinProcessor.prepareConfigs(MixinProcessor.java:568)
	at org.spongepowered.asm.mixin.transformer.MixinProcessor.select(MixinProcessor.java:462)
	at org.spongepowered.asm.mixin.transformer.MixinProcessor.checkSelect(MixinProcessor.java:438)
	at org.spongepowered.asm.mixin.transformer.MixinProcessor.applyMixins(MixinProcessor.java:290)
	at org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClass(MixinTransformer.java:234)
	at org.spongepowered.asm.mixin.transformer.MixinTransformer.transformClassBytes(MixinTransformer.java:202)
	at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.getPostMixinClassByteArray(KnotClassDelegate.java:422)
	at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.tryLoadClass(KnotClassDelegate.java:323)
	at net.fabricmc.loader.impl.launch.knot.KnotClassDelegate.loadClass(KnotClassDelegate.java:218)
	at net.fabricmc.loader.impl.launch.knot.KnotClassLoader.loadClass(KnotClassLoader.java:119)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:348)
	at net.fabricmc.loader.impl.util.DefaultLanguageAdapter.create(DefaultLanguageAdapter.java:50)
	at net.fabricmc.loader.impl.entrypoint.EntrypointStorage$NewEntry.getOrCreate(EntrypointStorage.java:124)
	at net.fabricmc.loader.impl.entrypoint.EntrypointContainerImpl.getEntrypoint(EntrypointContainerImpl.java:53)
	at net.fabricmc.loader.impl.FabricLoaderImpl.invokeEntrypoints(FabricLoaderImpl.java:399)
	at com.chocohead.wim.Main.main(Main.java:20)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.chocohead.wim.Provider.launch(Provider.java:129)
	at net.fabricmc.loader.impl.launch.knot.Knot.launch(Knot.java:74)
	at net.fabricmc.loader.impl.launch.knot.KnotClient.main(KnotClient.java:23)
Caused by: java.lang.NullPointerException
	at org.spongepowered.asm.mixin.transformer.InnerClassGenerator.registerInnerClass(InnerClassGenerator.java:341)
	at org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.prepareInnerClasses(MixinPreProcessorStandard.java:209)
	at org.spongepowered.asm.mixin.transformer.MixinPreProcessorStandard.prepare(MixinPreProcessorStandard.java:178)
	... 29 more

This PR corrects this by avoiding resolving each target's ClassInfo every time a mixin is loaded, making the most of the targets having already been resolved when the mixin config was selected. It also avoids iterating the targets list at all when a mixin has no inner classes, given most mixins will not.

Chocohead avatar Dec 16 '24 20:12 Chocohead