1616 *******************************************************************************/
1717package org .eclipse .jdt .internal .compiler .ast ;
1818
19+ import java .util .function .Function ;
1920import org .eclipse .jdt .core .compiler .CharOperation ;
2021import org .eclipse .jdt .internal .compiler .ASTVisitor ;
2122import org .eclipse .jdt .internal .compiler .classfmt .ClassFileConstants ;
@@ -241,6 +242,7 @@ public void resolve(ClassScope scope) {
241242 JavadocSingleNameReference param = this .paramReferences [i ];
242243 scope .problemReporter ().javadocUnexpectedTag (param .tagSourceStart , param .tagSourceEnd );
243244 }
245+ resolveParamTags (scope , true );
244246 resolveTypeParameterTags (scope , true );
245247
246248 // @return tags
@@ -542,9 +544,32 @@ else if (reference instanceof JavadocSingleTypeReference && reference.resolvedTy
542544 scope .problemReporter ().javadocInvalidReference (reference .sourceStart , reference .sourceEnd );
543545 }
544546 }
545-
546547 /*
547- * Resolve @param tags while method scope
548+ * Resolve @param tags for records
549+ */
550+ private void resolveParamTags (ClassScope scope , boolean reportMissing ) {
551+ TypeDeclaration typeDecl = scope .referenceContext ;
552+ if (!typeDecl .isRecord ())
553+ return ;
554+ Function <JavadocSingleNameReference , Binding > resolveNameRef =
555+ (nameRef ) -> {
556+ nameRef .resolve (scope );
557+ return nameRef .binding ;
558+ };
559+ Function <AbstractVariableDeclaration , Binding > resolveArgumentOrComponent =
560+ (arg ) -> {
561+ return typeDecl .binding .getField (arg .name , false );
562+ };
563+ resolveParamTags (typeDecl .initializerScope ,
564+ reportMissing ,
565+ typeDecl .recordComponents ,
566+ true ,
567+ typeDecl .modifiers , // not used
568+ resolveNameRef ,
569+ resolveArgumentOrComponent );
570+ }
571+ /*
572+ * Resolve @param tags for methods
548573 */
549574 private void resolveParamTags (MethodScope scope , boolean reportMissing , boolean considerParamRefAsUsage ) {
550575 AbstractMethodDeclaration methodDecl = scope .referenceMethod ();
@@ -558,36 +583,62 @@ private void resolveParamTags(MethodScope scope, boolean reportMissing, boolean
558583 }
559584 return ;
560585 }
586+ Function <JavadocSingleNameReference , Binding > resolveNameRef =
587+ (nameRef ) -> {
588+ nameRef .resolve (scope , true , considerParamRefAsUsage );
589+ return nameRef .binding ;
590+ };
591+ Function <AbstractVariableDeclaration , Binding > resolveArgumentOrComponent =
592+ (arg ) -> {
593+ return arg instanceof Argument argument ? argument .binding : scope .findVariable (arg .name );
594+ };
595+ resolveParamTags (scope ,
596+ reportMissing ,
597+ methodDecl .arguments (),
598+ !methodDecl .isCompactConstructor (),
599+ methodDecl .binding .modifiers ,
600+ resolveNameRef ,
601+ resolveArgumentOrComponent );
602+ }
603+ private void resolveParamTags (MethodScope scope ,
604+ boolean reportMissing ,
605+ AbstractVariableDeclaration [] arguments ,
606+ boolean reportAllUndocumented ,
607+ int modifiers ,
608+ Function <JavadocSingleNameReference , Binding > resolveNameRef ,
609+ Function <AbstractVariableDeclaration , Binding > resolveArgumentOrComponent ) {
561610
611+ int paramTagsSize = this .paramReferences == null ? 0 : this .paramReferences .length ;
562612 // If no param tags then report a problem for each method argument
563- AbstractVariableDeclaration [] arguments = methodDecl .arguments (true );
564613 int argumentsSize = arguments == null ? 0 : arguments .length ;
565614 if (paramTagsSize == 0 ) {
566- if (reportMissing && ! methodDecl . isCompactConstructor () ) {
615+ if (reportMissing && reportAllUndocumented ) {
567616 for (int i = 0 ; i < argumentsSize ; i ++) {
568617 AbstractVariableDeclaration arg = arguments [i ];
569- scope .problemReporter ().javadocMissingParamTag (arg .name , arg .sourceStart , arg .sourceEnd , methodDecl . binding . modifiers );
618+ scope .problemReporter ().javadocMissingParamTag (arg .name , arg .sourceStart , arg .sourceEnd , modifiers );
570619 }
571620 }
621+ return ;
572622 } else {
573- LocalVariableBinding [] bindings = new LocalVariableBinding [paramTagsSize ];
623+ VariableBinding [] bindings = new VariableBinding [paramTagsSize ];
574624 int maxBindings = 0 ;
575625
576626 // Scan all @param tags
577627 for (int i = 0 ; i < paramTagsSize ; i ++) {
578628 JavadocSingleNameReference param = this .paramReferences [i ];
579- param .resolve (scope , true , considerParamRefAsUsage );
580- if (param .binding != null && param .binding .isValidBinding ()) {
629+
630+ Binding lBinding = resolveNameRef .apply (param );
631+ if (lBinding instanceof VariableBinding varBinding ) {
581632 // Verify duplicated tags
582633 boolean found = false ;
583634 for (int j = 0 ; j < maxBindings && !found ; j ++) {
584635 if (bindings [j ] == param .binding ) {
585- scope .problemReporter ().javadocDuplicatedParamTag (param .token , param .sourceStart , param .sourceEnd , methodDecl . binding . modifiers );
636+ scope .problemReporter ().javadocDuplicatedParamTag (param .token , param .sourceStart , param .sourceEnd , modifiers );
586637 found = true ;
587638 }
588639 }
589640 if (!found ) {
590- bindings [maxBindings ++] = ( LocalVariableBinding ) param . binding ;
641+ bindings [maxBindings ++] = varBinding ;
591642 }
592643 }
593644 }
@@ -596,17 +647,19 @@ private void resolveParamTags(MethodScope scope, boolean reportMissing, boolean
596647 if (reportMissing ) {
597648 for (int i = 0 ; i < argumentsSize ; i ++) {
598649 AbstractVariableDeclaration arg = arguments [i ];
599- LocalVariableBinding argBinding = arg instanceof Argument argument ? argument .binding : scope .findVariable (arg .name );
600- boolean found = false ;
601- for (int j = 0 ; j < maxBindings ; j ++) {
602- LocalVariableBinding binding = bindings [j ];
603- if (argBinding == binding ) {
604- found = true ;
605- break ;
650+ Binding lBinding = resolveArgumentOrComponent .apply (arg );
651+ if (lBinding instanceof VariableBinding argBinding ) {
652+ boolean found = false ;
653+ for (int j = 0 ; j < maxBindings ; j ++) {
654+ VariableBinding binding = bindings [j ];
655+ if (argBinding == binding ) {
656+ found = true ;
657+ break ;
658+ }
659+ }
660+ if (!found ) {
661+ scope .problemReporter ().javadocMissingParamTag (arg .name , arg .sourceStart , arg .sourceEnd , modifiers );
606662 }
607- }
608- if (!found ) {
609- scope .problemReporter ().javadocMissingParamTag (arg .name , arg .sourceStart , arg .sourceEnd , methodDecl .binding .modifiers );
610663 }
611664 }
612665 }
@@ -760,12 +813,10 @@ private void resolveProvidesTags(BlockScope scope, boolean reportMissing) {
760813 */
761814 private void resolveTypeParameterTags (Scope scope , boolean reportMissing ) {
762815 int paramTypeParamLength = this .paramTypeParameters == null ? 0 : this .paramTypeParameters .length ;
763- int paramReferencesLength = this .paramReferences == null ? 0 : this .paramReferences .length ;
764816
765817 // Get declaration infos
766818 TypeParameter [] parameters = null ;
767819 TypeVariableBinding [] typeVariables = null ;
768- RecordComponent [] recordParameters = null ;
769820 int modifiers = -1 ;
770821 switch (scope .kind ) {
771822 case Scope .METHOD_SCOPE :
@@ -787,81 +838,17 @@ private void resolveTypeParameterTags(Scope scope, boolean reportMissing) {
787838 parameters = typeDeclaration .typeParameters ;
788839 typeVariables = typeDeclaration .binding .typeVariables ;
789840 modifiers = typeDeclaration .binding .modifiers ;
790- recordParameters = typeDeclaration .recordComponents ;
791841 break ;
792842 }
793843
794844 // If no type variables then report a problem for each param type parameter tag
795- if ((recordParameters == null || recordParameters .length == 0 )
796- && (typeVariables == null || typeVariables .length == 0 )) {
845+ if ((typeVariables == null || typeVariables .length == 0 )) {
797846 for (int i = 0 ; i < paramTypeParamLength ; i ++) {
798847 JavadocSingleTypeReference param = this .paramTypeParameters [i ];
799848 scope .problemReporter ().javadocUnexpectedTag (param .tagSourceStart , param .tagSourceEnd );
800849 }
801850 return ;
802851 }
803-
804- // If no param tags then report a problem for each record parameter
805- if (recordParameters != null ) {
806- int recordParametersLength = recordParameters .length ;
807- String argNames [] = new String [paramReferencesLength ];
808- if (paramReferencesLength == 0 ) {
809- if (reportMissing ) {
810- for (int i = 0 , l =recordParametersLength ; i <l ; i ++) {
811- scope .problemReporter ().javadocMissingParamTag (recordParameters [i ].name , recordParameters [i ].sourceStart , recordParameters [i ].sourceEnd , modifiers );
812- }
813- }
814- } else {
815- // Otherwise verify that all param tags match record args
816- // Scan all @param tags
817- for (int i = 0 ; i < paramReferencesLength ; ++i ) {
818- JavadocSingleNameReference param = this .paramReferences [i ];
819- String paramName = new String (param .getName ()[0 ]);
820- // Verify duplicated tags
821- boolean duplicate = false ;
822- for (int j = 0 ; j < i && !duplicate ; j ++) {
823- if (paramName .equals (argNames [j ])) {
824- scope .problemReporter ().javadocDuplicatedParamTag (param .token , param .sourceStart , param .sourceEnd , modifiers );
825- duplicate = true ;
826- }
827- }
828- if (!duplicate ) {
829- argNames [i ] = paramName ;
830- }
831- }
832- // Look for undocumented arguments
833- if (reportMissing ) {
834- for (RecordComponent component : recordParameters ) {
835- boolean found = false ;
836- for (int j = 0 ; j < paramReferencesLength && !found ; j ++) {
837- JavadocSingleNameReference param = this .paramReferences [j ];
838- String paramName = new String (param .getName ()[0 ]);
839- if (paramName .equals (new String (component .name ))) {
840- found = true ;
841- }
842- }
843- if (!found ) {
844- scope .problemReporter ().javadocMissingParamTag (component .name , component .sourceStart , component .sourceEnd , modifiers );
845- }
846- }
847- }
848- // Look for param tags that specify non-existent arguments
849- for (int i = 0 ; i < paramReferencesLength ; i ++) {
850- JavadocSingleNameReference param = this .paramReferences [i ];
851- String paramName = new String (param .getName ()[0 ]);
852- boolean found = false ;
853- for (RecordComponent component : recordParameters ) {
854- if (paramName .equals (new String (component .name ))) {
855- found = true ;
856- }
857- }
858- if (!found ) {
859- scope .problemReporter ().javadocInvalidParamTagName (param .sourceStart , param .sourceEnd );
860- }
861- }
862- }
863- }
864-
865852 // If no param tags then report a problem for each declaration type parameter
866853 if (parameters != null ) {
867854 int typeParametersLength = parameters .length ;
0 commit comments