1
2
3
4
5 package testinggoroutine
6
7 import (
8 "go/ast"
9 "go/types"
10 "slices"
11 )
12
13
14
15
16 func localFunctionDecls(info *types.Info, files []*ast.File) func(*types.Func) *ast.FuncDecl {
17 var fnDecls map[*types.Func]*ast.FuncDecl
18 return func(f *types.Func) *ast.FuncDecl {
19 if f != nil && fnDecls == nil {
20 fnDecls = make(map[*types.Func]*ast.FuncDecl)
21 for _, file := range files {
22 for _, decl := range file.Decls {
23 if fnDecl, ok := decl.(*ast.FuncDecl); ok {
24 if fn, ok := info.Defs[fnDecl.Name].(*types.Func); ok {
25 fnDecls[fn] = fnDecl
26 }
27 }
28 }
29 }
30 }
31
32 return fnDecls[f]
33 }
34 }
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 return slices.Contains(names, f.Name())
51 }
52
53
54
55
56 func funcLitInScope(id *ast.Ident) *ast.FuncLit {
57
58 if id.Obj == nil {
59 return nil
60 }
61 var rhs ast.Expr
62 switch d := id.Obj.Decl.(type) {
63 case *ast.AssignStmt:
64 for i, x := range d.Lhs {
65 if ident, isIdent := x.(*ast.Ident); isIdent && ident.Name == id.Name && i < len(d.Rhs) {
66 rhs = d.Rhs[i]
67 }
68 }
69 case *ast.ValueSpec:
70 for i, n := range d.Names {
71 if n.Name == id.Name && i < len(d.Values) {
72 rhs = d.Values[i]
73 }
74 }
75 }
76 lit, _ := rhs.(*ast.FuncLit)
77 return lit
78 }
79
View as plain text