Make @Generated optional on generated classes
Hi!
The @Generated annotation causes some troubles with JPMS.
History on @Generated
Originally, it was designed to show static code analyzers which classes to ignore. Nowadays, they will usually look for .gitignored files or something line target/generated-* or any @*Generated annotation. So that's that.
Why it is a problem with JPMS
I do not want code which uses my record builders to require the java.compiler module -- it is not needed, because none of that code would read the @Generated annotation. So, instead of using requires java.compiler;, the correct approach is requires static java.compiler -- which translates to "only use this module for compiling".
However, the compiler is a bit dumb, sees the @Generated annotation and complains that it will be there on the .class file -- which it will be not, because it does not know about annotations and their @RetentionPolicy, so it assumes it will be there.
This will yield the following compiler warning:
[WARNING] /path/to/my/target/generated-sources/annotations/MyRecordBuilder.java:[217,6] class javax.annotation.processing.Generated in module java.compiler is not indirectly exported using 'requires transitive'
Alternatives
1.: Do not generate @Generated at all
An option with all its drawbacks
2.: Only add @Generated if it is in the classpath
mapstruct uses this approach
3.: let the user decide (boolean)
Booleans are meh. Use an enum.
4. let the user decide (enum)
-AgeneratedAnnotation = enum AddGeneratedAnnotation { ON, OFF, USER_SUPPLIED, IF_ON_CLASSPATH }
Default: IF_ON_CLASSPATH
When USER_SUPPLIED is set, the user would also need to specify -AgeneratedUserAnnotation=com.my.project.MyProjectGenerated or so.
names are not meant to be final. Let some native speaker pick something better :)
Given the existence of addClassRetainedGenerated a new boolean will be easier to add.
Given the existence of
addClassRetainedGenerateda new boolean will be easier to add.
IIRC, this is only an ADDITIONAL annotation, no?
If so, I would treat them as unrelated. In fact, I would add -AaddClassRetainedGenerated=true after disabling @Generated because of the reason stated below.
/**
* If true, generated classes are annotated with {@code RecordBuilderGenerated} which has a retention policy of
* {@code CLASS}. This ensures that analyzers such as Jacoco will ignore the generated class.
*/
boolean addClassRetainedGenerated() default false;
So, I would still vote for an enum, but ultimately, the choice is yours.
@Randgalt you can review my draft PR. If that is okay for you, I will continue with the Interface Processor.