aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2023-05-15 22:01:00 +0200
committerTeddy Wing2023-05-15 22:01:00 +0200
commite4441d0d2e003d5a4adafc9a9aaa037b3be830b8 (patch)
tree7382c71a8f2ec573da1e2d94fbd956dd5e349c9d
parenta3515d6d5d52a84944b5bd0aaa863a50b3c1ec59 (diff)
downloadgocapturedrefrace-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.go43
-rw-r--r--testdata/simple.go4
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)
}