RFR: JDK15-8236210: javac generates wrong annotation for fields generated from record components
Vicente Romero
vicente.romero at oracle.com
Fri Jan 17 12:53:18 UTC 2020
Hi Maurizio,
Thanks for the review, some comments below
On 1/17/20 6:27 AM, Maurizio Cimadamore wrote:
> Tricky indeed. Few suggestions:
>
> * It seems like SymbolMetadata::remove has morphed more into a
> removeDeclarationMetadata (since you no longer remove type annos from
> there)
true
>
> * Another way to simplify the code and avoid the 'ignoreTypeUse'
> trick, would be for "annotationApplicable" to give you the list of all
> the applicable targets, rather than just a boolean. Then, from there,
> I think you can implement the rest of your logic w/o the need of
> rechecking for applicability multiple times.
right that could work, will give it a try
>
> * The test seems good, but it only checks for one side of the story:
> classfile generation; should we also test that the annotations are
> indeed available to processors?
we have already tests for that but they live in another neighborhood, see:
test/langtools/tools/javac/processing/model/element/CheckingTypeAnnotationsOnRecords.java
test/langtools/tools/javac/processing/model/element/AnnoProcessorOnRecordsTest.java
we can eventually move them to RecordCompilationTests in a separate effort
>
> Cheers
> Maurizio
Vicente
>
> On 16/01/2020 21:24, Vicente Romero wrote:
>> Please review the fix for [1] at [2]. Some background:
>>
>> Annotations applied to record components are propagated to the
>> corresponding record member so if an annotation has target: FIELD, it
>> is propagated to the corresponding FIELD, if it has target METHOD, it
>> is propagated to the accessor and so on. But at the moment when
>> method members are generated there is no enough information to
>> propagate only the right annotations. So all the annotations are
>> propagated to all the possible locations.
>>
>> So there is a point when we need to remove all the annotations that
>> are not in place before going on with the annotation party. On top of
>> the above there is the issue that there is no AST representing record
>> components, just symbols so the corresponding field has been holding
>> all the annotations and it's metadata has been modified as if it was
>> both a field and a record component.
>>
>> So there are two places where we need to trim annotations from: the
>> metadata of the symbol and / or the modifiers in the AST. Whatever is
>> in the metadata will be written to the class file, whatever is in the
>> modifiers could be see by annotation processors.
>>
>> The metadata contains both type annotations and declaration
>> annotations. Type annotations are all in the right place as they are
>> applicable to all the types of the corresponding record members
>> generated by the compiler. But we could need to remove declaration
>> annotations. So for declaration annotations if they are not
>> applicable to the given record member it will be needed to remove
>> them. For the AST modifiers if the annotation is not applicable
>> either as type annotation and or declaration annotation, only in the
>> last case it will be removed.
>>
>> So it could be that an annotation is removed as a declaration
>> annotation but it is kept in the AST modifier for further inspection
>> by annotation processors.
>>
>> For example:
>>
>> import java.lang.annotation.*;
>>
>> @Target({ElementType.TYPE_USE, ElementType.RECORD_COMPONENT})
>> @Retention(RetentionPolicy.RUNTIME)
>> @interface Anno { }
>>
>> record R(@Anno String s) {}
>>
>> just before Enter ends we will have for the case of the generated field:
>> - @Anno in the modifier
>> - @Anno as a type annotation
>> - @Anno as a declaration annotation
>>
>> the last one should be removed because the annotation has not FIELD
>> as target but it was applied as a declaration annotation because the
>> field was being treated both as a field and as a record component.
>> Once we reach the point when the corresponding annotations have been
>> copied to the record component, the field doesn't need to hold
>> annotations that are not intended for it anymore. Still @Anno has to
>> be kept in the AST's modifiers as it is applicable as a type
>> annotation to the type of the field.
>>
>> Thanks,
>> Vicente
>>
>> [1] https://bugs.openjdk.java.net/browse/JDK-8236210
>> [2] http://cr.openjdk.java.net/~vromero/8236210/webrev.00/
>>
More information about the compiler-dev
mailing list