56 lines
1.4 KiB
Go
56 lines
1.4 KiB
Go
package analyzer
|
|
|
|
import (
|
|
"flag"
|
|
"go/ast"
|
|
|
|
"golang.org/x/tools/go/analysis"
|
|
"golang.org/x/tools/go/analysis/passes/inspect"
|
|
"golang.org/x/tools/go/ast/inspector"
|
|
)
|
|
|
|
var Analyzer = &analysis.Analyzer{
|
|
Name: "explicitreturn",
|
|
Doc: "Enforces explicit return statements",
|
|
Flags: flag.FlagSet{},
|
|
Run: run,
|
|
Requires: []*analysis.Analyzer{inspect.Analyzer},
|
|
}
|
|
|
|
func run(pass *analysis.Pass) (interface{}, error) {
|
|
inspector := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
|
|
|
|
// only filter function defintions
|
|
nodeFilter := []ast.Node{
|
|
(*ast.FuncDecl)(nil),
|
|
(*ast.FuncLit)(nil),
|
|
}
|
|
|
|
inspector.Preorder(nodeFilter, func(node ast.Node) {
|
|
var funcBody *ast.BlockStmt
|
|
|
|
switch function := node.(type) {
|
|
case *ast.FuncLit:
|
|
funcBody = function.Body
|
|
for _, statement := range funcBody.List {
|
|
returnStmt, ok := statement.(*ast.ReturnStmt)
|
|
if ok && returnStmt.Results == nil && function.Type.Results != nil {
|
|
pass.ReportRangef(returnStmt, "implicit return found in anonymous function")
|
|
}
|
|
}
|
|
case *ast.FuncDecl:
|
|
funcBody = function.Body
|
|
for _, statement := range funcBody.List {
|
|
returnStmt, ok := statement.(*ast.ReturnStmt)
|
|
if ok && returnStmt.Results == nil && function.Type.Results != nil {
|
|
pass.ReportRangef(returnStmt, "implicit return found in function %s", function.Name)
|
|
}
|
|
}
|
|
default:
|
|
return
|
|
}
|
|
})
|
|
|
|
return nil, nil
|
|
}
|