1
0
mirror of https://github.com/golang/go synced 2024-11-18 10:24:42 -07:00

cmd: add a new analyzer for check missing values after append

If there is no second parameter added during append, there will be no prompt when executing go vet. Add an analyzer to detect this situation

Update #60448

Change-Id: If9848835424f310c54e3e9377aaaad4a1516871a
Reviewed-on: https://go-review.googlesource.com/c/go/+/498416
Run-TryBot: shuang cui <imcusg@gmail.com>
Run-TryBot: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Matloob <matloob@golang.org>
Reviewed-by: Tim King <taking@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
cui fliter 2023-05-26 12:02:54 +08:00 committed by Tim King
parent e9379a8f8b
commit dc523c8ddf
7 changed files with 86 additions and 0 deletions

View File

@ -40,6 +40,7 @@ var passFlagToTest = map[string]bool{
}
var passAnalyzersToVet = map[string]bool{
"appends": true,
"asmdecl": true,
"assign": true,
"atomic": true,

View File

@ -0,0 +1,49 @@
// 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/analysis/passes/internal/analysisutil"
"golang.org/x/tools/go/ast/inspector"
)
//go:embed doc.go
var doc string
var Analyzer = &analysis.Analyzer{
Name: "appends",
Doc: analysisutil.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) (interface{}, 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)
if ident, ok := call.Fun.(*ast.Ident); ok && ident.Name == "append" {
if _, ok := pass.TypesInfo.Uses[ident].(*types.Builtin); ok {
if len(call.Args) == 1 {
pass.ReportRangef(call, "append with no values")
}
}
}
})
return nil, nil
}

View File

@ -0,0 +1,20 @@
// 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.
//
// # Analyzer appends
//
// appends: check for missing values after append
//
// This checker reports calls to append that pass
// no values to be appended to the slice.
//
// s := []string{"a", "b", "c"}
// _ = append(s)
//
// Such calls are always no-ops and often indicate an
// underlying mistake.
package appends

View File

@ -52,6 +52,7 @@ golang.org/x/tools/cmd/bisect
golang.org/x/tools/cover
golang.org/x/tools/go/analysis
golang.org/x/tools/go/analysis/internal/analysisflags
golang.org/x/tools/go/analysis/passes/appends
golang.org/x/tools/go/analysis/passes/asmdecl
golang.org/x/tools/go/analysis/passes/assign
golang.org/x/tools/go/analysis/passes/atomic

View File

@ -9,6 +9,7 @@ import (
"golang.org/x/tools/go/analysis/unitchecker"
"golang.org/x/tools/go/analysis/passes/appends"
"golang.org/x/tools/go/analysis/passes/asmdecl"
"golang.org/x/tools/go/analysis/passes/assign"
"golang.org/x/tools/go/analysis/passes/atomic"
@ -46,6 +47,7 @@ func main() {
objabi.AddVersionFlag()
unitchecker.Main(
appends.Analyzer,
asmdecl.Analyzer,
assign.Analyzer,
atomic.Analyzer,

12
src/cmd/vet/testdata/appends/appends.go vendored Normal file
View File

@ -0,0 +1,12 @@
// 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.
// This file contains tests for the appends checker.
package appends
func AppendsTest() {
sli := []string{"a", "b", "c"}
sli = append(sli) // ERROR "append with no values"
}

View File

@ -62,6 +62,7 @@ func vetCmd(t *testing.T, arg, pkg string) *exec.Cmd {
func TestVet(t *testing.T) {
t.Parallel()
for _, pkg := range []string{
"appends",
"asm",
"assign",
"atomic",