[code-reflection] RFR: Regularize support for Java types/references [v5]
Maurizio Cimadamore
mcimadamore at openjdk.org
Fri May 23 10:28:01 UTC 2025
On Fri, 23 May 2025 10:24:10 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
>> This PR regularizes the support for Java types in the code model. There are two competing constraints to balance: on the one hand, the Java types should be readable from humans when inspecting the textual form of code model; on the other hand, we don't want to bake in Java-specific type parsing in the core code model API.
>>
>> Unfortunately, the current implementation scores poorly on both aspects, as (a) textual Java types can become very hard to read (e.g. `.<.<NewTest, NewTest$B>, NewTest$B$C>`), and (b) the parsing logic (defined in `DescParser`) contains several ad-hoc extensions that are only there to support Java types.
>>
>> To address this, this PR introduces two different kinds of externalized type forms: *inflated* type forms and *flattened* type forms. An inflated type form closely follow the structure of the `JavaType` or `JavaRef` it models. For instance, the Java type `Foo<? extends Bar>` is modelled as follows:
>>
>>
>> java.type.class(Foo, java.type.primitive(void),
>> java.type.wildcard(EXTENDS,
>> java.type.class(Bar, java.type.primitive(void))))
>>
>>
>> Inflated type forms can be *flattened* (using `JavaTypeUtils::flatten`), to derive a form that is more suitable for humans. For instance, the above inflated form is flattened as follows:
>>
>>
>> java.type:"Foo<? extends Bar>"
>>
>> Conversely, flattened type forms can be *inflated* back (using `JavaTypeUtils::inflate`) to their original inflated form.
>>
>> This distinction between inflated and flattened forms allow us to massively simplify `DescParser` -- which no longer has to worries about the syntactic vagaries of Java types. All that complexity is now pushed onto the flattened type forms support. The goal is to progressively make flattened Java type forms an "implementation detail" (more on that below).
>>
>> To accommodate flattened and inflated type forms, two changes are needed:
>> * in `OpWriter` we need to flatten an inflated type form (if possible) before writing it out as a string (this allows for the textual form of a code model to be more readable)
>> * in `OpParser` we need to inflate a flattened type form (if possible) before handing the type form back to the rest of the parsing machinery (which will e.g. invoke the type factory on such inflated type form)
>>
>> All Java types and references now follow this pattern:
>> 1. the `externalize` method returns an inflated type form
>> 2. the `toString` method returns a readable stri...
>
> Maurizio Cimadamore has updated the pull request incrementally with one additional commit since the last revision:
>
> Fix examples
cr-examples/triton/src/test/java/oracle/code/triton/TestAddKernel.java line 109:
> 107: @TritonCodeModel("""
> 108: module ()java.type:"void" -> {
> 109: tt.func @"add_kernel2_ptr<java.type.primitive<float>>_ptr<java.type.primitive<float>>_ptr<java.type.primitive<float>>_int_64_void" (%0 : ptr<java.type:"float">, %1 : ptr<java.type:"float">, %2 : ptr<java.type:"float">, %3 : java.type:"int")java.type:"void" -> {
Note (in this and other tests) -- the signature of the triton function contains the literal externalized type string of the various parameter/return types. These are NOT flattened strings because e.g. `Ptr::toString` does not flatten (nor it knows how to, if we were to use the public API). This leads to some asymmetry, where in some cases the inflated form appears in full (as here), while in other cases the short type string appears (e.g. because the type is a Java type, and its `toString` is more friendly).
I had half a mind to make `toString` of all triton types more friendly (e.g. not rely on externalize) -- but ultimately I decided to just stick with this very basic conversion -- perhaps we can come back to this later?
src/jdk.incubator.code/share/classes/jdk/incubator/code/type/CoreTypeFactory.java line 99:
> 97: case INFLATED_TYPE -> JavaTypeUtils.toJavaType(tree);
> 98: case INFLATED_REF -> JavaTypeUtils.toJavaRef(tree);
> 99: default -> throw new UnsupportedOperationException("Unsupported: " + tree);
I'm starting to think this should return `null`, as we used that as "composition" signal?
-------------
PR Review Comment: https://git.openjdk.org/babylon/pull/432#discussion_r2104295819
PR Review Comment: https://git.openjdk.org/babylon/pull/432#discussion_r2104297544
More information about the babylon-dev
mailing list