[code-reflection] RFR: Refactor JavaType

Maurizio Cimadamore mcimadamore at openjdk.org
Mon Apr 8 16:45:29 UTC 2024


This PR breaks up the monolithic JavaType interface into 3 classes:

* ClassType - used to model class types (e.g. `String`, `List<Integer>`)
* PrimitiveType - used to model primitive types (`int` and friends) - this one is package-private
* ArrayType - used to model array types (`int[]`, `List<Integer>[][]`)

I have retained `JavaType` at the top of the hierarchy - and then added three sealed subclasses.

While we discussed (offline) about the possibility of having a toplevel array type that was not a `JavaType`, I quickly realized that doing so would have required far deeper changes. For instance, the factory for creating a parameterized type takes a bunch of `JavaType` as type arguments, but if we want to model a type such as `List<int[]>`, then the mismatch `TypeElement` vs. `JavaType` becomes annoying (this was quite visible when tweaking the javac code). For this reason, I left `ArrayType` under the `JavaType` umbrella, for now.

I'm still not 100% happy about the way in which types are constructed. We now have the following factories in `JavaType`:

* `type(Class<?>)` - create a class type w/o type parameters
* `type(Class<?>, Class<?>[])`/`type(Class<?>, List<Class<?>>)` - create a class type w/ type parameters
* `type(JavaType, JavaType[])`/`type(JavaType, List<JavaType>)` - create a class type w/ type parameters
* `array(JavaType)` - create an array type with given component type (and dimension = 1)
* `array(JavaType, int)` - create an array type with given component type and dimension
* `ofNominalDescriptor(ClassDesc)` - create a `JavaType` from a symbolic desc
* `ofNominalDescriptorString(String)` - create a `JavaType` from a descriptor string
* `ofString(String)` - create a `JavaType` from a (model) string
* for primitive types, there are static constants in `JavaType` (e.g. `JavaType::INT`)


When rewriting the existing code to use the correct factories, I have to admit that I got myself confused several times, and ended up e.g. using `ofNominalDescriptor` in places where `ofString` was required.

My feeling is that we would be better off with something like this:

* have a way to create a `JavaType` from a `Class<?>`/`ClassDesc`/descriptor string
* have a single factory to create parameterized types (expressed in terms of `JavaType`)
* keep existing array factories, but perhaps investigate if we can get rid of the "flat" array factory that takes the dimensions (I don't see many uses for it)

Depending on feedback, I can try to add more changes to this PR, or I can address further refactorings in subsequent PRs.

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

Commit messages:
 - Revert changes to bytecode generator
 - Fix test issues
 - Fix issue with VOID parsing
 - Refactor JavaType hierarchy - initial push

Changes: https://git.openjdk.org/babylon/pull/46/files
  Webrev: https://webrevs.openjdk.org/?repo=babylon&pr=46&range=00
  Stats: 852 lines in 16 files changed: 490 ins; 286 del; 76 mod
  Patch: https://git.openjdk.org/babylon/pull/46.diff
  Fetch: git fetch https://git.openjdk.org/babylon.git pull/46/head:pull/46

PR: https://git.openjdk.org/babylon/pull/46


More information about the babylon-dev mailing list