The jl.constant API will have to be updated somewhat for Valhalla.
Since it was already on the drawing board when we designed jl.constant,
shouldn't be too bad, but there are a few subtleties. Now that the
descriptors are largely settling down, we can take a stab at this.
ClassDesc (the base abstraction) has several factories to get a CD from
a String:
of(String qualifiedName)
of(String packageName, unqualifiedClassName)
ofDescriptor(String fieldDescriptor)
Obviously we can already represent extended primitives with the last of
these, but doing nothing else would make them somewhat second-class.
For reference, we also have combinators:
nested(String unqualifiedNestedName): give me a ClassDesc for a
class nested in this one
arrayType(): give me a ClassDesc for the array with this component type
componentType(): (partial) give me a ClassDesc for the component
type of this one, assuming this one is an array type
With the addition of Q descriptors, this library reveals itself to be
L-biased; ClassDesc.of("com.foo.Bar") gives us an L-Bar. ("You could
look in the classfile", I hear some of you say. Not so fast; this is a
symbolic API, not a reflective one, by design.) But this is OK; L is a
reasonable default.
The fully orthogonal version would involve adding:
static ClassDesc ofValue(qualifiedName)
static ClassDesc ofValue(String packageName, unqualifiedClassName)
boolean isValue()
ClassDesc valueType() // flip to Q
ClassDesc refType() // flip to L
But the first two are not really necessary, since they can be expressed
both with ClassDesc.of(name).valueType(), or with
ClassDesc.ofDescriptor(desc), and I'm inclined to go that route -- the
canonical constructor is ofDescriptor, the others are conveniences
around that, and complex transforms are done by combinators.
Separately, over in bytecode-API land, we have identified a desire for
another overload of ClassDesc::of, which is one that takes an internal
(slash-separated) name.
One of the horrors of classfile APIs is that the classfile format is
woefully inconsistent about names. Sometimes it wants an internal
binary name (foo/Bar), sometimes a descriptor (Lfoo/Bar;), and there are
other exceptions (e.g., module and package names use dots, operand to
`new` is sometimes an internal binary name, but a descriptor for
arrays.) So accepting any sort of String immediately raises the
question: "in what format?" A more strongly typed API would use
ClassDesc in some places, but given that we might have an internal
binary name, or external binary name, or descriptor in hand, we need a
way to convert all of these to a ClassDesc. For the external binary
name and descriptor, we have ClassDesc::of and ::ofDescriptor, but we're
missing one for internal binary names. So I'm proposing:
ClassDesc ofInternal(String internalBinaryName)
to round out the set.
So, summarizing the new methods (modulo naming changes to reflect
changes in Valhalla language syntax):
ClassDesc ofInternal(String internalBinaryName)
boolean isValue()
ClassDesc valueType()
ClassDesc refType()
Also, eventually, all the *Impl classes in this library can become B2
primitives, since identity doesn't matter.