Skip to content

Commit

Permalink
fix: proper caching of types.
Browse files Browse the repository at this point in the history
Now cache key is a type itself, not it's string name.

fix: #8
  • Loading branch information
xobotyi committed Jul 29, 2022
1 parent 5b6eeb2 commit a4b0935
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 22 deletions.
34 changes: 16 additions & 18 deletions pkg/analyzer/analyzer.go
Expand Up @@ -21,10 +21,10 @@ type analyzer struct {
include PatternsList
exclude PatternsList

typesProcessCache map[string]bool
typesProcessCache map[types.Type]bool
typesProcessCacheMu sync.RWMutex

structFieldsCache map[string]*StructFields
structFieldsCache map[types.Type]*StructFields
structFieldsCacheMu sync.RWMutex
}

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

structFieldsCache: map[string]*StructFields{},
structFieldsCache: map[types.Type]*StructFields{},
}

var err error
Expand Down Expand Up @@ -123,7 +123,7 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(node ast.Node) {
return
}

if !a.shouldProcessType(typ.String()) {
if !a.shouldProcessType(typ) {
return
}

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

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

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

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

v = true
typStr := typ.String()

if len(a.include) > 0 && !a.include.MatchesAny(typ) {
if len(a.include) > 0 && !a.include.MatchesAny(typStr) {
v = false
}

if v && a.exclude.MatchesAny(typ) {
if v && a.exclude.MatchesAny(typStr) {
v = false
}

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

func (a *analyzer) structMissingFields(
lit *ast.CompositeLit,
strct *types.Struct,
typ string,
pkgPath string,
) []string {
func (a *analyzer) structMissingFields(lit *ast.CompositeLit, strct *types.Struct, private bool) []string {
keys, unnamed := literalKeys(lit)
fields := a.structFields(typ, strct)
fields := a.structFields(strct)

var fieldNames []string

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

func (a *analyzer) structFields(typ string, strct *types.Struct) *StructFields {
func (a *analyzer) structFields(strct *types.Struct) *StructFields {
typ := strct.Underlying()

a.structFieldsCacheMu.RLock()
fields, ok := a.structFieldsCache[typ]
a.structFieldsCacheMu.RUnlock()
Expand Down
10 changes: 6 additions & 4 deletions pkg/analyzer/struct-fields.go
Expand Up @@ -5,18 +5,20 @@ import (
)

type StructFields struct {
All []string
Public []string

All []string
}

func NewStructFields(strct *types.Struct) *StructFields {
sf := StructFields{} //nolint:exhaustruct
sf := StructFields{
All: make([]string, strct.NumFields()),
Public: []string{},
}

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

sf.All = append(sf.All, f.Name())
sf.All[i] = f.Name()

if f.Exported() {
sf.Public = append(sf.Public, f.Name())
Expand Down
19 changes: 19 additions & 0 deletions testdata/src/s/s.go
Expand Up @@ -34,6 +34,25 @@ func shouldPass() Test {
}
}

func shouldPassPrivateLocalTypeCorrect1() {
type myTpe struct {
a string
b string
}

_ = myTpe{"", ""}
}

func shouldPassPrivateLocalTypeCorrect2() {
type myTpe struct {
a string
b string
c string
}

_ = myTpe{"", "", ""}
}

func shouldPass2() Test2 {
return Test2{
External: e.External{
Expand Down

0 comments on commit a4b0935

Please sign in to comment.