Skip to content

Expose class passed to AtResolver to enclosing selector#2616

Closed
Bawnorton wants to merge 1 commit intominecraft-dev:devfrom
Bawnorton:dev
Closed

Expose class passed to AtResolver to enclosing selector#2616
Bawnorton wants to merge 1 commit intominecraft-dev:devfrom
Bawnorton:dev

Conversation

@Bawnorton
Copy link
Copy Markdown
Contributor

@Bawnorton Bawnorton commented Apr 30, 2026

My MixinSquared plugin needs a way of overriding what targets can appear in the @At such that the list of results doesn't include references to the target mixin itself (for example shadows). Consider the following mixin:

@Mixin(Target.class)
abstract class TargetMixin {
    @Shadow
    protected abstract String getName();

    @WrapOperation(
            method = "aMethod",
            at = @At(
                    value = "INVOKE",
                    target = "Ljava/io/PrintStream;println(Ljava/lang/String;)V"
            )
    )
    private void wrap(PrintStream instance, String x, Operation<Void> original) {
        String originalName = getName();
        original.call(instance, "wrapped " + originalName);
    }
}

a mixin targeting that injector will interpret getName as belonging to TargetMixin however, that's not the case as its a shadow member, the most straightforward way of mitigating this is transforming the target class passed to the AtResolver as if it were applied by mixin which would result in the correct targeting.

Thus, when using the m^2 plugin + mcdev targeting this mixin will result in:

    @TargetHandler(
            mixin = "com.bawnorton.sandbox.mixin.TargetMixin",
            name = "wrap"
    )
    @Inject(
            method = "@MixinSquared:Handler",
            at = @At(
                    value = "INVOKE",
                    target = "Lcom/bawnorton/sandbox/mixin/TargetMixin;getName()Ljava/lang/String;"
            )
    )

being valid and:

    @TargetHandler(
            mixin = "com.bawnorton.sandbox.mixin.TargetMixin",
            name = "wrap"
    )
    @Inject(
            method = "@MixinSquared:Handler",
            at = @At(
                    value = "INVOKE",
                    target = "Lcom/bawnorton/sandbox/Target;getName()Ljava/lang/String;"
            )
    )

being invalid. In reality the inverse is true.

Not certain about the exact best implementation, there didn't appear to be anything already exposed that allowed me to override this behaviour. I figured I'd open a PR before thinking on it some more so perhaps others can weigh in.

@Bawnorton Bawnorton marked this pull request as draft April 30, 2026 12:27
@Bawnorton Bawnorton changed the title Expose AtResolver to enclosing selector Expose class passed to AtResolver to enclosing selector Apr 30, 2026
@Bawnorton Bawnorton marked this pull request as ready for review April 30, 2026 15:13
@ryantheleach
Copy link
Copy Markdown

For those that are unaware (as I was) MixinSquared is a library that allows Mod A's mixins to target Mod B's mixins, and thus the example Mixin being given is NOT the injector, but the target itself.

The examples given by Bawnorton were moderately confusing me, until I made that connection.

@Bawnorton
Copy link
Copy Markdown
Contributor Author

Ah apologies, yeah sorry I should have clarified. I have made contributions before to expose various parts of the mixin target resolution pipeline here before so it didn't cross my mind to clarify.
The library is here https://github.com/Bawnorton/MixinSquared
The mcdev addon plugin is here https://plugins.jetbrains.com/plugin/26828-mixinsquared

@Earthcomputer
Copy link
Copy Markdown
Member

I'm confused, why isn't selector.getCustomOwner enough?

@Bawnorton
Copy link
Copy Markdown
Contributor Author

Bawnorton commented May 1, 2026

Because the selector here is the selector parsed from At#target rather than the selector from method

@Earthcomputer
Copy link
Copy Markdown
Member

So basically the fundamental problem is that the bytecode seen by mcdev is different from the bytecode eventually seen by MixinSquared? I wonder if it might be better to make those bytecodes match, like provide a way for the selector to optionally transform the bytecode of the method before it is further processed? I think that may fix all potential problems in one go.

@Bawnorton
Copy link
Copy Markdown
Contributor Author

So basically the fundamental problem is that the bytecode seen by mcdev is different from the bytecode eventually seen by MixinSquared?

Yes, that is the crux of the issue.

I wonder if it might be better to make those bytecodes match, like provide a way for the selector to optionally transform the bytecode of the method before it is further processed? I think that may fix all potential problems in one go.

That does sound like a more concrete solution, I'll see what I can come up with

@LlamaLad7
Copy link
Copy Markdown
Contributor

Yeah that'll be needed for the support to work properly when combined with eg expressions, casts that have been changed, etc

@Bawnorton
Copy link
Copy Markdown
Contributor Author

Makes sense, I'll close this and open a different PR w/ that approach

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants