[code-reflection] RFR: Lump constructor reference with method reference

Maurizio Cimadamore mcimadamore at openjdk.org
Wed Nov 12 18:50:00 UTC 2025


On Wed, 12 Nov 2025 14:18:03 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

> This PR merges constructor and method references together. The two share several commonalities -- they both have an owner type a name and a function type. The only distinction is that a constructor reference always has the special name `<init>` but that can be easily accommodated.
> 
> When merging, most of the effort went into the resolution routines. `MethodRef` provided two families of resolution methods:
> 
> 1. `resolveToDirectMethod`, `resolveToDirectHandle`
> 2. `resolveToMethod`, `resolveToHandle`
> 
> The methods in (1) seemed to look for a _declared_ method in the reference's owner type. E.g. for a reference like `A::m()`, the methods in (1) threw an exception if the resolved method/handle pointed to a method that was not in `A`.
> 
> The methods in (2) looked for any (accessible) matching method. So, in the above case, if the result of resolution was some `B::m()` that would be returned instead.
> 
> In other words, (1) is used when treating the method reference as a _declaration_, whereas (2) is used when treating the method reference as a use site, or call site.
> 
> Perhaps unsurprisingly, some of these combinations were never used: `resolveToDirectHandle` doesn't make much sense -- typically a method handle is needed to perform an invocation, in which case you probably want same semantics as a bytecode `invokeXYZ` instruction. On the other hand, `resolveToMethod` seemed to be used inside HAT (I'm in the process of investigating if this use was deliberate).
> 
> For these reasons I decided to only include the resolution methods that were actually used, and refine the naming scheme a little:
> 
> 1, `resolveToDeclaredMethod`, `resolveToDeclaredConstructor`
> 2. `resolveToHandle`
> 
> To keep the naming consistent, I also updated `FieldRef::resolveToMember` to `FieldRef::resolveToField`. Notably, `FieldRef` didn't provide "redundant" resolution methods.
> 
> I also tightened the impl of the methods in (1) so that they no longer require an `InvokeKind` parameter -- since these methods just look at declarations using core reflection, we don't need an invocation kind (which is needed when resolving to a method handle).
> 
> I also added javadoc to both `MethodRef` and `FieldRef`, to capture the indend semantics.
> 
> All copiler and JDK tests pass. All examples in `cr-examples` build and pass tests (I had to tweak the pom file for the triton example, as that seemed broken).

I've updated the PR so that the all resolution methods now use use-site resolution logic as well.
The primitive for resolution is the method handle/var handle resolution. For methods, we try static then instance InvokeKind, so that users don't have to pass in an extra parameter.

After thinking some more, I don't think the code in `TypeVariableType` requires more tweaks... at the end of the day, we attempt resolution, and see if the target method/constructor has the declared type variable, which is ok. We can make the logic tighter at a later point if we think it's preferrable.

-------------

PR Comment: https://git.openjdk.org/babylon/pull/677#issuecomment-3523418225


More information about the babylon-dev mailing list