[code-reflection] RFR: JavaRef extends TypeElement

Maurizio Cimadamore mcimadamore at openjdk.org
Wed Apr 30 09:06:55 UTC 2025


On Wed, 30 Apr 2025 08:56:40 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Each implementation of `JavaRef` supports an external form, using the sigil prefix `&` to indicate a reference of some kind.
>> 
>> The externalized form of `TypeVarRef` is changed to be uniformly structured. This required update to the code model text of a few tests. Arguably we are taking a step back in terms of readability, but we can address that later - it was easier to update a few tests rather than preserve the existing encoding in a few places.
>> 
>> We still rely on the bespoke string form for java refs, which is used as the value of an externalized attribute. Ideally such attribute values are either instances of `JavaRef` or `ExternalizedTypeElement` to be transformed into the appropriate `JavaRef`. We can address that later to further separate out parsing.
>> 
>> I believe we have what we need to further enhance the code model builder to not rely on bespoke parsing logic of types and refs. We can either construct `ExternalizedTypeElement` tree instances explicitly or parse from a very simple grammar. If we are careful i believe we can share the results of nested type elements if reused e.g. as in `List<Double>` and `Set<Double>`.
>> 
>> More generally it now means we can generate a simple s-expression-like tree for the whole code model, e.g., a string where the `(` and `)` characters represent tree structure and say `L` represents a leaf node, and a list of leaf node values in topological order.
>> 
>> --
>> 
>> Below is the type grammar, which i believe is consistent with what we have implemented.
>> 
>> # Type element grammar
>> 
>> ## General structure
>> 
>> 
>> identifier
>>   string
>> 
>> name
>>   identifier
>> 
>> sigil
>>   # | . | & | + | - | [
>> 
>> type
>>   sigil
>>   identifier
>>   sigil identifier
>>   identifier < types >
>>   sigil identifier < types >
>> 
>> types
>>    type
>>    type , types
>> 
>> 
>> ## Core types
>> 
>> 
>> varType
>>   "var" < type >
>> 
>> tupleType
>>   "tuple"
>>   "tuple" < types >
>> 
>> funcType
>>   "func" < types >
>> 
>> 
>> # Java types
>> 
>> 
>> javaType
>>   primitiveType | classType | wildCardType | arrayType | typeVariableType
>> 
>> javaType-no-wildCardType
>>   primitiveType | classType | arrayType | typeVariableType
>> 
>> primitiveType
>>   boolean | byte | ... | void
>> 
>> classType
>>   name
>>   name < paramTypes >
>>   . < enclosingType , innerType >
>> paramTypes
>>   javaType
>>   javaType , javaTypes
>> enclosingType
>>   classType
>> innerType
>>   classType
>> 
>> wildcardType
>>   + < wildcardTypeBound >
>>   - < wildcardTypeBound >
>> wildcardTypeB...
>
> test/jdk/java/lang/reflect/code/type/TestReferences.java line 52:
> 
>> 50:                 {"java.io.PrintStream::println(java.lang.String)void", "java.io.PrintStream", "println"},
>> 51:                 {"MethodReferenceTest$A::m(java.lang.Object)java.lang.Object", "MethodReferenceTest$A", "m"},
>> 52:                 {"R<#T<R, java.lang.Number>>::n()#T<R, java.lang.Number>", "R<#T<R, java.lang.Number>>", "n"}
> 
> Parsing of MethodRef should eventually disappear, right? E.g. one thing is parsing the externalized method ref -- (which can be done in a principled way) but parsing a MethodRef using a slightly different externalized string (like in this test) seems confusing. (Same for all JavaRefs, really)

Ok, this is covered by your `We still rely on the bespoke string form for java refs, which is used as the value of an externalized attribute` comment. And also explains why there are only so few changes in tests (I was expecting anything using invoke, or field load to need a refresh :-) ).

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

PR Review Comment: https://git.openjdk.org/babylon/pull/416#discussion_r2068215031


More information about the babylon-dev mailing list