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

Maurizio Cimadamore mcimadamore at openjdk.org
Wed Nov 12 15:31:44 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'm not too sure if having the `declared` variant makes sense... the uses in HAT seems to reflect this pattern:


var method = invokeOp.invokeDescriptor().resolveToMethod(lookup, invokeOp.invokeKind());
CoreOp.FuncOp f = Op.ofMethod(method).orElse(null);


It seems sensible for this code to work _regardless_ of whether the resolved method is declared  in `refType` or not.

Perhaps, the right thing to do would be to always use `MH::lookup`-like resolution semantics (for both `MethodRef` and `FieldRef`, and regardless of what the resolution output is a reflective class or not).

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

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


More information about the babylon-dev mailing list