aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/kulti
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/kulti
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/kulti')
-rw-r--r--vendor/github.com/kulti/thelper/LICENSE21
-rw-r--r--vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go639
-rw-r--r--vendor/github.com/kulti/thelper/pkg/analyzer/report.go56
3 files changed, 0 insertions, 716 deletions
diff --git a/vendor/github.com/kulti/thelper/LICENSE b/vendor/github.com/kulti/thelper/LICENSE
deleted file mode 100644
index e070215fe..000000000
--- a/vendor/github.com/kulti/thelper/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020 Aleksey Bakin
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go b/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go
deleted file mode 100644
index a22fd6aca..000000000
--- a/vendor/github.com/kulti/thelper/pkg/analyzer/analyzer.go
+++ /dev/null
@@ -1,639 +0,0 @@
-package analyzer
-
-import (
- "flag"
- "fmt"
- "go/ast"
- "go/token"
- "go/types"
- "sort"
- "strings"
-
- "github.com/gostaticanalysis/analysisutil"
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
-)
-
-const (
- doc = "thelper detects tests helpers which is not start with t.Helper() method."
- checksDoc = `coma separated list of enabled checks
-
-Available checks
-
-` + checkTBegin + ` - check t.Helper() begins helper function
-` + checkTFirst + ` - check *testing.T is first param of helper function
-` + checkTName + ` - check *testing.T param has t name
-
-Also available similar checks for benchmark and TB helpers: ` +
- checkFBegin + `, ` + checkFFirst + `, ` + checkFName + `,` +
- checkBBegin + `, ` + checkBFirst + `, ` + checkBName + `,` +
- checkTBBegin + `, ` + checkTBFirst + `, ` + checkTBName + `
-
-`
-)
-
-type enabledChecksValue map[string]struct{}
-
-func (m enabledChecksValue) Enabled(c string) bool {
- _, ok := m[c]
- return ok
-}
-
-func (m enabledChecksValue) String() string {
- ss := make([]string, 0, len(m))
- for s := range m {
- ss = append(ss, s)
- }
- sort.Strings(ss)
- return strings.Join(ss, ",")
-}
-
-func (m enabledChecksValue) Set(s string) error {
- ss := strings.FieldsFunc(s, func(c rune) bool { return c == ',' })
- if len(ss) == 0 {
- return nil
- }
-
- for k := range m {
- delete(m, k)
- }
- for _, v := range ss {
- switch v {
- case checkTBegin, checkTFirst, checkTName,
- checkFBegin, checkFFirst, checkFName,
- checkBBegin, checkBFirst, checkBName,
- checkTBBegin, checkTBFirst, checkTBName:
- m[v] = struct{}{}
- default:
- return fmt.Errorf("unknown check name %q (see help for full list)", v)
- }
- }
- return nil
-}
-
-const (
- checkTBegin = "t_begin"
- checkTFirst = "t_first"
- checkTName = "t_name"
- checkFBegin = "f_begin"
- checkFFirst = "f_first"
- checkFName = "f_name"
- checkBBegin = "b_begin"
- checkBFirst = "b_first"
- checkBName = "b_name"
- checkTBBegin = "tb_begin"
- checkTBFirst = "tb_first"
- checkTBName = "tb_name"
-)
-
-type thelper struct {
- enabledChecks enabledChecksValue
-}
-
-// NewAnalyzer return a new thelper analyzer.
-// thelper analyzes Go test codes how they use t.Helper() method.
-func NewAnalyzer() *analysis.Analyzer {
- thelper := thelper{}
- thelper.enabledChecks = enabledChecksValue{
- checkTBegin: struct{}{},
- checkTFirst: struct{}{},
- checkTName: struct{}{},
- checkFBegin: struct{}{},
- checkFFirst: struct{}{},
- checkFName: struct{}{},
- checkBBegin: struct{}{},
- checkBFirst: struct{}{},
- checkBName: struct{}{},
- checkTBBegin: struct{}{},
- checkTBFirst: struct{}{},
- checkTBName: struct{}{},
- }
-
- a := &analysis.Analyzer{
- Name: "thelper",
- Doc: doc,
- Run: thelper.run,
- Requires: []*analysis.Analyzer{
- inspect.Analyzer,
- },
- }
-
- a.Flags.Init("thelper", flag.ExitOnError)
- a.Flags.Var(&thelper.enabledChecks, "checks", checksDoc)
-
- return a
-}
-
-func (t thelper) run(pass *analysis.Pass) (interface{}, error) {
- tCheckOpts, fCheckOpts, bCheckOpts, tbCheckOpts, ok := t.buildCheckFuncOpts(pass)
- if !ok {
- return nil, nil
- }
-
- inspect, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
- if !ok {
- return nil, nil
- }
-
- var reports reports
- nodeFilter := []ast.Node{
- (*ast.FuncDecl)(nil),
- (*ast.FuncLit)(nil),
- (*ast.CallExpr)(nil),
- }
- inspect.Preorder(nodeFilter, func(node ast.Node) {
- var fd funcDecl
- switch n := node.(type) {
- case *ast.FuncLit:
- fd.Pos = n.Pos()
- fd.Type = n.Type
- fd.Body = n.Body
- fd.Name = ast.NewIdent("")
- case *ast.FuncDecl:
- fd.Pos = n.Name.NamePos
- fd.Type = n.Type
- fd.Body = n.Body
- fd.Name = n.Name
- case *ast.CallExpr:
- runSubtestExprs := extractSubtestExp(pass, n, tCheckOpts.subRun, tCheckOpts.subTestFuncType)
- if len(runSubtestExprs) == 0 {
- runSubtestExprs = extractSubtestExp(pass, n, bCheckOpts.subRun, bCheckOpts.subTestFuncType)
- }
- if len(runSubtestExprs) == 0 {
- runSubtestExprs = extractSubtestFuzzExp(pass, n, fCheckOpts.subRun)
- }
-
- if len(runSubtestExprs) > 0 {
- for _, expr := range runSubtestExprs {
- reports.Filter(funcDefPosition(pass, expr))
- }
- } else {
- reports.NoFilter(funcDefPosition(pass, n.Fun))
- }
- return
- default:
- return
- }
-
- checkFunc(pass, &reports, fd, tCheckOpts)
- checkFunc(pass, &reports, fd, fCheckOpts)
- checkFunc(pass, &reports, fd, bCheckOpts)
- checkFunc(pass, &reports, fd, tbCheckOpts)
- })
-
- reports.Flush(pass)
-
- return nil, nil
-}
-
-type checkFuncOpts struct {
- skipPrefix string
- varName string
- fnHelper types.Object
- subRun types.Object
- subTestFuncType types.Type
- hpType types.Type
- ctxType types.Type
- checkBegin bool
- checkFirst bool
- checkName bool
-}
-
-func (t thelper) buildCheckFuncOpts(pass *analysis.Pass) (checkFuncOpts, checkFuncOpts, checkFuncOpts, checkFuncOpts, bool) {
- var ctxType types.Type
- ctxObj := analysisutil.ObjectOf(pass, "context", "Context")
- if ctxObj != nil {
- ctxType = ctxObj.Type()
- }
-
- tCheckOpts, ok := t.buildTestCheckFuncOpts(pass, ctxType)
- if !ok {
- return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false
- }
-
- fCheckOpts, ok := t.buildFuzzCheckFuncOpts(pass, ctxType)
- if !ok {
- return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false
- }
-
- bCheckOpts, ok := t.buildBenchmarkCheckFuncOpts(pass, ctxType)
- if !ok {
- return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false
- }
-
- tbCheckOpts, ok := t.buildTBCheckFuncOpts(pass, ctxType)
- if !ok {
- return checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, checkFuncOpts{}, false
- }
-
- return tCheckOpts, fCheckOpts, bCheckOpts, tbCheckOpts, true
-}
-
-func (t thelper) buildTestCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) {
- tObj := analysisutil.ObjectOf(pass, "testing", "T")
- if tObj == nil {
- return checkFuncOpts{}, false
- }
-
- tHelper, _, _ := types.LookupFieldOrMethod(tObj.Type(), true, tObj.Pkg(), "Helper")
- if tHelper == nil {
- return checkFuncOpts{}, false
- }
-
- tRun, _, _ := types.LookupFieldOrMethod(tObj.Type(), true, tObj.Pkg(), "Run")
- if tRun == nil {
- return checkFuncOpts{}, false
- }
-
- tType := types.NewPointer(tObj.Type())
- tVar := types.NewVar(token.NoPos, nil, "t", tType)
- return checkFuncOpts{
- skipPrefix: "Test",
- varName: "t",
- fnHelper: tHelper,
- subRun: tRun,
- hpType: tType,
- subTestFuncType: types.NewSignature(nil, types.NewTuple(tVar), nil, false),
- ctxType: ctxType,
- checkBegin: t.enabledChecks.Enabled(checkTBegin),
- checkFirst: t.enabledChecks.Enabled(checkTFirst),
- checkName: t.enabledChecks.Enabled(checkTName),
- }, true
-}
-
-func (t thelper) buildFuzzCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) {
- fObj := analysisutil.ObjectOf(pass, "testing", "F")
- if fObj == nil {
- return checkFuncOpts{}, true // fuzzing supports since go1.18, it's ok, that testig.F is missed.
- }
-
- fHelper, _, _ := types.LookupFieldOrMethod(fObj.Type(), true, fObj.Pkg(), "Helper")
- if fHelper == nil {
- return checkFuncOpts{}, false
- }
-
- tFuzz, _, _ := types.LookupFieldOrMethod(fObj.Type(), true, fObj.Pkg(), "Fuzz")
- if tFuzz == nil {
- return checkFuncOpts{}, false
- }
-
- return checkFuncOpts{
- skipPrefix: "Fuzz",
- varName: "f",
- fnHelper: fHelper,
- subRun: tFuzz,
- hpType: types.NewPointer(fObj.Type()),
- ctxType: ctxType,
- checkBegin: t.enabledChecks.Enabled(checkFBegin),
- checkFirst: t.enabledChecks.Enabled(checkFFirst),
- checkName: t.enabledChecks.Enabled(checkFName),
- }, true
-}
-
-func (t thelper) buildBenchmarkCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) {
- bObj := analysisutil.ObjectOf(pass, "testing", "B")
- if bObj == nil {
- return checkFuncOpts{}, false
- }
-
- bHelper, _, _ := types.LookupFieldOrMethod(bObj.Type(), true, bObj.Pkg(), "Helper")
- if bHelper == nil {
- return checkFuncOpts{}, false
- }
-
- bRun, _, _ := types.LookupFieldOrMethod(bObj.Type(), true, bObj.Pkg(), "Run")
- if bRun == nil {
- return checkFuncOpts{}, false
- }
-
- bType := types.NewPointer(bObj.Type())
- bVar := types.NewVar(token.NoPos, nil, "b", bType)
- return checkFuncOpts{
- skipPrefix: "Benchmark",
- varName: "b",
- fnHelper: bHelper,
- subRun: bRun,
- hpType: types.NewPointer(bObj.Type()),
- subTestFuncType: types.NewSignature(nil, types.NewTuple(bVar), nil, false),
- ctxType: ctxType,
- checkBegin: t.enabledChecks.Enabled(checkBBegin),
- checkFirst: t.enabledChecks.Enabled(checkBFirst),
- checkName: t.enabledChecks.Enabled(checkBName),
- }, true
-}
-
-func (t thelper) buildTBCheckFuncOpts(pass *analysis.Pass, ctxType types.Type) (checkFuncOpts, bool) {
- tbObj := analysisutil.ObjectOf(pass, "testing", "TB")
- if tbObj == nil {
- return checkFuncOpts{}, false
- }
-
- tbHelper, _, _ := types.LookupFieldOrMethod(tbObj.Type(), true, tbObj.Pkg(), "Helper")
- if tbHelper == nil {
- return checkFuncOpts{}, false
- }
-
- return checkFuncOpts{
- skipPrefix: "",
- varName: "tb",
- fnHelper: tbHelper,
- hpType: tbObj.Type(),
- ctxType: ctxType,
- checkBegin: t.enabledChecks.Enabled(checkTBBegin),
- checkFirst: t.enabledChecks.Enabled(checkTBFirst),
- checkName: t.enabledChecks.Enabled(checkTBName),
- }, true
-}
-
-type funcDecl struct {
- Pos token.Pos
- Name *ast.Ident
- Type *ast.FuncType
- Body *ast.BlockStmt
-}
-
-func checkFunc(pass *analysis.Pass, reports *reports, funcDecl funcDecl, opts checkFuncOpts) {
- if !opts.checkFirst && !opts.checkBegin && !opts.checkName {
- return
- }
-
- if opts.skipPrefix != "" && strings.HasPrefix(funcDecl.Name.Name, opts.skipPrefix) {
- return
- }
-
- p, pos, ok := searchFuncParam(pass, funcDecl, opts.hpType)
- if !ok {
- return
- }
-
- if opts.checkFirst {
- if pos != 0 {
- checkFirstPassed := false
- if pos == 1 && opts.ctxType != nil {
- _, pos, ok := searchFuncParam(pass, funcDecl, opts.ctxType)
- checkFirstPassed = ok && (pos == 0)
- }
-
- if !checkFirstPassed {
- reports.Reportf(funcDecl.Pos, "parameter %s should be the first or after context.Context", opts.hpType)
- }
- }
- }
-
- if len(p.Names) > 0 && p.Names[0].Name != "_" {
- if opts.checkName {
- if p.Names[0].Name != opts.varName {
- reports.Reportf(funcDecl.Pos, "parameter %s should have name %s", opts.hpType, opts.varName)
- }
- }
-
- if opts.checkBegin {
- if len(funcDecl.Body.List) == 0 || !isTHelperCall(pass, funcDecl.Body.List[0], opts.fnHelper) {
- reports.Reportf(funcDecl.Pos, "test helper function should start from %s.Helper()", opts.varName)
- }
- }
- }
-}
-
-// searchFuncParam search a function param with desired type.
-// It returns the param field, its position, and true if something is found.
-func searchFuncParam(pass *analysis.Pass, f funcDecl, p types.Type) (*ast.Field, int, bool) {
- for i, f := range f.Type.Params.List {
- if isExprHasType(pass, f.Type, p) {
- return f, i, true
- }
- }
- return nil, 0, false
-}
-
-// isTHelperCall returns true if provided statement 's' is t.Helper() or b.Helper() call.
-func isTHelperCall(pass *analysis.Pass, s ast.Stmt, tHelper types.Object) bool {
- exprStmt, ok := s.(*ast.ExprStmt)
- if !ok {
- return false
- }
-
- callExpr, ok := exprStmt.X.(*ast.CallExpr)
- if !ok {
- return false
- }
-
- selExpr, ok := callExpr.Fun.(*ast.SelectorExpr)
- if !ok {
- return false
- }
-
- return isSelectorCall(pass, selExpr, tHelper)
-}
-
-// extractSubtestExp analyzes that call expresion 'e' is t.Run or b.Run
-// and returns subtest function.
-func extractSubtestExp(
- pass *analysis.Pass, e *ast.CallExpr, tbRun types.Object, testFuncType types.Type,
-) []ast.Expr {
- selExpr, ok := e.Fun.(*ast.SelectorExpr)
- if !ok {
- return nil
- }
-
- if !isSelectorCall(pass, selExpr, tbRun) {
- return nil
- }
-
- if len(e.Args) != 2 {
- return nil
- }
-
- if funcs := unwrapTestingFunctionBuilding(pass, e.Args[1], testFuncType); funcs != nil {
- return funcs
- }
-
- return []ast.Expr{e.Args[1]}
-}
-
-// extractSubtestFuzzExp analyzes that call expresion 'e' is f.Fuzz
-// and returns subtest function.
-func extractSubtestFuzzExp(
- pass *analysis.Pass, e *ast.CallExpr, fuzzRun types.Object,
-) []ast.Expr {
- selExpr, ok := e.Fun.(*ast.SelectorExpr)
- if !ok {
- return nil
- }
-
- if !isSelectorCall(pass, selExpr, fuzzRun) {
- return nil
- }
-
- if len(e.Args) != 1 {
- return nil
- }
-
- return []ast.Expr{e.Args[0]}
-}
-
-// unwrapTestingFunctionConstruction checks that expresion is build testing functions
-// and returns the result of building.
-func unwrapTestingFunctionBuilding(pass *analysis.Pass, expr ast.Expr, testFuncType types.Type) []ast.Expr {
- callExpr, ok := expr.(*ast.CallExpr)
- if !ok {
- return nil
- }
-
- var funcDecl funcDecl
- switch f := callExpr.Fun.(type) {
- case *ast.FuncLit:
- funcDecl.Body = f.Body
- funcDecl.Type = f.Type
- case *ast.Ident:
- funObjDecl := findFunctionDeclaration(pass, f)
- if funObjDecl == nil {
- return nil
- }
-
- funcDecl.Body = funObjDecl.Body
- funcDecl.Type = funObjDecl.Type
- case *ast.SelectorExpr:
- fd := findSelectorDeclaration(pass, f)
- if fd == nil {
- return nil
- }
-
- funcDecl.Body = fd.Body
- funcDecl.Type = fd.Type
- default:
- return nil
- }
-
- results := funcDecl.Type.Results.List
- if len(results) != 1 || !isExprHasType(pass, results[0].Type, testFuncType) {
- return nil
- }
-
- var funcs []ast.Expr
- ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
- if n == nil {
- return false
- }
-
- if retStmt, ok := n.(*ast.ReturnStmt); ok {
- if len(retStmt.Results) == 1 {
- funcs = append(funcs, retStmt.Results[0])
- }
- }
- return true
- })
-
- return funcs
-}
-
-// funcDefPosition returns a function's position.
-// It works with anonymous functions as well with function names.
-func funcDefPosition(pass *analysis.Pass, e ast.Expr) token.Pos {
- anonFunLit, ok := e.(*ast.FuncLit)
- if ok {
- return anonFunLit.Pos()
- }
-
- funIdent, ok := e.(*ast.Ident)
- if !ok {
- selExpr, ok := e.(*ast.SelectorExpr)
- if !ok {
- return token.NoPos
- }
- funIdent = selExpr.Sel
- }
-
- funDef, ok := pass.TypesInfo.Uses[funIdent]
- if !ok {
- return token.NoPos
- }
-
- return funDef.Pos()
-}
-
-// isSelectorCall checks is selExpr is a call expresion on specific callObj.
-// Useful to check Run() call for t.Run or b.Run.
-func isSelectorCall(pass *analysis.Pass, selExpr *ast.SelectorExpr, callObj types.Object) bool {
- sel, ok := pass.TypesInfo.Selections[selExpr]
- if !ok {
- return false
- }
-
- return sel.Obj() == callObj
-}
-
-// isExprHasType returns true if expr has expected type.
-func isExprHasType(pass *analysis.Pass, expr ast.Expr, expType types.Type) bool {
- typeInfo, ok := pass.TypesInfo.Types[expr]
- if !ok {
- return false
- }
-
- return types.Identical(typeInfo.Type, expType)
-}
-
-// findSelectorDeclaration returns function declaration called by selector expression.
-func findSelectorDeclaration(pass *analysis.Pass, expr *ast.SelectorExpr) *ast.FuncDecl {
- xsel, ok := pass.TypesInfo.Selections[expr]
- if !ok {
- return nil
- }
-
- for _, file := range pass.Files {
- for _, decl := range file.Decls {
- fd, ok := decl.(*ast.FuncDecl)
- if ok && fd.Recv != nil && len(fd.Recv.List) == 1 {
- recvType, ok := fd.Recv.List[0].Type.(*ast.Ident)
- if !ok {
- continue
- }
-
- recvObj, ok := pass.TypesInfo.Uses[recvType]
- if !ok {
- continue
- }
-
- if !(types.Identical(recvObj.Type(), xsel.Recv())) {
- continue
- }
-
- if fd.Name.Name == expr.Sel.Name {
- return fd
- }
- }
- }
- }
-
- return nil
-}
-
-// findFunctionDeclaration returns function declaration called by identity.
-func findFunctionDeclaration(pass *analysis.Pass, ident *ast.Ident) *ast.FuncDecl {
- if ident.Obj != nil {
- if funObjDecl, ok := ident.Obj.Decl.(*ast.FuncDecl); ok {
- return funObjDecl
- }
- }
-
- obj := pass.TypesInfo.ObjectOf(ident)
- if obj == nil {
- return nil
- }
-
- for _, file := range pass.Files {
- for _, decl := range file.Decls {
- funcDecl, ok := decl.(*ast.FuncDecl)
- if !ok {
- continue
- }
-
- if funcDecl.Name.Pos() == obj.Pos() {
- return funcDecl
- }
- }
- }
-
- return nil
-}
diff --git a/vendor/github.com/kulti/thelper/pkg/analyzer/report.go b/vendor/github.com/kulti/thelper/pkg/analyzer/report.go
deleted file mode 100644
index 4a23e36d5..000000000
--- a/vendor/github.com/kulti/thelper/pkg/analyzer/report.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package analyzer
-
-import (
- "go/token"
-
- "golang.org/x/tools/go/analysis"
-)
-
-type reports struct {
- reports []report
- filter map[token.Pos]struct{}
- nofilter map[token.Pos]struct{}
-}
-
-type report struct {
- pos token.Pos
- format string
- args []interface{}
-}
-
-func (rr *reports) Reportf(pos token.Pos, format string, args ...interface{}) {
- rr.reports = append(rr.reports, report{
- pos: pos,
- format: format,
- args: args,
- })
-}
-
-func (rr *reports) Filter(pos token.Pos) {
- if pos.IsValid() {
- if rr.filter == nil {
- rr.filter = make(map[token.Pos]struct{})
- }
- rr.filter[pos] = struct{}{}
- }
-}
-
-func (rr *reports) NoFilter(pos token.Pos) {
- if pos.IsValid() {
- if rr.nofilter == nil {
- rr.nofilter = make(map[token.Pos]struct{})
- }
- rr.nofilter[pos] = struct{}{}
- }
-}
-
-func (rr reports) Flush(pass *analysis.Pass) {
- for _, r := range rr.reports {
- if _, ok := rr.filter[r.pos]; ok {
- if _, ok := rr.nofilter[r.pos]; !ok {
- continue
- }
- }
- pass.Reportf(r.pos, r.format, r.args...)
- }
-}