1
2
3
4
5 package testinggoroutine
6
7 import (
8 "go/ast"
9 "go/types"
10
11 "golang.org/x/tools/go/ast/astutil"
12 "golang.org/x/tools/internal/typeparams"
13 )
14
15
16
17
18 func localFunctionDecls(info *types.Info, files []*ast.File) func(*types.Func) *ast.FuncDecl {
19 var fnDecls map[*types.Func]*ast.FuncDecl
20 return func(f *types.Func) *ast.FuncDecl {
21 if f != nil && fnDecls == nil {
22 fnDecls = make(map[*types.Func]*ast.FuncDecl)
23 for _, file := range files {
24 for _, decl := range file.Decls {
25 if fnDecl, ok := decl.(*ast.FuncDecl); ok {
26 if fn, ok := info.Defs[fnDecl.Name].(*types.Func); ok {
27 fnDecls[fn] = fnDecl
28 }
29 }
30 }
31 }
32 }
33
34 return fnDecls[f]
35 }
36 }
37
38
39
40 func isMethodNamed(f *types.Func, pkgPath string, names ...string) bool {
41 if f == nil {
42 return false
43 }
44 if f.Pkg() == nil || f.Pkg().Path() != pkgPath {
45 return false
46 }
47 if f.Type().(*types.Signature).Recv() == nil {
48 return false
49 }
50 for _, n := range names {
51 if f.Name() == n {
52 return true
53 }
54 }
55 return false
56 }
57
58 func funcIdent(fun ast.Expr) *ast.Ident {
59 switch fun := astutil.Unparen(fun).(type) {
60 case *ast.IndexExpr, *ast.IndexListExpr:
61 x, _, _, _ := typeparams.UnpackIndexExpr(fun)
62 id, _ := x.(*ast.Ident)
63 return id
64 case *ast.Ident:
65 return fun
66 default:
67 return nil
68 }
69 }
70
71
72
73
74 func funcLitInScope(id *ast.Ident) *ast.FuncLit {
75
76 if id.Obj == nil {
77 return nil
78 }
79 var rhs ast.Expr
80 switch d := id.Obj.Decl.(type) {
81 case *ast.AssignStmt:
82 for i, x := range d.Lhs {
83 if ident, isIdent := x.(*ast.Ident); isIdent && ident.Name == id.Name && i < len(d.Rhs) {
84 rhs = d.Rhs[i]
85 }
86 }
87 case *ast.ValueSpec:
88 for i, n := range d.Names {
89 if n.Name == id.Name && i < len(d.Values) {
90 rhs = d.Values[i]
91 }
92 }
93 }
94 lit, _ := rhs.(*ast.FuncLit)
95 return lit
96 }
97
View as plain text