therapi-runtime-javadoc icon indicating copy to clipboard operation
therapi-runtime-javadoc copied to clipboard

Enhanced support for record classes

Open dnault opened this issue 3 years ago • 3 comments

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 GENERATED or RECORD flags set on the method (which I think is specified, but I can't find the exact mention in the JVM spec)
  • @param tags from the primary constructor could be applied to the fields and/or methods

dnault avatar Jan 02 '22 00:01 dnault

@xeals Do you have any more hints about how to identify the canonical constructor? I couldn't sniff out the flags you mentioned.

dnault avatar Jan 02 '22 00:01 dnault

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 through long Symbol.flags()
  • the canonical constructor of a record (a com.sun.tools.javac.code.Symbol.MethodSymbol) appears to be tagged with com.sun.tools.Flags.RECORD (1 << 61) and com.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 instanceof check)

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.

xeals avatar Jan 04 '22 05:01 xeals

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).

dnault avatar Jan 04 '22 21:01 dnault