mirror of
https://github.com/sharkdp/bat.git
synced 2024-11-30 03:33:54 +01:00
82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
|
// The hugeparam command identifies by-value parameters that are larger than n bytes.
|
||
|
//
|
||
|
// Example:
|
||
|
// $ ./hugeparams encoding/xml
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"flag"
|
||
|
"fmt"
|
||
|
"go/ast"
|
||
|
"go/token"
|
||
|
"go/types"
|
||
|
"log"
|
||
|
|
||
|
"golang.org/x/tools/go/loader"
|
||
|
)
|
||
|
|
||
|
//!+
|
||
|
var bytesFlag = flag.Int("bytes", 48, "maximum parameter size in bytes")
|
||
|
|
||
|
var sizeof = (&types.StdSizes{8, 8}).Sizeof // the sizeof function
|
||
|
|
||
|
func PrintHugeParams(fset *token.FileSet, info *types.Info, files []*ast.File) {
|
||
|
checkTuple := func(descr string, tuple *types.Tuple) {
|
||
|
for i := 0; i < tuple.Len(); i++ {
|
||
|
v := tuple.At(i)
|
||
|
if sz := sizeof(v.Type()); sz > int64(*bytesFlag) {
|
||
|
fmt.Printf("%s: %q %s: %s = %d bytes\n",
|
||
|
fset.Position(v.Pos()),
|
||
|
v.Name(), descr, v.Type(), sz)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
checkSig := func(sig *types.Signature) {
|
||
|
checkTuple("parameter", sig.Params())
|
||
|
checkTuple("result", sig.Results())
|
||
|
}
|
||
|
for _, file := range files {
|
||
|
ast.Inspect(file, func(n ast.Node) bool {
|
||
|
switch n := n.(type) {
|
||
|
case *ast.FuncDecl:
|
||
|
checkSig(info.Defs[n.Name].Type().(*types.Signature))
|
||
|
case *ast.FuncLit:
|
||
|
checkSig(info.Types[n.Type].Type.(*types.Signature))
|
||
|
}
|
||
|
return true
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//!-
|
||
|
|
||
|
func main() {
|
||
|
flag.Parse()
|
||
|
|
||
|
// The loader loads a complete Go program from source code.
|
||
|
var conf loader.Config
|
||
|
_, err := conf.FromArgs(flag.Args(), false)
|
||
|
if err != nil {
|
||
|
log.Fatal(err) // command syntax error
|
||
|
}
|
||
|
lprog, err := conf.Load()
|
||
|
if err != nil {
|
||
|
log.Fatal(err) // load error
|
||
|
}
|
||
|
|
||
|
for _, info := range lprog.InitialPackages() {
|
||
|
PrintHugeParams(lprog.Fset, &info.Info, info.Files)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
//!+output
|
||
|
% ./hugeparam encoding/xml
|
||
|
/go/src/encoding/xml/marshal.go:167:50: "start" parameter: encoding/xml.StartElement = 56 bytes
|
||
|
/go/src/encoding/xml/marshal.go:734:97: "" result: encoding/xml.StartElement = 56 bytes
|
||
|
/go/src/encoding/xml/marshal.go:761:51: "start" parameter: encoding/xml.StartElement = 56 bytes
|
||
|
/go/src/encoding/xml/marshal.go:781:68: "start" parameter: encoding/xml.StartElement = 56 bytes
|
||
|
/go/src/encoding/xml/xml.go:72:30: "" result: encoding/xml.StartElement = 56 bytes
|
||
|
//!-output
|
||
|
*/
|