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