shad-go/lectures/11-analysis/jokelint/analysis.go

57 lines
1 KiB
Go
Raw Normal View History

2021-04-27 18:37:22 +00:00
package jokelint
import (
"go/ast"
"go/constant"
"go/types"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/ast/inspector"
)
var Analyzer = &analysis.Analyzer{
Name: "jokelint",
Doc: "check for outdated jokes about go",
Run: run,
}
func run(pass *analysis.Pass) (interface{}, error) {
ins := inspector.New(pass.Files)
// We filter only function calls.
nodeFilter := []ast.Node{
(*ast.CallExpr)(nil),
}
ins.Preorder(nodeFilter, func(n ast.Node) {
call := n.(*ast.CallExpr)
visitCall(pass, call)
})
return nil, nil
}
func visitCall(pass *analysis.Pass, call *ast.CallExpr) {
fn, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return
}
def := pass.TypesInfo.Uses[fn.Sel]
if x, ok := def.(*types.Func); !ok {
return
} else if x.Pkg().Path() != "fmt" || x.Name() != "Println" {
return
}
if len(call.Args) != 1 {
return
}
arg := call.Args[0]
argTyp := pass.TypesInfo.Types[arg]
if argTyp.Value != nil && constant.StringVal(argTyp.Value) == "lol no generics" {
pass.Reportf(call.Pos(), "outdated joke")
}
}