[code-reflection] RFR: Move code reflection API into incubating module

Paul Sandoz psandoz at openjdk.org
Tue Nov 12 19:37:59 UTC 2024


On Thu, 7 Nov 2024 19:20:25 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

> This PR moves the code reflection API into a separate incubating module. In order to do that, Babylon compiler support (`ReflectMethods`) has morphed into a compiler plugin, which is optionally invoked when the user specifies the command line option `--add-modules jdk.incubator.module`.
> 
> #### Basic structure
> 
> The new module `jdk.incubator.module` has the following structure (starred packages are not exported):
> 
> 
> src/jdk.incubator.code/share/classes
> └── jdk
>     └── incubator
>         └── code
>             ├── analysis
>             ├── bytecode
>             ├── compiler (*)
>             ├── internal (*)
>             ├── interpreter
>             ├── op
>             ├── parser
>             │   └── impl (*)
>             ├── tools
>             │   ├── dot
>             │   └── renderer
>             ├── type
>             │   └── impl (*)
>             └── writer
> 
> 
> In other words, the new module subsumes the sources under `java.base/java.lang.reflect.code` and those under `jdk.code.tools`.
> 
> #### Compiler plugin
> 
> To decouple the `ReflectMethods` class from `jdk,compiler` we have moved `ReflectMethods` in a new compiler plugin in the new module (see `compiler` package). Compiler plugins are loaded using regular `ServiceLoader` infrastructure. However, here we have an issue: incubator modules are not resolved by default (unless `--add-modules` is used). This means that javac will not look inside `jdk.incubator.code` when finding its plugins.
> 
> To workaround this issue, javac will create a new module layer which points at `jdk.incubator.module` and then call `ServiceLoader::load` by passing that layer (see `BasicJavacTask`). This will force the javac plugin to be loaded, and no additional runtime warnings to be displayed when running javac.
> 
> Some additional tweaks were needed to avoid the creation of a module layer if the incubator module is not present (e.g. if we're using javac in "boostrap mode") or if we're running javac from an exploded build (in which case the incubator module is part of the module graph).
> 
> Note, the `@CodeReflection` annotation has been moved to `jdk.incubator.code`.
> 
> #### Symbol constants
> 
> All code reflection-related symbol constants have migrated from `Symtab` to the `CodeReflectionSymbols` in the new module. This is necessary because the symbols are now defined in a module other than `java.base` and javac `Symtab` cannot resolve references to symbols outside `java.base` early on (`Symtab` is one of the first classes to be initialized in the compiler).
> 
> After ...

Thank you for doing this tricky effort. Overall it looks very good and all but the first comment can be addressed later:
- The test `test/jdk/java/lang/reflect/Method/cr/TreeAccessTest.java` needs updating, but it really does not do anything that other tests already do. I suggest we just remove it.
- We can move the code reflection lang and JDK tests under more appropriate directories, and consolidate any code reflection tests in other areas.
- I am inclined to rethink the name/location of `Op.ofMethod`, in part because I think we should reconsider the design of `Quotable`. It could be a marker interface and we appeal to a reflection-based method to obtain the `Quoted` instance. We can work this out later. (Relatedly the compiler support for structural quoting when targeting lambda expressions to`Quoted` can be revisited to use a specific bootstrap.)

I will give it a quick test run locally.

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

PR Comment: https://git.openjdk.org/babylon/pull/273#issuecomment-2471400904


More information about the babylon-dev mailing list