@@ -963,9 +963,39 @@ protected void runPhase(Env<AttrContext> env) {
963963 ClassSymbol sym = tree .sym ;
964964 if ((sym .flags_field & RECORD ) != 0 ) {
965965 List <JCVariableDecl > fields = TreeInfo .recordFields (tree );
966- memberEnter . memberEnter ( fields , env );
966+
967967 for (JCVariableDecl field : fields ) {
968- sym .createRecordComponent (field ,
968+ /** Some notes regarding the code below. Annotations applied to elements of a record header are propagated
969+ * to other elements which, when applicable, not explicitly declared by the user: the canonical constructor,
970+ * accessors, fields and record components. Of all these the only ones that can't be explicitly declared are
971+ * the fields and the record components.
972+ *
973+ * Now given that annotations are propagated to all possible targets regardless of applicability,
974+ * annotations not applicable to a given element should be removed. See Check::validateAnnotation. Once
975+ * annotations are removed we could lose the whole picture, that's why original annotations are stored in
976+ * the record component, see RecordComponent::originalAnnos, but there is no real AST representing a record
977+ * component so if there is an annotation processing round it could be that we need to reenter a record for
978+ * which we need to re-attribute its annotations. This is why one of the things the code below is doing is
979+ * copying the original annotations from the record component to the corresponding field, again this applies
980+ * only if APs are present.
981+ *
982+ * First, we find the record component by comparing its name and position with current field,
983+ * if any, and we mark it. Then we copy the annotations to the field so that annotations applicable only to the record component
984+ * can be attributed, as if declared in the field, and then stored in the metadata associated to the record
985+ * component. The invariance we need to keep here is that record components must be scheduled for
986+ * annotation only once during this process.
987+ */
988+ RecordComponent rc = sym .findRecordComponentToRemove (field );
989+
990+ if (rc != null && (rc .getOriginalAnnos ().length () != field .mods .annotations .length ())) {
991+ TreeCopier <JCTree > tc = new TreeCopier <>(make .at (field .pos ));
992+ List <JCAnnotation > originalAnnos = tc .copy (rc .getOriginalAnnos ());
993+ field .mods .annotations = originalAnnos ;
994+ }
995+
996+ memberEnter .memberEnter (field , env );
997+
998+ sym .createRecordComponent (rc , field ,
969999 field .mods .annotations .isEmpty () ?
9701000 List .nil () :
9711001 new TreeCopier <JCTree >(make .at (field .pos )).copy (field .mods .annotations ));
@@ -1211,37 +1241,10 @@ private void addRecordMembersIfNeeded(JCClassDecl tree, Env<AttrContext> env) {
12111241 memberEnter .memberEnter (equals , env );
12121242 }
12131243
1214- /** Some notes regarding the code below. Annotations applied to elements of a record header are propagated
1215- * to other elements which, when applicable, not explicitly declared by the user: the canonical constructor,
1216- * accessors, fields and record components. Of all these the only ones that can't be explicitly declared are
1217- * the fields and the record components.
1218- *
1219- * Now given that annotations are propagated to all possible targets regardless of applicability,
1220- * annotations not applicable to a given element should be removed. See Check::validateAnnotation. Once
1221- * annotations are removed we could lose the whole picture, that's why original annotations are stored in
1222- * the record component, see RecordComponent::originalAnnos, but there is no real AST representing a record
1223- * component so if there is an annotation processing round it could be that we need to reenter a record for
1224- * which we need to re-attribute its annotations. This is why one of the things the code below is doing is
1225- * copying the original annotations from the record component to the corresponding field, again this applies
1226- * only if APs are present.
1227- *
1228- * We need to copy the annotations to the field so that annotations applicable only to the record component
1229- * can be attributed as if declared in the field and then stored in the metadata associated to the record
1230- * component.
1231- */
1244+ // fields can't be varargs, lets remove the flag
12321245 List <JCVariableDecl > recordFields = TreeInfo .recordFields (tree );
12331246 for (JCVariableDecl field : recordFields ) {
1234- RecordComponent rec = tree .sym .getRecordComponent (field .sym );
1235- TreeCopier <JCTree > tc = new TreeCopier <>(make .at (field .pos ));
1236- List <JCAnnotation > originalAnnos = tc .copy (rec .getOriginalAnnos ());
1237-
12381247 field .mods .flags &= ~Flags .VARARGS ;
1239- if (originalAnnos .length () != field .mods .annotations .length ()) {
1240- field .mods .annotations = originalAnnos ;
1241- annotate .annotateLater (originalAnnos , env , field .sym , field .pos ());
1242- }
1243-
1244- // also here
12451248 field .sym .flags_field &= ~Flags .VARARGS ;
12461249 }
12471250 // now lets add the accessors
0 commit comments