Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private Method Support in Interface Mixins #497

Open
LambdAurora opened this issue May 17, 2021 · 3 comments
Open

Private Method Support in Interface Mixins #497

LambdAurora opened this issue May 17, 2021 · 3 comments

Comments

@LambdAurora
Copy link

LambdAurora commented May 17, 2021

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 final and 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 static injector (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.

@Mumfrey
Copy link
Member

Mumfrey commented May 17, 2021

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.

@Mumfrey Mumfrey changed the title Mixin doesn't allow mixin interface to hold private method. Private Method Support in Interface Mixins May 17, 2021
@LambdAurora
Copy link
Author

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.

Leawind added a commit to Leawind/Third-Person that referenced this issue Dec 27, 2023
forge version can not launch due to a bug of the dependency.

SpongePowered/Mixin#497
FabricMC/Mixin#54
Leawind added a commit to Leawind/Third-Person that referenced this issue Dec 31, 2023
forge version can not launch due to a bug of the dependency.

SpongePowered/Mixin#497
FabricMC/Mixin#54
Leawind added a commit to Leawind/Third-Person that referenced this issue Dec 31, 2023
forge version can not launch due to a bug of the dependency.

SpongePowered/Mixin#497
FabricMC/Mixin#54
Leawind added a commit to Leawind/Third-Person that referenced this issue Dec 31, 2023
forge version can not launch due to a bug of the dependency.

SpongePowered/Mixin#497
FabricMC/Mixin#54
Leawind added a commit to Leawind/Third-Person that referenced this issue Dec 31, 2023
forge version can not launch due to a bug of the dependency.

SpongePowered/Mixin#497
FabricMC/Mixin#54
@jedlimlx
Copy link

jedlimlx commented Oct 5, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants