square / javapoet

A Java API for generating .java source files.
Apache License 2.0
10.83k stars 1.38k forks source link

Fix boxing and unboxing of annotated primitives #986

Closed invliD closed 1 year ago

invliD commented 1 year ago

TypeName#box currently relies on identity comparisons between this and one of the primitive TypeName constants. However, it is possible to have an instance of a primitive that isn't any of those constants by calling TypeName#annotated or TypeName#withoutAnnotations. The returned TypeName instance can no longer be boxed.

TypeName#unbox and TypeName#isBoxedPrimitive have a similar issue. this is compared using equals instead of identity, but annotations are part of the compared string, so a boxed primitive with annotations is not found to be any of the existing constants. Annotated boxed TypeName instances can no longer be unboxed.

This PR changes behavior of all 3 methods to do a more appropriate comparison when trying to find the (un)boxed version of this. After (un)boxing, the annotations from this are copied onto the returned value. That way, boxing and unboxing works on both unannotated and annotated TypeNames, preserving any annotations. When no annotations are present, identity is preserved. I added unit tests to test both boxing and unboxing. Those tests fail without the code changes in TypeName.

invliD commented 1 year ago

@JakeWharton Would you be able to take a look at this?