Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions go/tools/builders/nogo_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,12 @@ func (act *action) execOnce() {
act.pass = pass

var err error
defer func() {
if r := recover(); r != nil {
// If the analyzer panics, we catch it here and return an error.
act.err = fmt.Errorf("panic: %v", r)
}
}()
if !act.pkg.illTyped || pass.Analyzer.RunDespiteErrors {
act.result, err = pass.Analyzer.Run(pass)
if err == nil {
Expand Down
70 changes: 68 additions & 2 deletions tests/core/nogo/custom/custom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ nogo(
":importfmt",
":visibility",
":cgogen",
":panicalyzer",
],
# config = "",
visibility = ["//visibility:public"],
Expand Down Expand Up @@ -80,6 +81,14 @@ go_library(
visibility = ["//visibility:public"],
)

go_library(
name = "panicalyzer",
srcs = ["panicalyzer.go"],
importpath = "panicalyzer",
deps = ["@org_golang_x_tools//go/analysis"],
visibility = ["//visibility:public"],
)

go_library(
name = "has_errors",
srcs = ["has_errors.go"],
Expand Down Expand Up @@ -130,6 +139,12 @@ go_binary(
pure = "on",
)

go_library(
name = "panics",
srcs = ["panics.go"],
importpath = "panics",
)

-- foofuncname.go --
// foofuncname checks for functions named "Foo".
// It has the same package name as another check to test the checks with
Expand Down Expand Up @@ -336,6 +351,40 @@ func run(pass *analysis.Pass) (interface{}, error) {
return nil, nil
}

-- panicalyzer.go --
// panicalyzer panics on functions named "ShouldPanic".
package panicalyzer

import (
"go/ast"

"golang.org/x/tools/go/analysis"
)

const doc = "panic on functions named \"ShouldPanic\""

var Analyzer = &analysis.Analyzer{
Name: "panicalyzer",
Run: run,
Doc: doc,
}

func run(pass *analysis.Pass) (interface{}, error) {
for _, f := range pass.Files {
ast.Inspect(f, func(n ast.Node) bool {
switch n := n.(type) {
case *ast.FuncDecl:
if n.Name.Name == "ShouldPanic" {
panic("function must not be named ShouldPanic")
}
return true
}
return true
})
}
return nil, nil
}

-- config.json --
{
"importfmt": {
Expand Down Expand Up @@ -368,6 +417,10 @@ func run(pass *analysis.Pass) (interface{}, error) {
"foofuncname": {
"description": "no exemptions since we know this check is 100% accurate, so override base config",
"exclude_files": {}
},
"panicalyzer": {
"description": "no exemptions",
"exclude_files": {}
}
}

Expand Down Expand Up @@ -402,6 +455,12 @@ func Foo() bool { // This should fail foofuncname
return true
}

-- panics.go --
package panics

func ShouldPanic() {
}

-- no_errors.go --
// package noerrors contains no analyzer errors.
package noerrors
Expand Down Expand Up @@ -459,7 +518,7 @@ func Test(t *testing.T) {
desc, config, target string
wantSuccess bool
includes, excludes []string
bazelArgs []string
bazelArgs []string
}{
{
desc: "default_config",
Expand Down Expand Up @@ -530,7 +589,7 @@ func Test(t *testing.T) {
target: "//:type_check_fail",
wantSuccess: false,
includes: []string{
"4 analyzers skipped due to type-checking error: type_check_fail.go:8:10:",
"\\d analyzers skipped due to type-checking error: type_check_fail.go:8:10:",
},
// Ensure that nogo runs even though compilation fails
bazelArgs: []string{"--keep_going"},
Expand All @@ -543,6 +602,13 @@ func Test(t *testing.T) {
desc: "uses_cgo_clean",
target: "//:uses_cgo_clean",
wantSuccess: true,
}, {
desc: "panics",
target: "//:panics",
wantSuccess: false,
includes: []string{
"panic: function must not be named ShouldPanic",
},
},
} {
t.Run(test.desc, func(t *testing.T) {
Expand Down