Skip to content

Commit 375abff

Browse files
authored
fix: proper caching of types. (#9)
Now cache key is a type itself, not it's string name. fix: #8
1 parent 2a7dfaf commit 375abff

File tree

3 files changed

+41
-22
lines changed

3 files changed

+41
-22
lines changed

pkg/analyzer/analyzer.go

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ type analyzer struct {
2121
include PatternsList
2222
exclude PatternsList
2323

24-
typesProcessCache map[string]bool
24+
typesProcessCache map[types.Type]bool
2525
typesProcessCacheMu sync.RWMutex
2626

27-
structFieldsCache map[string]*StructFields
27+
structFieldsCache map[types.Type]*StructFields
2828
structFieldsCacheMu sync.RWMutex
2929
}
3030

@@ -33,9 +33,9 @@ type analyzer struct {
3333
// -e arguments adds exclude patterns
3434
func NewAnalyzer(include []string, exclude []string) (*analysis.Analyzer, error) {
3535
a := analyzer{ //nolint:exhaustruct
36-
typesProcessCache: map[string]bool{},
36+
typesProcessCache: map[types.Type]bool{},
3737

38-
structFieldsCache: map[string]*StructFields{},
38+
structFieldsCache: map[types.Type]*StructFields{},
3939
}
4040

4141
var err error
@@ -123,7 +123,7 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(node ast.Node) {
123123
return
124124
}
125125

126-
if !a.shouldProcessType(typ.String()) {
126+
if !a.shouldProcessType(typ) {
127127
return
128128
}
129129

@@ -138,7 +138,7 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(node ast.Node) {
138138
}
139139
}
140140

141-
missingFields := a.structMissingFields(lit, strct, typ.String(), pass.Pkg.Path())
141+
missingFields := a.structMissingFields(lit, strct, strings.HasPrefix(typ.String(), pass.Pkg.Path()+"."))
142142

143143
if len(missingFields) == 1 {
144144
pass.Reportf(node.Pos(), "%s is missing in %s", missingFields[0], strctName)
@@ -148,7 +148,7 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(node ast.Node) {
148148
}
149149
}
150150

151-
func (a *analyzer) shouldProcessType(typ string) bool {
151+
func (a *analyzer) shouldProcessType(typ types.Type) bool {
152152
if len(a.include) == 0 && len(a.exclude) == 0 {
153153
// skip whole part with cache, since we have no restrictions and have to check everything
154154
return true
@@ -163,12 +163,13 @@ func (a *analyzer) shouldProcessType(typ string) bool {
163163
defer a.typesProcessCacheMu.Unlock()
164164

165165
v = true
166+
typStr := typ.String()
166167

167-
if len(a.include) > 0 && !a.include.MatchesAny(typ) {
168+
if len(a.include) > 0 && !a.include.MatchesAny(typStr) {
168169
v = false
169170
}
170171

171-
if v && a.exclude.MatchesAny(typ) {
172+
if v && a.exclude.MatchesAny(typStr) {
172173
v = false
173174
}
174175

@@ -178,18 +179,13 @@ func (a *analyzer) shouldProcessType(typ string) bool {
178179
return v
179180
}
180181

181-
func (a *analyzer) structMissingFields(
182-
lit *ast.CompositeLit,
183-
strct *types.Struct,
184-
typ string,
185-
pkgPath string,
186-
) []string {
182+
func (a *analyzer) structMissingFields(lit *ast.CompositeLit, strct *types.Struct, private bool) []string {
187183
keys, unnamed := literalKeys(lit)
188-
fields := a.structFields(typ, strct)
184+
fields := a.structFields(strct)
189185

190186
var fieldNames []string
191187

192-
if strings.HasPrefix(typ, pkgPath+".") {
188+
if private {
193189
// we're in same package and should match private fields
194190
fieldNames = fields.All
195191
} else {
@@ -203,7 +199,9 @@ func (a *analyzer) structMissingFields(
203199
return difference(fieldNames, keys)
204200
}
205201

206-
func (a *analyzer) structFields(typ string, strct *types.Struct) *StructFields {
202+
func (a *analyzer) structFields(strct *types.Struct) *StructFields {
203+
typ := strct.Underlying()
204+
207205
a.structFieldsCacheMu.RLock()
208206
fields, ok := a.structFieldsCache[typ]
209207
a.structFieldsCacheMu.RUnlock()

pkg/analyzer/struct-fields.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ import (
55
)
66

77
type StructFields struct {
8+
All []string
89
Public []string
9-
10-
All []string
1110
}
1211

1312
func NewStructFields(strct *types.Struct) *StructFields {
14-
sf := StructFields{} //nolint:exhaustruct
13+
sf := StructFields{
14+
All: make([]string, strct.NumFields()),
15+
Public: []string{},
16+
}
1517

1618
for i := 0; i < strct.NumFields(); i++ {
1719
f := strct.Field(i)
1820

19-
sf.All = append(sf.All, f.Name())
21+
sf.All[i] = f.Name()
2022

2123
if f.Exported() {
2224
sf.Public = append(sf.Public, f.Name())

testdata/src/s/s.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,25 @@ func shouldPass() Test {
3434
}
3535
}
3636

37+
func shouldPassPrivateLocalTypeCorrect1() {
38+
type myTpe struct {
39+
a string
40+
b string
41+
}
42+
43+
_ = myTpe{"", ""}
44+
}
45+
46+
func shouldPassPrivateLocalTypeCorrect2() {
47+
type myTpe struct {
48+
a string
49+
b string
50+
c string
51+
}
52+
53+
_ = myTpe{"", "", ""}
54+
}
55+
3756
func shouldPass2() Test2 {
3857
return Test2{
3958
External: e.External{

0 commit comments

Comments
 (0)