[code-reflection] RFR: Cleanup JavaType factories

Maurizio Cimadamore mcimadamore at openjdk.org
Thu May 2 17:38:09 UTC 2024


On Thu, 2 May 2024 13:12:56 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

> This PR is a biggie cleanup of the various `JavaType` classes.
> 
> Perhaps the biggest contribution of this PR is to cleanup the factories in `JavaType`. The new factories are as follows:
> * a factory to create a type from a `ClassDesc`
> * a factory to create a type from a `j.l.r.Type`
> * a couple of factories for creating parameterized types, which work on `JavaType` instances
> * a couple of factories for array types
> * a couple of factories for wildcard types
> * a factory for type variables
> 
> This resolves the non-orthogonality found in the current set of factories, where one can take a `JavaType` and can, simultaneously, parameterize it, and turn it into an array type. Now the factories for these two operations are distinct.
> 
> The new factories also clarify the relationship between `JavaType`, `ClassDesc` and `j.l.Type` - that is:
> 
> * a type can be built from a nominal descriptor, using `type(ClassDesc)`
> * a type can turned into a nominal descriptor, using `toNominalDescriptor()`
> * a type can be built from a reflective type mirror, using `type(Type)`
> * a type can turned into a nominal descriptor, using `resolve(Lookup)`
> 
> These operations are symmetric - that is, you can start from a reflective type mirror, build a `JavaType` form it, then resolve that into a `Type` and check that you get back where you started. I've enhanced `JavaTypeTest` to check round trip for both `ClassDesc` and `Type`.
> 
> Note that the `JavaType` can be associated with complex reflective mirrors, e.g. beyond just `Class<?>`. For this reason, existing uses of `JavaType::resolve` in `BytecodeGenerator` and `Interpreter` which were expecting to obtain a `Class` from a `resolve` call have been rewritten to use the idiom `type.erasure().resolve(...)`.
> 
> As part of this PR I've also added javadoc for all the methods/fields under the `JavaType` hierarchy that did not have one, and expanded existing docs.
> 
> I've added several tests to make sure that all the conversions work as expected, and I have verified the examples (by opening their files in the IDE and make sure there's no error, I did not build).

src/java.base/share/classes/sun/reflect/generics/reflectiveObjects/WildcardTypeImpl.java line 86:

> 84:      * @return a wild card type with the requested bounds
> 85:      */
> 86:     public static WildcardTypeImpl make(Type[] ubs,

I had to tweak this class: in our case we already know the type for the wildcard bounds, so we don't need to "resolve" them. The reflective code wants to push the bound parsing as lazily as possible, but this generality is not needed for us. Note that the existing code was already flexible enough to handle both the eager and the lazy case (e.g. lazy bounds are turned dynamically into proper bounds on first access), so the only thing left to do was to define an internal factory for the non-parsing flavor.

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

PR Review Comment: https://git.openjdk.org/babylon/pull/71#discussion_r1588030594


More information about the babylon-dev mailing list