therapi-runtime-javadoc
therapi-runtime-javadoc copied to clipboard
Enhanced support for record classes
Implement the features suggested by @xeals in #52:
- The class docs could be re-applied to the primary constructor, which can be determined by the
GENERATEDorRECORDflags set on the method (which I think is specified, but I can't find the exact mention in the JVM spec) @paramtags from the primary constructor could be applied to the fields and/or methods
@xeals Do you have any more hints about how to identify the canonical constructor? I couldn't sniff out the flags you mentioned.
I'd not recorded the info when I was playing around (of course), but I rediscovered what I was talking about.
Unfortunately this was found through a debugger and I didn't realise it exposes javac internals, which in JDK16+ are a little harder to access than they used to be (doable, just requiring opt-in flags).
With that in mind:
- the annotation processor gets given instances of
com.sun.tools.javac.code.Symbol, which are annotated with compile-time flags accessible throughlong Symbol.flags() - the canonical constructor of a record (a
com.sun.tools.javac.code.Symbol.MethodSymbol) appears to be tagged withcom.sun.tools.Flags.RECORD(1 << 61) andcom.sun.tools.Flags.COMPACT_RECORD_CONSTRUCTOR(1 << 51) - other constructors only get the regular visibility flags
- these can be all checked when checking enclosed elements of the record declaration in the annotation processor (I think requiring an
instanceofcheck)
It doesn't look like any of this is transferred to a properly public API, so deciding to opt into those private APIs might be a bigger decision than just adding support. Looking at it again I would be hesitant.
Thanks for digging into this again, Alex. I agree we should stick to the public API.
I wonder if we could infer the signature of the canonical constructor by paying attention to the ElementKind.RECORD_COMPONENT elements. Kind of like https://stackoverflow.com/a/67126110/611819 . For example, if we see an int and a String, then we know the the canonical constructor has a signature of (int, String).