diff options
| author | dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> | 2024-03-04 17:40:11 +0000 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-03-04 18:34:55 +0000 |
| commit | 5fc5366972c874b919f93165bb4ed4e2bcb7c350 (patch) | |
| tree | 287c3361a0dee0c72af80d9a1a66714a06e98a62 /vendor/github.com/GaijinEntertainment | |
| parent | 1be5ce38a9059c356eb193a8c34d60d61c9fc31f (diff) | |
mod: bump github.com/golangci/golangci-lint from 1.55.2 to 1.56.2
Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.55.2 to 1.56.2.
- [Release notes](https://github.com/golangci/golangci-lint/releases)
- [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md)
- [Commits](https://github.com/golangci/golangci-lint/compare/v1.55.2...v1.56.2)
---
updated-dependencies:
- dependency-name: github.com/golangci/golangci-lint
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Diffstat (limited to 'vendor/github.com/GaijinEntertainment')
| -rw-r--r-- | vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go | 75 | ||||
| -rw-r--r-- | vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go | 35 | ||||
| -rw-r--r-- | vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go | 28 | ||||
| -rw-r--r-- | vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go | 35 | ||||
| -rw-r--r-- | vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go (renamed from vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go) | 43 |
5 files changed, 170 insertions, 46 deletions
diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go index d0cd2d5bb..b490f1c64 100644 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/analyzer/analyzer.go @@ -12,16 +12,17 @@ import ( "golang.org/x/tools/go/analysis/passes/inspect" "golang.org/x/tools/go/ast/inspector" - "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields" + "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment" "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/pattern" + "github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure" ) type analyzer struct { include pattern.List `exhaustruct:"optional"` exclude pattern.List `exhaustruct:"optional"` - fieldsCache map[types.Type]fields.StructFields - fieldsCacheMu sync.RWMutex `exhaustruct:"optional"` + structFields structure.FieldsCache `exhaustruct:"optional"` + comments comment.Cache `exhaustruct:"optional"` typeProcessingNeed map[string]bool typeProcessingNeedMu sync.RWMutex `exhaustruct:"optional"` @@ -29,8 +30,8 @@ type analyzer struct { func NewAnalyzer(include, exclude []string) (*analysis.Analyzer, error) { a := analyzer{ - fieldsCache: make(map[types.Type]fields.StructFields), typeProcessingNeed: make(map[string]bool), + comments: comment.Cache{}, } var err error @@ -74,12 +75,7 @@ Anonymous structs can be matched by '<anonymous>' alias. func (a *analyzer) run(pass *analysis.Pass) (any, error) { insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) //nolint:forcetypeassert - insp.WithStack( - []ast.Node{ - (*ast.CompositeLit)(nil), - }, - a.newVisitor(pass), - ) + insp.WithStack([]ast.Node{(*ast.CompositeLit)(nil)}, a.newVisitor(pass)) return nil, nil //nolint:nilnil } @@ -115,7 +111,10 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(n ast.Node, push bool, s } } - pos, msg := a.processStruct(pass, lit, structTyp, typeInfo) + file := a.comments.Get(pass.Fset, stack[0].(*ast.File)) //nolint:forcetypeassert + rc := getCompositeLitRelatedComments(stack, file) + pos, msg := a.processStruct(pass, lit, structTyp, typeInfo, rc) + if pos != nil { pass.Reportf(*pos, msg) } @@ -124,6 +123,35 @@ func (a *analyzer) newVisitor(pass *analysis.Pass) func(n ast.Node, push bool, s } } +// getCompositeLitRelatedComments returns all comments that are related to checked node. We +// have to traverse the stack manually as ast do not associate comments with +// [ast.CompositeLit]. +func getCompositeLitRelatedComments(stack []ast.Node, cm ast.CommentMap) []*ast.CommentGroup { + comments := make([]*ast.CommentGroup, 0) + + for i := len(stack) - 1; i >= 0; i-- { + node := stack[i] + + switch node.(type) { + case *ast.CompositeLit, // stack[len(stack)-1] + *ast.ReturnStmt, // return ... + *ast.IndexExpr, // map[enum]...{...}[key] + *ast.CallExpr, // myfunc(map...) + *ast.UnaryExpr, // &map... + *ast.AssignStmt, // variable assignment (without var keyword) + *ast.DeclStmt, // var declaration, parent of *ast.GenDecl + *ast.GenDecl, // var declaration, parent of *ast.ValueSpec + *ast.ValueSpec: // var declaration + comments = append(comments, cm[node]...) + + default: + return comments + } + } + + return comments +} + func getStructType(pass *analysis.Pass, lit *ast.CompositeLit) (*types.Struct, *TypeInfo, bool) { switch typ := pass.TypesInfo.TypeOf(lit).(type) { case *types.Named: // named type @@ -179,8 +207,15 @@ func (a *analyzer) processStruct( lit *ast.CompositeLit, structTyp *types.Struct, info *TypeInfo, + comments []*ast.CommentGroup, ) (*token.Pos, string) { - if !a.shouldProcessType(info) { + shouldProcess := a.shouldProcessType(info) + + if shouldProcess && comment.HasDirective(comments, comment.DirectiveIgnore) { + return nil, "" + } + + if !shouldProcess && !comment.HasDirective(comments, comment.DirectiveEnforce) { return nil, "" } @@ -233,24 +268,12 @@ func (a *analyzer) shouldProcessType(info *TypeInfo) bool { return res } -//revive:disable-next-line:unused-receiver func (a *analyzer) litSkippedFields( lit *ast.CompositeLit, typ *types.Struct, onlyExported bool, -) fields.StructFields { - a.fieldsCacheMu.RLock() - f, ok := a.fieldsCache[typ] - a.fieldsCacheMu.RUnlock() - - if !ok { - a.fieldsCacheMu.Lock() - f = fields.NewStructFields(typ) - a.fieldsCache[typ] = f - a.fieldsCacheMu.Unlock() - } - - return f.SkippedFields(lit, onlyExported) +) structure.Fields { + return a.structFields.Get(typ).Skipped(lit, onlyExported) } type TypeInfo struct { diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go new file mode 100644 index 000000000..88edef638 --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/cache.go @@ -0,0 +1,35 @@ +package comment + +import ( + "go/ast" + "go/token" + "sync" +) + +type Cache struct { + comments map[*ast.File]ast.CommentMap + mu sync.RWMutex +} + +// Get returns a comment map for a given file. In case if a comment map is not +// found, it creates a new one. +func (c *Cache) Get(fset *token.FileSet, f *ast.File) ast.CommentMap { + c.mu.RLock() + if cm, ok := c.comments[f]; ok { + c.mu.RUnlock() + return cm + } + c.mu.RUnlock() + + c.mu.Lock() + defer c.mu.Unlock() + + if c.comments == nil { + c.comments = make(map[*ast.File]ast.CommentMap) + } + + cm := ast.NewCommentMap(fset, f, f.Comments) + c.comments[f] = cm + + return cm +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go new file mode 100644 index 000000000..a39a8076f --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/comment/directive.go @@ -0,0 +1,28 @@ +package comment + +import ( + "go/ast" + "strings" +) + +type Directive string + +const ( + prefix = `//exhaustruct:` + DirectiveIgnore Directive = prefix + `ignore` + DirectiveEnforce Directive = prefix + `enforce` +) + +// HasDirective parses a directive from a given list of comments. +// If no directive is found, the second return value is `false`. +func HasDirective(comments []*ast.CommentGroup, expected Directive) bool { + for _, cg := range comments { + for _, commentLine := range cg.List { + if strings.HasPrefix(commentLine.Text, string(expected)) { + return true + } + } + } + + return false +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go new file mode 100644 index 000000000..12a379692 --- /dev/null +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields-cache.go @@ -0,0 +1,35 @@ +package structure + +import ( + "go/types" + "sync" +) + +type FieldsCache struct { + fields map[*types.Struct]Fields + mu sync.RWMutex +} + +// Get returns a struct fields for a given type. In case if a struct fields is +// not found, it creates a new one from type definition. +func (c *FieldsCache) Get(typ *types.Struct) Fields { + c.mu.RLock() + fields, ok := c.fields[typ] + c.mu.RUnlock() + + if ok { + return fields + } + + c.mu.Lock() + defer c.mu.Unlock() + + if c.fields == nil { + c.fields = make(map[*types.Struct]Fields) + } + + fields = NewFields(typ) + c.fields[typ] = fields + + return fields +} diff --git a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go index af2390e87..b6b1a48c8 100644 --- a/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/fields/struct.go +++ b/vendor/github.com/GaijinEntertainment/go-exhaustruct/v3/internal/structure/fields.go @@ -1,33 +1,34 @@ -package fields +package structure import ( "go/ast" "go/types" "reflect" + "strings" ) const ( - TagName = "exhaustruct" - OptionalTagValue = "optional" + tagName = "exhaustruct" + optionalTagValue = "optional" ) -type StructField struct { +type Field struct { Name string Exported bool Optional bool } -type StructFields []*StructField +type Fields []*Field -// NewStructFields creates a new [StructFields] from a given struct type. -// StructFields items are listed in order they appear in the struct. -func NewStructFields(strct *types.Struct) StructFields { - sf := make(StructFields, 0, strct.NumFields()) +// NewFields creates a new [Fields] from a given struct type. +// Fields items are listed in order they appear in the struct. +func NewFields(strct *types.Struct) Fields { + sf := make(Fields, 0, strct.NumFields()) for i := 0; i < strct.NumFields(); i++ { f := strct.Field(i) - sf = append(sf, &StructField{ + sf = append(sf, &Field{ Name: f.Name(), Exported: f.Exported(), Optional: HasOptionalTag(strct.Tag(i)), @@ -38,27 +39,29 @@ func NewStructFields(strct *types.Struct) StructFields { } func HasOptionalTag(tags string) bool { - return reflect.StructTag(tags).Get(TagName) == OptionalTagValue + return reflect.StructTag(tags).Get(tagName) == optionalTagValue } // String returns a comma-separated list of field names. -func (sf StructFields) String() (res string) { +func (sf Fields) String() string { + b := strings.Builder{} + for i := 0; i < len(sf); i++ { - if res != "" { - res += ", " + if b.Len() != 0 { + b.WriteString(", ") } - res += sf[i].Name + b.WriteString(sf[i].Name) } - return res + return b.String() } -// SkippedFields returns a list of fields that are not present in the given +// Skipped returns a list of fields that are not present in the given // literal, but expected to. // //revive:disable-next-line:cyclomatic -func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) StructFields { +func (sf Fields) Skipped(lit *ast.CompositeLit, onlyExported bool) Fields { if len(lit.Elts) != 0 && !isNamedLiteral(lit) { if len(lit.Elts) == len(sf) { return nil @@ -68,7 +71,7 @@ func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) S } em := sf.existenceMap() - res := make(StructFields, 0, len(sf)) + res := make(Fields, 0, len(sf)) for i := 0; i < len(lit.Elts); i++ { kv, ok := lit.Elts[i].(*ast.KeyValueExpr) @@ -99,7 +102,7 @@ func (sf StructFields) SkippedFields(lit *ast.CompositeLit, onlyExported bool) S return res } -func (sf StructFields) existenceMap() map[string]bool { +func (sf Fields) existenceMap() map[string]bool { m := make(map[string]bool, len(sf)) for i := 0; i < len(sf); i++ { |
