Я пытаюсь найти вызовы функций func
s, которые имеют context.Context
в качестве первого параметра.
Я смог сделать то, что показано ниже, но я застрял в получении базового введите от *types.Named
. Как я могу это сделать?
package main
import (
"bytes"
"context"
"fmt"
"go/ast"
"go/printer"
"go/token"
"go/types"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/singlechecker"
)
var Analyzer = &analysis.Analyzer{
Name: "addlint",
Doc: "reports integer additions",
Run: run,
}
func main() {
singlechecker.Main(Analyzer)
}
func funcHasContextContextAsFirstParam(pass *analysis.Pass, expr ast.Expr) bool {
t := pass.TypesInfo.TypeOf(expr)
if t == nil {
return false
}
bt, ok := t.Underlying().(*types.Signature)
if !ok {
return false
}
fmt.Printf("signature: %+v - %T\n", bt, bt)
params := bt.Params()
for i := 0; i < params.Len(); i++ {
v := params.At(i)
fmt.Printf("Type : %T\n", v.Type())
if named, ok := v.Type().(*types.Named); ok {
// fmt.Printf("named : %v - %T\n", named.Obj(), named.Obj())
fmt.Printf("named : %T\n", named)
fmt.Printf("named.Obj() : %T\n", named.Obj())
typ := named.Underlying()
fmt.Printf("typ: %T\n", typ.Underlying())
if _, ok = typ.(context.Context); ok {
fmt.Printf("context.Context type!\n")
}
}
}
return true
}
func run(pass *analysis.Pass) (interface{}, error) {
for _, file := range pass.Files {
ast.Inspect(file, func(n ast.Node) bool {
be, ok := n.(*ast.CallExpr)
if !ok {
return true
}
fmt.Printf("call expression %+v\n", be)
funcHasContextContextAsFirstParam(pass, be.Fun)
return true
})
}
return nil, nil
}
Вот вывод, который я получаю:
call expression &{Fun:foo Lparen:6160580 Args:[c 0xc0003c5780 0xc0003c57c0] Ellipsis:0 Rparen:6160596}
signature: func(ctx context.Context, n int, str string) - *types.Signature
Type : *types.Named
named : *types.Named
named.Obj() : *types.TypeName
typ: *types.Interface