Mixin
Mixin copied to clipboard
Private Method Support in Interface Mixins
Mixin and interfaces is a long story of friendship.
Let's take it from the start and talk about the Oxidizable interface in Minecraft 1.17, all names here are from the yarn mappings.
All oxidation level increases are done with a supplier of a bimap of blocks, and the level decreases one is simply the inversion of the first.
It looks like that
Supplier<BiMap<Block, Block>> OXIDATION_LEVEL_INCREASES = Suppliers.memoize(() -> { return /* an immutable bi map builder here */; });
For any mods which wants to add blocks in this map will find a wall, a big one.
Let's take a look at Java 8 first and the issues:
- a setter accessor is impossible due to the fact that it would try to remove the
finaland the JVM won't like that at all. - an injector to the lambda is impossible due to the fact that:
- mixin will refuse anything that isn't an interface to mixin an interface
- mixin will refuse to use a
public staticinjector (required by interfaces in Java 8)
- any other injection-like will fail due to the same issues.
With the recent upgrade to Java 16 we now have access to private methods in interfaces, and I guessed I could finally ditch the ugly raw-asm transformation, but yet it's still impossible due to the fact that mixin yells tesla_coil.mixins.json:OxidizableMixin: Interface mixin contains a non-public method! Found onBuildLevelIncreasesMap(Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfoReturnable;)V in tesla_coil.mixins.json:OxidizableMixin
So, I cannot use a class mixin, I cannot use a public static injector, nor a private static injector.
(note: even though Java 16 is not yet officially supported, the issue still exist if using Java 11 as the private methods in interfaces are in Java since Java 9)
To conclude, mixin is way too aggressive in its checks globally which impedes its capacities.
To conclude, mixin is way too aggressive in its checks globally which impedes its capacities.
It's not "too aggressive", this is by design, so it's exactly as aggressive as it was intended to be. Changes are coming in 0.9 which address this and other issues which affect manipulation of interfaces and default methods.
It's not "too aggressive", this is by design, so it's exactly as aggressive as it was intended to be.
I don't reject the fact that it's by design, I badly worded that part, but my point is some checks can end up more frustrating than it should for a mixin user. At least I'm happy to see that work is being done to improve manipulation of interfaces.