[code-reflection] RFR: Add support for enclosing class types

Maurizio Cimadamore mcimadamore at openjdk.org
Thu May 30 14:32:40 UTC 2024


`ReflectMethod` can already handle references to inner classes. There is, however, an issue as the code model currently does not allow to represents inner class types. That is, inner classes are "flattened" into a single class type. As a result, only one parameterization can be specified (the one for the innermost type).

This means that if we have a class declaration like this:


class Outer<X> {
   class Inner<X> { }
}


We can represent types like `Outer.Inner` and `Outer.Inner<String>` (note that this is called a *rare type*, and is disallowed by the spec) but not types like `Outer<String>.Inner<Integer>`.

The solution is for `ClassType` to capture the enclosing type information. This solves not only the problem of parameterization of the enclosing class, but a more subtle problem: given a type like `Foo$Bar`, how to tell if this is an inner class with an enclosing `Foo`, or just a class with a weird name? The structural type info is impossible to reconstruct given only the binary name.

We now have a new `ExternalizedTypeElement`, whose identifier is `.` which is used to denote qualified types. That is, a type like `Outer<String>.Inner<Integer>` is expressed in the serialized form as follows:


.<Outer<java.lang.String>, Outer$Inner<java.lang.Integer>>


This Java type can be constructed as follows (note the new `JavaType::qualified` factory):


JavaType outer = parameterized(type(Outer.class), J_L_STRING);
JavaType inner = parameterized(qualified(outer, "Inner"), J_L_INTEGER);


The parser and factory code is relatively straightforward. The only subtle bit is that when we have an inner type in javac (or, equivalently, when parsing external type elements in the factory), we need to "infer" the inner class name given the flat names of the inner vs. outer types. This is done by removing the "enclosing part" from the inner type flat name.

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

Commit messages:
 - Fix whitespaces
 - Simplify test
 - Initial push

Changes: https://git.openjdk.org/babylon/pull/107/files
  Webrev: https://webrevs.openjdk.org/?repo=babylon&pr=107&range=00
  Stats: 216 lines in 10 files changed: 165 ins; 4 del; 47 mod
  Patch: https://git.openjdk.org/babylon/pull/107.diff
  Fetch: git fetch https://git.openjdk.org/babylon.git pull/107/head:pull/107

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


More information about the babylon-dev mailing list