Skip to content

Commit 396f2c2

Browse files
authored
Merge pull request #174 from Karthik-K-N/qualifiedname
Print qualified field name in error messages
2 parents eff876c + ee219d1 commit 396f2c2

File tree

63 files changed

+1088
-1079
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1088
-1079
lines changed

pkg/analysis/arrayofstruct/analyzer.go

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ func run(pass *analysis.Pass) (any, error) {
4444
return nil, kalerrors.ErrCouldNotGetInspector
4545
}
4646

47-
inspect.InspectFields(func(field *ast.Field, jsonTagInfo extractjsontags.FieldTagInfo, markersAccess markershelper.Markers) {
48-
checkField(pass, field, markersAccess)
47+
inspect.InspectFields(func(field *ast.Field, jsonTagInfo extractjsontags.FieldTagInfo, markersAccess markershelper.Markers, qualifiedFieldName string) {
48+
checkField(pass, field, markersAccess, qualifiedFieldName)
4949
})
5050

5151
return nil, nil //nolint:nilnil
5252
}
5353

54-
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markershelper.Markers) {
54+
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markershelper.Markers, qualifiedFieldName string) {
5555
// Get the element type of the array
5656
elementType := getArrayElementType(pass, field)
5757
if elementType == nil {
@@ -79,7 +79,7 @@ func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markershelp
7979
return
8080
}
8181

82-
reportArrayOfStructIssue(pass, field)
82+
reportArrayOfStructIssue(pass, field, qualifiedFieldName)
8383
}
8484

8585
// getArrayElementType extracts the element type from an array field.
@@ -107,19 +107,8 @@ func getArrayElementType(pass *analysis.Pass, field *ast.Field) ast.Expr {
107107
}
108108

109109
// reportArrayOfStructIssue reports a diagnostic for an array of structs without required fields.
110-
func reportArrayOfStructIssue(pass *analysis.Pass, field *ast.Field) {
111-
fieldName := utils.FieldName(field)
112-
structName := utils.GetStructNameForField(pass, field)
113-
114-
var prefix string
115-
if structName != "" {
116-
prefix = fmt.Sprintf("%s.%s", structName, fieldName)
117-
} else {
118-
prefix = fieldName
119-
}
120-
121-
message := fmt.Sprintf("%s is an array of structs, but the struct has no required fields. At least one field should be marked as required to prevent ambiguous YAML configurations", prefix)
122-
110+
func reportArrayOfStructIssue(pass *analysis.Pass, field *ast.Field, qualifiedFieldName string) {
111+
message := fmt.Sprintf("%s is an array of structs, but the struct has no required fields. At least one field should be marked as required to prevent ambiguous YAML configurations", qualifiedFieldName)
123112
pass.Report(analysis.Diagnostic{
124113
Pos: field.Pos(),
125114
Message: message,

pkg/analysis/commentstart/analyzer.go

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@ import (
1919
"fmt"
2020
"go/ast"
2121
"go/token"
22-
"go/types"
2322
"strings"
2423

2524
"golang.org/x/tools/go/analysis"
2625
kalerrors "sigs.k8s.io/kube-api-linter/pkg/analysis/errors"
2726
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/extractjsontags"
2827
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/inspector"
2928
"sigs.k8s.io/kube-api-linter/pkg/analysis/helpers/markers"
30-
"sigs.k8s.io/kube-api-linter/pkg/analysis/utils"
3129
)
3230

3331
const name = "commentstart"
@@ -47,25 +45,20 @@ func run(pass *analysis.Pass) (any, error) {
4745
return nil, kalerrors.ErrCouldNotGetInspector
4846
}
4947

50-
inspect.InspectFields(func(field *ast.Field, jsonTagInfo extractjsontags.FieldTagInfo, _ markers.Markers) {
51-
checkField(pass, field, jsonTagInfo)
48+
inspect.InspectFields(func(field *ast.Field, jsonTagInfo extractjsontags.FieldTagInfo, _ markers.Markers, qualifiedFieldName string) {
49+
checkField(pass, field, jsonTagInfo, qualifiedFieldName)
5250
})
5351

5452
return nil, nil //nolint:nilnil
5553
}
5654

57-
func checkField(pass *analysis.Pass, field *ast.Field, tagInfo extractjsontags.FieldTagInfo) {
55+
func checkField(pass *analysis.Pass, field *ast.Field, tagInfo extractjsontags.FieldTagInfo, qualifiedFieldName string) {
5856
if tagInfo.Name == "" {
5957
return
6058
}
6159

62-
fieldName := utils.FieldName(field)
63-
if fieldName == "" {
64-
fieldName = types.ExprString(field.Type)
65-
}
66-
6760
if field.Doc == nil {
68-
pass.Reportf(field.Pos(), "field %s is missing godoc comment", fieldName)
61+
pass.Reportf(field.Pos(), "field %s is missing godoc comment", qualifiedFieldName)
6962
return
7063
}
7164

@@ -75,7 +68,7 @@ func checkField(pass *analysis.Pass, field *ast.Field, tagInfo extractjsontags.F
7568
// The comment start is correct, apart from the casing, we can fix that.
7669
pass.Report(analysis.Diagnostic{
7770
Pos: firstLine.Pos(),
78-
Message: fmt.Sprintf("godoc for field %s should start with '%s ...'", fieldName, tagInfo.Name),
71+
Message: fmt.Sprintf("godoc for field %s should start with '%s ...'", qualifiedFieldName, tagInfo.Name),
7972
SuggestedFixes: []analysis.SuggestedFix{
8073
{
8174
Message: fmt.Sprintf("should replace first word with `%s`", tagInfo.Name),
@@ -90,7 +83,7 @@ func checkField(pass *analysis.Pass, field *ast.Field, tagInfo extractjsontags.F
9083
},
9184
})
9285
} else {
93-
pass.Reportf(field.Doc.List[0].Pos(), "godoc for field %s should start with '%s ...'", fieldName, tagInfo.Name)
86+
pass.Reportf(field.Doc.List[0].Pos(), "godoc for field %s should start with '%s ...'", qualifiedFieldName, tagInfo.Name)
9487
}
9588
}
9689
}

pkg/analysis/commentstart/testdata/src/a/a.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ type CommentStartTestStruct struct {
66
NoJSONTag string
77
EmptyJSONTag string `json:""`
88
InlineJSONTag string `json:",inline"`
9-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
9+
NoComment string `json:"noComment"` // want "field CommentStartTestStruct.NoComment is missing godoc comment"
1010
Ignored string `json:"-"`
11-
Hyphen string `json:"-,"` // want "field Hyphen is missing godoc comment"
11+
Hyphen string `json:"-,"` // want "field CommentStartTestStruct.Hyphen is missing godoc comment"
1212

13-
AnonymousStruct struct { // want "field AnonymousStruct is missing godoc comment"
13+
AnonymousStruct struct { // want "field CommentStartTestStruct.AnonymousStruct is missing godoc comment"
1414
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
1515
} `json:"anonymousStruct"`
1616

@@ -24,18 +24,18 @@ type CommentStartTestStruct struct {
2424

2525
StructForInlineField `json:",inline"`
2626

27-
A `json:"a"` // want "field A is missing godoc comment"
27+
A `json:"a"` // want "field CommentStartTestStruct.A is missing godoc comment"
2828

29-
PkgA pkg.A `json:"pkgA"` // want "field PkgA is missing godoc comment"
29+
PkgA pkg.A `json:"pkgA"` // want "field CommentStartTestStruct.PkgA is missing godoc comment"
3030

31-
pkg.Embedded `json:"embedded"` // want "field pkg.Embedded is missing godoc comment"
31+
pkg.Embedded `json:"embedded"` // want "field CommentStartTestStruct.pkg.Embedded is missing godoc comment"
3232

33-
*pkg.EmbeddedPointer `json:"embeddedPointer"` // want "field \\*pkg.EmbeddedPointer is missing godoc comment"
33+
*pkg.EmbeddedPointer `json:"embeddedPointer"` // want "field CommentStartTestStruct.\\*pkg.EmbeddedPointer is missing godoc comment"
3434

35-
// IncorrectStartComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectStartComment should start with 'incorrectStartComment ...'"
35+
// IncorrectStartComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectStartComment should start with 'incorrectStartComment ...'"
3636
IncorrectStartComment string `json:"incorrectStartComment"`
3737

38-
// IncorrectStartOptionalComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectStartOptionalComment should start with 'incorrectStartOptionalComment ...'"
38+
// IncorrectStartOptionalComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectStartOptionalComment should start with 'incorrectStartOptionalComment ...'"
3939
IncorrectStartOptionalComment string `json:"incorrectStartOptionalComment"`
4040

4141
// correctStartComment is a field with a correct start to the comment.
@@ -44,39 +44,39 @@ type CommentStartTestStruct struct {
4444
// correctStartOptionalComment is a field with a correct start to the comment.
4545
CorrectStartOptionalComment string `json:"correctStartOptionalComment,omitempty"`
4646

47-
// IncorrectMultiLineComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectMultiLineComment should start with 'incorrectMultiLineComment ...'"
47+
// IncorrectMultiLineComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectMultiLineComment should start with 'incorrectMultiLineComment ...'"
4848
// Except this time there are multiple lines to the comment.
4949
IncorrectMultiLineComment string `json:"incorrectMultiLineComment"`
5050

5151
// correctMultiLineComment is a field with a correct start to the comment.
5252
// Except this time there are multiple lines to the comment.
5353
CorrectMultiLineComment string `json:"correctMultiLineComment"`
5454

55-
// This comment just isn't correct at all, doesn't even start with anything resembling the field names. // want "godoc for field IncorrectComment should start with 'incorrectComment ...'"
55+
// This comment just isn't correct at all, doesn't even start with anything resembling the field names. // want "godoc for field CommentStartTestStruct.IncorrectComment should start with 'incorrectComment ...'"
5656
IncorrectComment string `json:"incorrectComment"`
5757
}
5858

5959
// DoNothing is used to check that the analyser doesn't report on methods.
6060
func (CommentStartTestStruct) DoNothing() {}
6161

6262
type StructForInlineField struct {
63-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
63+
NoComment string `json:"noComment"` // want "field StructForInlineField.NoComment is missing godoc comment"
6464
}
6565

6666
type A struct {
67-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
67+
NoComment string `json:"noComment"` // want "field A.NoComment is missing godoc comment"
6868
}
6969

7070
type unexportedStruct struct {
71-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
71+
NoComment string `json:"noComment"` // want "field unexportedStruct.NoComment is missing godoc comment"
7272
}
7373

7474
type (
7575
MultipleTypeDeclaration1 struct {
76-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
76+
NoComment string `json:"noComment"` // want "field MultipleTypeDeclaration1.NoComment is missing godoc comment"
7777
}
7878
MultipleTypeDeclaration2 struct {
79-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
79+
NoComment string `json:"noComment"` // want "field MultipleTypeDeclaration2.NoComment is missing godoc comment"
8080
}
8181
)
8282

pkg/analysis/commentstart/testdata/src/a/a.go.golden

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ type CommentStartTestStruct struct {
66
NoJSONTag string
77
EmptyJSONTag string `json:""`
88
InlineJSONTag string `json:",inline"`
9-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
9+
NoComment string `json:"noComment"` // want "field CommentStartTestStruct.NoComment is missing godoc comment"
1010
Ignored string `json:"-"`
11-
Hyphen string `json:"-,"` // want "field Hyphen is missing godoc comment"
11+
Hyphen string `json:"-,"` // want "field CommentStartTestStruct.Hyphen is missing godoc comment"
1212

13-
AnonymousStruct struct { // want "field AnonymousStruct is missing godoc comment"
13+
AnonymousStruct struct { // want "field CommentStartTestStruct.AnonymousStruct is missing godoc comment"
1414
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
1515
} `json:"anonymousStruct"`
1616

@@ -24,18 +24,18 @@ type CommentStartTestStruct struct {
2424

2525
StructForInlineField `json:",inline"`
2626

27-
A `json:"a"` // want "field A is missing godoc comment"
27+
A `json:"a"` // want "field CommentStartTestStruct.A is missing godoc comment"
2828

29-
PkgA pkg.A `json:"pkgA"` // want "field PkgA is missing godoc comment"
29+
PkgA pkg.A `json:"pkgA"` // want "field CommentStartTestStruct.PkgA is missing godoc comment"
3030

31-
pkg.Embedded `json:"embedded"` // want "field pkg.Embedded is missing godoc comment"
31+
pkg.Embedded `json:"embedded"` // want "field CommentStartTestStruct.pkg.Embedded is missing godoc comment"
3232

33-
*pkg.EmbeddedPointer `json:"embeddedPointer"` // want "field \\*pkg.EmbeddedPointer is missing godoc comment"
33+
*pkg.EmbeddedPointer `json:"embeddedPointer"` // want "field CommentStartTestStruct.\\*pkg.EmbeddedPointer is missing godoc comment"
3434

35-
// incorrectStartComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectStartComment should start with 'incorrectStartComment ...'"
35+
// incorrectStartComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectStartComment should start with 'incorrectStartComment ...'"
3636
IncorrectStartComment string `json:"incorrectStartComment"`
3737

38-
// incorrectStartOptionalComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectStartOptionalComment should start with 'incorrectStartOptionalComment ...'"
38+
// incorrectStartOptionalComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectStartOptionalComment should start with 'incorrectStartOptionalComment ...'"
3939
IncorrectStartOptionalComment string `json:"incorrectStartOptionalComment"`
4040

4141
// correctStartComment is a field with a correct start to the comment.
@@ -44,39 +44,39 @@ type CommentStartTestStruct struct {
4444
// correctStartOptionalComment is a field with a correct start to the comment.
4545
CorrectStartOptionalComment string `json:"correctStartOptionalComment,omitempty"`
4646

47-
// incorrectMultiLineComment is a field with an incorrect start to the comment. // want "godoc for field IncorrectMultiLineComment should start with 'incorrectMultiLineComment ...'"
47+
// incorrectMultiLineComment is a field with an incorrect start to the comment. // want "godoc for field CommentStartTestStruct.IncorrectMultiLineComment should start with 'incorrectMultiLineComment ...'"
4848
// Except this time there are multiple lines to the comment.
4949
IncorrectMultiLineComment string `json:"incorrectMultiLineComment"`
5050

5151
// correctMultiLineComment is a field with a correct start to the comment.
5252
// Except this time there are multiple lines to the comment.
5353
CorrectMultiLineComment string `json:"correctMultiLineComment"`
5454

55-
// This comment just isn't correct at all, doesn't even start with anything resembling the field names. // want "godoc for field IncorrectComment should start with 'incorrectComment ...'"
55+
// This comment just isn't correct at all, doesn't even start with anything resembling the field names. // want "godoc for field CommentStartTestStruct.IncorrectComment should start with 'incorrectComment ...'"
5656
IncorrectComment string `json:"incorrectComment"`
5757
}
5858

5959
// DoNothing is used to check that the analyser doesn't report on methods.
6060
func (CommentStartTestStruct) DoNothing() {}
6161

6262
type StructForInlineField struct {
63-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
63+
NoComment string `json:"noComment"` // want "field StructForInlineField.NoComment is missing godoc comment"
6464
}
6565

6666
type A struct {
67-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
67+
NoComment string `json:"noComment"` // want "field A.NoComment is missing godoc comment"
6868
}
6969

7070
type unexportedStruct struct {
71-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
71+
NoComment string `json:"noComment"` // want "field unexportedStruct.NoComment is missing godoc comment"
7272
}
7373

7474
type (
7575
MultipleTypeDeclaration1 struct {
76-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
76+
NoComment string `json:"noComment"` // want "field MultipleTypeDeclaration1.NoComment is missing godoc comment"
7777
}
7878
MultipleTypeDeclaration2 struct {
79-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
79+
NoComment string `json:"noComment"` // want "field MultipleTypeDeclaration2.NoComment is missing godoc comment"
8080
}
8181
)
8282

pkg/analysis/commentstart/testdata/src/a/pkg/a.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package pkg
22

33
type A struct {
4-
NoComment string `json:"noComment"` // want "field NoComment is missing godoc comment"
4+
NoComment string `json:"noComment"` // want "field A.NoComment is missing godoc comment"
55
}
66

77
// To embed the same struct multiple times, we need to rename the type.

pkg/analysis/conflictingmarkers/analyzer.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -67,26 +67,26 @@ func (a *analyzer) run(pass *analysis.Pass) (any, error) {
6767
return nil, kalerrors.ErrCouldNotGetInspector
6868
}
6969

70-
inspect.InspectFields(func(field *ast.Field, _ extractjsontags.FieldTagInfo, markersAccess markers.Markers) {
71-
checkField(pass, field, markersAccess, a.conflictSets)
70+
inspect.InspectFields(func(field *ast.Field, _ extractjsontags.FieldTagInfo, markersAccess markers.Markers, qualifiedFieldName string) {
71+
checkField(pass, field, markersAccess, a.conflictSets, qualifiedFieldName)
7272
})
7373

7474
return nil, nil //nolint:nilnil
7575
}
7676

77-
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Markers, conflictSets []ConflictSet) {
77+
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Markers, conflictSets []ConflictSet, qualifiedFieldName string) {
7878
if field == nil || len(field.Names) == 0 {
7979
return
8080
}
8181

8282
markers := utils.TypeAwareMarkerCollectionForField(pass, markersAccess, field)
8383

8484
for _, conflictSet := range conflictSets {
85-
checkConflict(pass, field, markers, conflictSet)
85+
checkConflict(pass, field, markers, conflictSet, qualifiedFieldName)
8686
}
8787
}
8888

89-
func checkConflict(pass *analysis.Pass, field *ast.Field, markers markers.MarkerSet, conflictSet ConflictSet) {
89+
func checkConflict(pass *analysis.Pass, field *ast.Field, markers markers.MarkerSet, conflictSet ConflictSet, qualifiedFieldName string) {
9090
// Track which sets have markers present
9191
conflictingMarkers := make([]sets.Set[string], 0)
9292

@@ -106,11 +106,11 @@ func checkConflict(pass *analysis.Pass, field *ast.Field, markers markers.Marker
106106

107107
// If two or more sets have markers, report the conflict
108108
if len(conflictingMarkers) >= 2 {
109-
reportConflict(pass, field, conflictSet, conflictingMarkers)
109+
reportConflict(pass, field, conflictSet, conflictingMarkers, qualifiedFieldName)
110110
}
111111
}
112112

113-
func reportConflict(pass *analysis.Pass, field *ast.Field, conflictSet ConflictSet, conflictingMarkers []sets.Set[string]) {
113+
func reportConflict(pass *analysis.Pass, field *ast.Field, conflictSet ConflictSet, conflictingMarkers []sets.Set[string], qualifiedFieldName string) {
114114
// Build a descriptive message showing which sets conflict
115115
setDescriptions := make([]string, 0, len(conflictingMarkers))
116116

@@ -119,15 +119,8 @@ func reportConflict(pass *analysis.Pass, field *ast.Field, conflictSet ConflictS
119119
setDescriptions = append(setDescriptions, fmt.Sprintf("%v", markersList))
120120
}
121121

122-
fieldName := utils.FieldName(field)
123-
structName := utils.GetStructNameForField(pass, field)
124-
125-
if structName != "" {
126-
fieldName = structName + "." + fieldName
127-
}
128-
129122
message := fmt.Sprintf("field %s has conflicting markers: %s: {%s}. %s",
130-
fieldName,
123+
qualifiedFieldName,
131124
conflictSet.Name,
132125
strings.Join(setDescriptions, ", "),
133126
conflictSet.Description)

pkg/analysis/duplicatemarkers/analyzer.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ func run(pass *analysis.Pass) (any, error) {
4848
return nil, kalerrors.ErrCouldNotGetInspector
4949
}
5050

51-
inspect.InspectFields(func(field *ast.Field, _ extractjsontags.FieldTagInfo, markersAccess markers.Markers) {
52-
checkField(pass, field, markersAccess)
51+
inspect.InspectFields(func(field *ast.Field, _ extractjsontags.FieldTagInfo, markersAccess markers.Markers, qualifiedFieldName string) {
52+
checkField(pass, field, markersAccess, qualifiedFieldName)
5353
})
5454

5555
inspect.InspectTypeSpec(func(typeSpec *ast.TypeSpec, markersAccess markers.Markers) {
@@ -59,7 +59,7 @@ func run(pass *analysis.Pass) (any, error) {
5959
return nil, nil //nolint:nilnil
6060
}
6161

62-
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Markers) {
62+
func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Markers, qualifiedFieldName string) {
6363
if field == nil || len(field.Names) == 0 {
6464
return
6565
}
@@ -74,7 +74,7 @@ func checkField(pass *analysis.Pass, field *ast.Field, markersAccess markers.Mar
7474
continue
7575
}
7676

77-
report(pass, field.Pos(), field.Names[0].Name, marker)
77+
report(pass, field.Pos(), qualifiedFieldName, marker)
7878
}
7979
}
8080

0 commit comments

Comments
 (0)