Revamp the build system to be more inline with other Prometheus exporters. Notably add Darwin and Windows build targets, and add support for releases using tar files.
94 lines
2.4 KiB
Go
94 lines
2.4 KiB
Go
// Copyright 2015 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 defines the check for unused results of calls to certain
|
|
// pure functions.
|
|
|
|
package main
|
|
|
|
import (
|
|
"flag"
|
|
"go/ast"
|
|
"go/token"
|
|
"go/types"
|
|
"strings"
|
|
)
|
|
|
|
var unusedFuncsFlag = flag.String("unusedfuncs",
|
|
"errors.New,fmt.Errorf,fmt.Sprintf,fmt.Sprint,sort.Reverse",
|
|
"comma-separated list of functions whose results must be used")
|
|
|
|
var unusedStringMethodsFlag = flag.String("unusedstringmethods",
|
|
"Error,String",
|
|
"comma-separated list of names of methods of type func() string whose results must be used")
|
|
|
|
func init() {
|
|
register("unusedresult",
|
|
"check for unused result of calls to functions in -unusedfuncs list and methods in -unusedstringmethods list",
|
|
checkUnusedResult,
|
|
exprStmt)
|
|
}
|
|
|
|
// func() string
|
|
var sigNoArgsStringResult = types.NewSignature(nil, nil,
|
|
types.NewTuple(types.NewVar(token.NoPos, nil, "", types.Typ[types.String])),
|
|
false)
|
|
|
|
var unusedFuncs = make(map[string]bool)
|
|
var unusedStringMethods = make(map[string]bool)
|
|
|
|
func initUnusedFlags() {
|
|
commaSplit := func(s string, m map[string]bool) {
|
|
if s != "" {
|
|
for _, name := range strings.Split(s, ",") {
|
|
if len(name) == 0 {
|
|
flag.Usage()
|
|
}
|
|
m[name] = true
|
|
}
|
|
}
|
|
}
|
|
commaSplit(*unusedFuncsFlag, unusedFuncs)
|
|
commaSplit(*unusedStringMethodsFlag, unusedStringMethods)
|
|
}
|
|
|
|
func checkUnusedResult(f *File, n ast.Node) {
|
|
call, ok := unparen(n.(*ast.ExprStmt).X).(*ast.CallExpr)
|
|
if !ok {
|
|
return // not a call statement
|
|
}
|
|
fun := unparen(call.Fun)
|
|
|
|
if f.pkg.types[fun].IsType() {
|
|
return // a conversion, not a call
|
|
}
|
|
|
|
selector, ok := fun.(*ast.SelectorExpr)
|
|
if !ok {
|
|
return // neither a method call nor a qualified ident
|
|
}
|
|
|
|
sel, ok := f.pkg.selectors[selector]
|
|
if ok && sel.Kind() == types.MethodVal {
|
|
// method (e.g. foo.String())
|
|
obj := sel.Obj().(*types.Func)
|
|
sig := sel.Type().(*types.Signature)
|
|
if types.Identical(sig, sigNoArgsStringResult) {
|
|
if unusedStringMethods[obj.Name()] {
|
|
f.Badf(call.Lparen, "result of (%s).%s call not used",
|
|
sig.Recv().Type(), obj.Name())
|
|
}
|
|
}
|
|
} else if !ok {
|
|
// package-qualified function (e.g. fmt.Errorf)
|
|
obj, _ := f.pkg.uses[selector.Sel]
|
|
if obj, ok := obj.(*types.Func); ok {
|
|
qname := obj.Pkg().Path() + "." + obj.Name()
|
|
if unusedFuncs[qname] {
|
|
f.Badf(call.Lparen, "result of %v call not used", qname)
|
|
}
|
|
}
|
|
}
|
|
}
|