Update and fix staticcheck
This commit is contained in:
7
vendor/honnef.co/go/tools/facts/generated.go
vendored
7
vendor/honnef.co/go/tools/facts/generated.go
vendored
@ -19,6 +19,7 @@ const (
|
||||
Goyacc
|
||||
Cgo
|
||||
Stringer
|
||||
ProtocGenGo
|
||||
)
|
||||
|
||||
var (
|
||||
@ -51,10 +52,16 @@ func isGenerated(path string) (Generator, bool) {
|
||||
return Goyacc, true
|
||||
case "by cmd/cgo;":
|
||||
return Cgo, true
|
||||
case "by protoc-gen-go.":
|
||||
return ProtocGenGo, true
|
||||
}
|
||||
if strings.HasPrefix(text, `by "stringer `) {
|
||||
return Stringer, true
|
||||
}
|
||||
if strings.HasPrefix(text, `by goyacc `) {
|
||||
return Goyacc, true
|
||||
}
|
||||
|
||||
return Unknown, true
|
||||
}
|
||||
if bytes.Equal(s, oldCgo) {
|
||||
|
78
vendor/honnef.co/go/tools/facts/purity.go
vendored
78
vendor/honnef.co/go/tools/facts/purity.go
vendored
@ -1,14 +1,13 @@
|
||||
package facts
|
||||
|
||||
import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"reflect"
|
||||
|
||||
"golang.org/x/tools/go/analysis"
|
||||
"honnef.co/go/tools/functions"
|
||||
"honnef.co/go/tools/internal/passes/buildssa"
|
||||
"honnef.co/go/tools/ssa"
|
||||
"honnef.co/go/tools/internal/passes/buildir"
|
||||
"honnef.co/go/tools/ir"
|
||||
)
|
||||
|
||||
type IsPure struct{}
|
||||
@ -22,7 +21,7 @@ var Purity = &analysis.Analyzer{
|
||||
Name: "fact_purity",
|
||||
Doc: "Mark pure functions",
|
||||
Run: purity,
|
||||
Requires: []*analysis.Analyzer{buildssa.Analyzer},
|
||||
Requires: []*analysis.Analyzer{buildir.Analyzer},
|
||||
FactTypes: []analysis.Fact{(*IsPure)(nil)},
|
||||
ResultType: reflect.TypeOf(PurityResult{}),
|
||||
}
|
||||
@ -56,65 +55,68 @@ var pureStdlib = map[string]struct{}{
|
||||
}
|
||||
|
||||
func purity(pass *analysis.Pass) (interface{}, error) {
|
||||
seen := map[*ssa.Function]struct{}{}
|
||||
ssapkg := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).Pkg
|
||||
var check func(ssafn *ssa.Function) (ret bool)
|
||||
check = func(ssafn *ssa.Function) (ret bool) {
|
||||
if ssafn.Object() == nil {
|
||||
seen := map[*ir.Function]struct{}{}
|
||||
irpkg := pass.ResultOf[buildir.Analyzer].(*buildir.IR).Pkg
|
||||
var check func(fn *ir.Function) (ret bool)
|
||||
check = func(fn *ir.Function) (ret bool) {
|
||||
if fn.Object() == nil {
|
||||
// TODO(dh): support closures
|
||||
return false
|
||||
}
|
||||
if pass.ImportObjectFact(ssafn.Object(), new(IsPure)) {
|
||||
if pass.ImportObjectFact(fn.Object(), new(IsPure)) {
|
||||
return true
|
||||
}
|
||||
if ssafn.Pkg != ssapkg {
|
||||
if fn.Pkg != irpkg {
|
||||
// Function is in another package but wasn't marked as
|
||||
// pure, ergo it isn't pure
|
||||
return false
|
||||
}
|
||||
// Break recursion
|
||||
if _, ok := seen[ssafn]; ok {
|
||||
if _, ok := seen[fn]; ok {
|
||||
return false
|
||||
}
|
||||
|
||||
seen[ssafn] = struct{}{}
|
||||
seen[fn] = struct{}{}
|
||||
defer func() {
|
||||
if ret {
|
||||
pass.ExportObjectFact(ssafn.Object(), &IsPure{})
|
||||
pass.ExportObjectFact(fn.Object(), &IsPure{})
|
||||
}
|
||||
}()
|
||||
|
||||
if functions.IsStub(ssafn) {
|
||||
if functions.IsStub(fn) {
|
||||
return false
|
||||
}
|
||||
|
||||
if _, ok := pureStdlib[ssafn.Object().(*types.Func).FullName()]; ok {
|
||||
if _, ok := pureStdlib[fn.Object().(*types.Func).FullName()]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
if ssafn.Signature.Results().Len() == 0 {
|
||||
if fn.Signature.Results().Len() == 0 {
|
||||
// A function with no return values is empty or is doing some
|
||||
// work we cannot see (for example because of build tags);
|
||||
// don't consider it pure.
|
||||
return false
|
||||
}
|
||||
|
||||
for _, param := range ssafn.Params {
|
||||
for _, param := range fn.Params {
|
||||
// TODO(dh): this may not be strictly correct. pure code
|
||||
// can, to an extent, operate on non-basic types.
|
||||
if _, ok := param.Type().Underlying().(*types.Basic); !ok {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if ssafn.Blocks == nil {
|
||||
// Don't consider external functions pure.
|
||||
if fn.Blocks == nil {
|
||||
return false
|
||||
}
|
||||
checkCall := func(common *ssa.CallCommon) bool {
|
||||
checkCall := func(common *ir.CallCommon) bool {
|
||||
if common.IsInvoke() {
|
||||
return false
|
||||
}
|
||||
builtin, ok := common.Value.(*ssa.Builtin)
|
||||
builtin, ok := common.Value.(*ir.Builtin)
|
||||
if !ok {
|
||||
if common.StaticCallee() != ssafn {
|
||||
if common.StaticCallee() != fn {
|
||||
if common.StaticCallee() == nil {
|
||||
return false
|
||||
}
|
||||
@ -124,47 +126,47 @@ func purity(pass *analysis.Pass) (interface{}, error) {
|
||||
}
|
||||
} else {
|
||||
switch builtin.Name() {
|
||||
case "len", "cap", "make", "new":
|
||||
case "len", "cap":
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
for _, b := range ssafn.Blocks {
|
||||
for _, b := range fn.Blocks {
|
||||
for _, ins := range b.Instrs {
|
||||
switch ins := ins.(type) {
|
||||
case *ssa.Call:
|
||||
case *ir.Call:
|
||||
if !checkCall(ins.Common()) {
|
||||
return false
|
||||
}
|
||||
case *ssa.Defer:
|
||||
case *ir.Defer:
|
||||
if !checkCall(&ins.Call) {
|
||||
return false
|
||||
}
|
||||
case *ssa.Select:
|
||||
case *ir.Select:
|
||||
return false
|
||||
case *ssa.Send:
|
||||
case *ir.Send:
|
||||
return false
|
||||
case *ssa.Go:
|
||||
case *ir.Go:
|
||||
return false
|
||||
case *ssa.Panic:
|
||||
case *ir.Panic:
|
||||
return false
|
||||
case *ssa.Store:
|
||||
case *ir.Store:
|
||||
return false
|
||||
case *ssa.FieldAddr:
|
||||
case *ir.FieldAddr:
|
||||
return false
|
||||
case *ir.Alloc:
|
||||
return false
|
||||
case *ir.Load:
|
||||
return false
|
||||
case *ssa.UnOp:
|
||||
if ins.Op == token.MUL || ins.Op == token.AND {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
for _, ssafn := range pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA).SrcFuncs {
|
||||
check(ssafn)
|
||||
for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs {
|
||||
check(fn)
|
||||
}
|
||||
|
||||
out := PurityResult{}
|
||||
|
Reference in New Issue
Block a user