diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-07-04 11:12:55 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-07-04 15:05:30 +0200 |
| commit | c7d7f10bdff703e4a3c0414e8a33d4e45c91eb35 (patch) | |
| tree | 0dff0ee1f98dbfa3ad8776112053a450d176592b /vendor/github.com/golangci/check/cmd/varcheck | |
| parent | 9573094ce235bd9afe88f5da27a47dd6bcc1e13b (diff) | |
go.mod: vendor golangci-lint
Diffstat (limited to 'vendor/github.com/golangci/check/cmd/varcheck')
| -rw-r--r-- | vendor/github.com/golangci/check/cmd/varcheck/varcheck.go | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/vendor/github.com/golangci/check/cmd/varcheck/varcheck.go b/vendor/github.com/golangci/check/cmd/varcheck/varcheck.go new file mode 100644 index 000000000..8e93e0473 --- /dev/null +++ b/vendor/github.com/golangci/check/cmd/varcheck/varcheck.go @@ -0,0 +1,163 @@ +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package varcheck + +import ( + "flag" + "go/ast" + "go/token" + "strings" + + "go/types" + + "golang.org/x/tools/go/loader" +) + +var ( + buildTags = flag.String("varcheck.tags", "", "Build tags") +) + +type object struct { + pkgPath string + name string +} + +type visitor struct { + prog *loader.Program + pkg *loader.PackageInfo + uses map[object]int + positions map[object]token.Position + insideFunc bool +} + +func getKey(obj types.Object) object { + if obj == nil { + return object{} + } + + pkg := obj.Pkg() + pkgPath := "" + if pkg != nil { + pkgPath = pkg.Path() + } + + return object{ + pkgPath: pkgPath, + name: obj.Name(), + } +} + +func (v *visitor) decl(obj types.Object) { + key := getKey(obj) + if _, ok := v.uses[key]; !ok { + v.uses[key] = 0 + } + if _, ok := v.positions[key]; !ok { + v.positions[key] = v.prog.Fset.Position(obj.Pos()) + } +} + +func (v *visitor) use(obj types.Object) { + key := getKey(obj) + if _, ok := v.uses[key]; ok { + v.uses[key]++ + } else { + v.uses[key] = 1 + } +} + +func isReserved(name string) bool { + return name == "_" || strings.HasPrefix(strings.ToLower(name), "_cgo_") +} + +func (v *visitor) Visit(node ast.Node) ast.Visitor { + switch node := node.(type) { + case *ast.Ident: + v.use(v.pkg.Info.Uses[node]) + + case *ast.ValueSpec: + if !v.insideFunc { + for _, ident := range node.Names { + if !isReserved(ident.Name) { + v.decl(v.pkg.Info.Defs[ident]) + } + } + } + for _, val := range node.Values { + ast.Walk(v, val) + } + if node.Type != nil { + ast.Walk(v, node.Type) + } + return nil + + case *ast.FuncDecl: + if node.Body != nil { + v.insideFunc = true + ast.Walk(v, node.Body) + v.insideFunc = false + } + + if node.Recv != nil { + ast.Walk(v, node.Recv) + } + if node.Type != nil { + ast.Walk(v, node.Type) + } + + return nil + } + + return v +} + +type Issue struct { + Pos token.Position + VarName string +} + +func Run(program *loader.Program, reportExported bool) []Issue { + var issues []Issue + uses := make(map[object]int) + positions := make(map[object]token.Position) + + for _, pkgInfo := range program.InitialPackages() { + if pkgInfo.Pkg.Path() == "unsafe" { + continue + } + + v := &visitor{ + prog: program, + pkg: pkgInfo, + uses: uses, + positions: positions, + } + + for _, f := range v.pkg.Files { + ast.Walk(v, f) + } + } + + for obj, useCount := range uses { + if useCount == 0 && (reportExported || !ast.IsExported(obj.name)) { + pos := positions[obj] + issues = append(issues, Issue{ + Pos: pos, + VarName: obj.name, + }) + } + } + + return issues +} |
