diff options
author | Teddy Wing | 2023-05-15 22:01:00 +0200 |
---|---|---|
committer | Teddy Wing | 2023-05-15 22:01:00 +0200 |
commit | e4441d0d2e003d5a4adafc9a9aaa037b3be830b8 (patch) | |
tree | 7382c71a8f2ec573da1e2d94fbd956dd5e349c9d | |
parent | a3515d6d5d52a84944b5bd0aaa863a50b3c1ec59 (diff) | |
download | gocapturedrefrace-e4441d0d2e003d5a4adafc9a9aaa037b3be830b8.tar.bz2 |
Try getting `GenDecl`s in closure
Turns out this only gets declarations like:
var decl string
but not:
decl := "a"
Is there a way to get the above one too?
-rw-r--r-- | gocapturedrefrace.go | 43 | ||||
-rw-r--r-- | testdata/simple.go | 4 |
2 files changed, 37 insertions, 10 deletions
diff --git a/gocapturedrefrace.go b/gocapturedrefrace.go index 517cf8e..9430faf 100644 --- a/gocapturedrefrace.go +++ b/gocapturedrefrace.go @@ -5,6 +5,7 @@ import ( "fmt" "go/ast" "go/printer" + "go/token" "golang.org/x/tools/go/analysis" ) @@ -55,12 +56,12 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { for _, field := range funcLit.Type.Params.List { formalParams = append(formalParams, field.Names[0].Obj) } - fmt.Printf("%#v\n", formalParams) + fmt.Printf("formalParams: %#v\n", formalParams) // TODO: Ensure argument types are not references // TODO: Build a list of variables created in the closure assignments := assignmentsInFunc(pass, funcLit) - fmt.Printf("%#v\n", assignments) + fmt.Printf("variable declarations: %#v\n", assignments) // TODO: Use ast.GenDecl instead ast.Inspect( @@ -98,27 +99,49 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { func assignmentsInFunc( pass *analysis.Pass, funcLit *ast.FuncLit, -) []string { - assignments := []string{} +) []*ast.Object { + assignments := []*ast.Object{} ast.Inspect( funcLit, func(node ast.Node) bool { - ident, ok := node.(*ast.Ident) + decl, ok := node.(*ast.GenDecl) if !ok { return true } - if ident.Obj == nil || ident.Obj.Decl == nil { + fmt.Printf("decl: %#v\n", decl) + + if decl.Tok != token.VAR { return true } - _, ok = ident.Obj.Decl.(*ast.AssignStmt) - if !ok { - return true + for _, spec := range decl.Specs { + valueSpec, ok := spec.(*ast.ValueSpec) + if !ok { + return true + } + + fmt.Printf("valueSpec: %#v\n", valueSpec) + + assignments = append(assignments, valueSpec.Names[0].Obj) } - assignments = append(assignments, ident.Name) + // ident, ok := node.(*ast.Ident) + // if !ok { + // return true + // } + // + // if ident.Obj == nil || ident.Obj.Decl == nil { + // return true + // } + // + // _, ok = ident.Obj.Decl.(*ast.AssignStmt) + // if !ok { + // return true + // } + // + // assignments = append(assignments, ident.Name) return true }, diff --git a/testdata/simple.go b/testdata/simple.go index d01a95e..76fb5d5 100644 --- a/testdata/simple.go +++ b/testdata/simple.go @@ -21,6 +21,10 @@ func main() { str := "a" strings.Repeat(str, 3) + + var decl string + decl = "b" + strings.Repeat(decl, 2) }(copied) } |