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.

Reply via email to