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

Paul Sandoz psandoz at openjdk.org
Wed Nov 12 19:13:46 UTC 2025


On Wed, 12 Nov 2025 18:49:58 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).
>
> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Update resolution logic to be use-site

src/jdk.incubator.code/share/classes/jdk/incubator/code/dialect/java/FieldRef.java line 74:

> 72:      * @throws ReflectiveOperationException if a resolution error occurs
> 73:      * @throws UnsupportedOperationException if this reference is not a constructor reference
> 74:      * @throws IllegalArgumentException if the provided {@code kind} is unsupported for this method reference

Not relevant for fields.

src/jdk.incubator.code/share/classes/jdk/incubator/code/dialect/java/impl/MethodRefImpl.java line 108:

> 106:         if (mh == null) {
> 107:             try {
> 108:                 mh = resolveToHandle(l, InvokeKind.STATIC);

Suggestion:

                mh = resolveToHandle(l, InvokeKind.INSTANCE);

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

PR Review Comment: https://git.openjdk.org/babylon/pull/677#discussion_r2519484052
PR Review Comment: https://git.openjdk.org/babylon/pull/677#discussion_r2519480745


More information about the babylon-dev mailing list