| // Copyright 2023 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Package appends defines an Analyzer that detects | |
| // if there is only one variable in append. | |
| package appends | |
| import ( | |
| _ "embed" | |
| "go/ast" | |
| "go/types" | |
| "golang.org/x/tools/go/analysis" | |
| "golang.org/x/tools/go/analysis/passes/inspect" | |
| "golang.org/x/tools/go/ast/inspector" | |
| "golang.org/x/tools/go/types/typeutil" | |
| "golang.org/x/tools/internal/analysis/analyzerutil" | |
| ) | |
| //go:embed doc.go | |
| var doc string | |
| var Analyzer = &analysis.Analyzer{ | |
| Name: "appends", | |
| Doc: analyzerutil.MustExtractDoc(doc, "appends"), | |
| URL: "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/appends", | |
| Requires: []*analysis.Analyzer{inspect.Analyzer}, | |
| Run: run, | |
| } | |
| func run(pass *analysis.Pass) (any, error) { | |
| inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector) | |
| nodeFilter := []ast.Node{ | |
| (*ast.CallExpr)(nil), | |
| } | |
| inspect.Preorder(nodeFilter, func(n ast.Node) { | |
| call := n.(*ast.CallExpr) | |
| b, ok := typeutil.Callee(pass.TypesInfo, call).(*types.Builtin) | |
| if ok && b.Name() == "append" && len(call.Args) == 1 { | |
| pass.ReportRangef(call, "append with no values") | |
| } | |
| }) | |
| return nil, nil | |
| } |