Skip to content

Feature/method signature intersection - #2647

Open
LlamaLad7 wants to merge 50 commits into
minecraft-dev:devfrom
LlamaLad7:feature/method-signature-intersection
Open

LlamaLad7 wants to merge 50 commits into
minecraft-dev:devfrom
LlamaLad7:feature/method-signature-intersection

Conversation

@LlamaLad7

@LlamaLad7 LlamaLad7 commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Overhauls InvalidInjectorMethodSignatureInspection and related infrastructure. Apologies for this not being broken up into digestible commits, there were simply too many interleaved changes.

I appreciate that this will be tricky to review, the complex logic is documented where I felt it was needed and lots of new tests are provided.

The general changes are

  • Injectors are now split into those that work with instructions and those that don't (@WrapMethod)
  • Injectors now usually declare their expected signatures in one of several structured formats, rather than the group system as before
  • Suggested method signatures are computed by intersecting the expected signatures from every target instruction/method. This is made possible by the structured formats, with separate intersection logic for each required format that makes use of format-specific knowledge. Attempts are made to produce signatures that are most useful, for example by avoiding @Coerce where possible and prioritising the most specific supertype when it is not possible. Additionally, ModifyVariable and ModifyArg suggestions prioritise the handler's existing return type where available.
  • In the special case where the handler's existing parameters are valid for every target but the return type is not, an attempt is made to suggest a new return type without requiring parameter changes. The logic here is very complex since it works for any type of expected signature. Nonetheless it has good complexities, and will always produce a result if one exists, though this result may not be globally optimal (whatever that even means).
  • Several bugfixes to related injector logic, including incorrect Coerce handling, ModifyConstant not supporting .class literals, Inject allowing captured locals without the target method's parameters, WrapMethod not requiring exact staticness
  • The mixin parameter name inspection is reworked to be more sensible. For example if 2 signatures contribute a name each for a parameter, we shouldn't expect the parameter to match either of those names, because it represents them both and will likely be named as such

- ParameterGroups are gone, with every signature now effectively containing a required leading group and an optional vararg trailing group. The prior flexibility made working them easy to get wrong, for example in the matching logic which would have been incorrect for leading vararg groups.
- Inject previously contained 2 optional groups (the target's params and the captured locals) but this was in fact incorrect, since the captured params are required if we want to capture any locals, so it is now (better) represented as 2 separate signature options.
- The distinction between `WARN_IF_ABSENT` and `ERROR_IF_ABSENT` is entirely removed. It was effectively unused since it only applied to captured Inject locals, which are varargs and therefore never "absent" (a separate inspection handles unused LocalCapture).
- ModifyArgs is in fact all-or-nothing wrt capturing the target parameters, and this is now reflected.
Not sure why these are there, Mixin doesn't allow them.
It does not work and cannot ever work.
…s specified, and supporting wildcard matches

This branch has not been deployed

No deployments
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.

1 participant