Skip to content

Commit 9cf0295

Browse files
sivchariJoelSpeed
authored andcommitted
use WithStack to check more strictly
Signed-off-by: sivchari <shibuuuu5@gmail.com>
1 parent f5dd31c commit 9cf0295

File tree

1 file changed

+31
-13
lines changed

1 file changed

+31
-13
lines changed

pkg/analysis/jsontags/analyzer.go

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"go/ast"
7+
"go/token"
78
"regexp"
89

910
"github.com/JoelSpeed/kal/pkg/analysis/helpers/extractjsontags"
@@ -64,28 +65,42 @@ func (a *analyzer) run(pass *analysis.Pass) (interface{}, error) {
6465

6566
// Filter to fields so that we can iterate over fields in a struct.
6667
nodeFilter := []ast.Node{
67-
(*ast.StructType)(nil),
68+
(*ast.Field)(nil),
6869
}
6970

70-
inspect.Preorder(nodeFilter, func(n ast.Node) {
71-
sTyp, ok := n.(*ast.StructType)
71+
inspect.WithStack(nodeFilter, func(n ast.Node, push bool, stack []ast.Node) (proceed bool) {
72+
if !push {
73+
return false
74+
}
75+
76+
if len(stack) < 2 {
77+
return true
78+
}
79+
80+
// The 0th node in the stack is the *ast.File.
81+
// The 1st node in the stack is the *ast.GenDecl.
82+
decl, ok := stack[1].(*ast.GenDecl)
7283
if !ok {
73-
return
84+
return false
7485
}
7586

76-
if sTyp.Fields == nil {
77-
return
87+
if decl.Tok != token.TYPE {
88+
// Returning false here means we won't inspect non-type declarations (e.g. var, const, import).
89+
return false
7890
}
7991

80-
for _, field := range sTyp.Fields.List {
81-
a.checkField(pass, field, jsonTags)
92+
field, ok := n.(*ast.Field)
93+
if !ok {
94+
return true
8295
}
96+
97+
return a.checkField(pass, field, jsonTags)
8398
})
8499

85100
return nil, nil //nolint:nilnil
86101
}
87102

88-
func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, jsonTags extractjsontags.StructFieldTags) {
103+
func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, jsonTags extractjsontags.StructFieldTags) (proceed bool) {
89104
tagInfo := jsonTags.FieldTags(field)
90105

91106
var prefix string
@@ -97,26 +112,29 @@ func (a *analyzer) checkField(pass *analysis.Pass, field *ast.Field, jsonTags ex
97112

98113
if tagInfo.Missing {
99114
pass.Reportf(field.Pos(), "%s is missing json tag", prefix)
100-
return
115+
return true
101116
}
102117

103118
if tagInfo.Inline {
104-
return
119+
return true
105120
}
106121

107122
if tagInfo.Ignored {
108-
return
123+
// Returning false here means we won't inspect the children of an ignored field.
124+
return false
109125
}
110126

111127
if tagInfo.Name == "" {
112128
pass.Reportf(field.Pos(), "%s has empty json tag", prefix)
113-
return
129+
return true
114130
}
115131

116132
matched := a.jsonTagRegex.Match([]byte(tagInfo.Name))
117133
if !matched {
118134
pass.Reportf(field.Pos(), "%s json tag does not match pattern %q: %s", prefix, a.jsonTagRegex.String(), tagInfo.Name)
119135
}
136+
137+
return true
120138
}
121139

122140
func defaultConfig(cfg *config.JSONTagsConfig) {

0 commit comments

Comments
 (0)