SpongePowered / Mixin

Mixin is a trait/mixin and bytecode weaving framework for Java using ASM
MIT License
1.42k stars 193 forks source link

Private Method Support in Interface Mixins #497

Open LambdAurora opened 3 years ago

LambdAurora commented 3 years ago

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:

Mumfrey commented 3 years ago

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.

LambdAurora commented 3 years ago

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.

jedlimlx commented 1 month ago

I've been trying to inject code into the lambda in this file, which is quite similar to the Oxidizable registry mentioned above.

My Mixin code is below.

@Mixin(value = Mossable.class, remap = false)
public interface MossableMixin {
    @Inject(
        method = "lambda$static$0",
        at = @At(
            value = "INVOKE",
            target="com/ordana/immersive_weathering/IWPlatformStuff.addExtraMossyBlocks (Lcom/google/common/collect/ImmutableBiMap$Builder;)V"
        ), locals = LocalCapture.CAPTURE_FAILSOFT, remap = false
    )
    private static void lambda$static$0(
        CallbackInfoReturnable<BiMap<Block, Block>> cir,
        ImmutableBiMap.Builder<Block, Block> builder
    ) {
        WeatheringHelper.addOptional(builder, "twigs:cobblestone_bricks", "twigs:mossy_cobblestone_bricks");
    }
}

On running this code, I get the following error adjustments.mixins.json:MossableMixin: Interface mixin contains a non-public method! Found lambda$static$0(Lorg/spongepowered/asm/mixin/injection/callback/CallbackInfoReturnable;Lcom/google/common/collect/ImmutableBiMap$Builder;)V in adjustments.mixins.json:MossableMixin.

The mixin version I'm using is 0.8.7 on Forge 1.20.1. My compatibility level is Java 17.

Someone on the Discord mentioned that this might be a bug, so I decided to put this here.