aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2023-05-16 21:41:49 +0200
committerTeddy Wing2023-05-16 21:41:49 +0200
commitd8e104832a45c6da60a5cada831384fec9558559 (patch)
tree0aa5645c5fbec2e1560da05b0e52935b9efad634
parente90bf2432617a5fca20f2b9fc6332fc0d2bc6979 (diff)
downloadgocapturedrefrace-d8e104832a45c6da60a5cada831384fec9558559.tar.bz2
checkClosure: Clean up old code
* Remove old in-progress code now that we have a working implementation. * Add explanatory comments. * Remove `assignmentsInFunc()` which is unused.
-rw-r--r--gocapturedrefrace.go135
1 files changed, 3 insertions, 132 deletions
diff --git a/gocapturedrefrace.go b/gocapturedrefrace.go
index c4678a3..a28c47b 100644
--- a/gocapturedrefrace.go
+++ b/gocapturedrefrace.go
@@ -1,9 +1,7 @@
package gocapturedrefrace
import (
- "fmt"
"go/ast"
- "go/token"
"go/types"
"golang.org/x/tools/go/analysis"
@@ -65,23 +63,6 @@ func checkClosure(
funcLit *ast.FuncLit,
funcScope *types.Scope,
) {
- formalParams := []*ast.Object{}
- for _, field := range funcLit.Type.Params.List {
- formalParams = append(formalParams, field.Names[0].Obj)
- }
- fmt.Printf("formalParams: %#v\n", formalParams)
- // TODO: Ensure argument types are not references
- // TODO: goStmt.Call.Args should also give us something like this.
-
- // TODO: Build a list of variables created in the closure
- // assignments := assignmentsInFunc(pass, funcLit)
- // fmt.Printf("variable declarations: %#v\n", assignments)
- // TODO: Use ast.GenDecl instead
- // ast.Scope?
-
- // TODO: Need to find variables not declared in the closure, and
- // reference arguments
-
ast.Inspect(
funcLit,
func(node ast.Node) bool {
@@ -94,38 +75,21 @@ func checkClosure(
return true
}
- // TODO: Find out whether ident is a captured reference
- // Maybe check if variable was not assigned or passed as an argument?
-
- // for _, param := range formalParams {
- // if ident.Obj == param {
- // return true
- // }
- // }
-
- // TODO: Use (*types.Scope).LookupParent with ident to find out
- // whether a variable was defined in an outer scope.
+ // Find out whether `ident` was defined in an outer scope.
scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos)
- fmt.Println("LookupParent:")
- fmt.Printf(" scope: %#v\n", scope)
- fmt.Printf(" obj : %#v\n", scopeObj)
- // If scope and scopeObj are nil, then variable is local
-
- // This also means variable is local.
- if funcScope == scope {
- fmt.Printf("In function scope %v\n", scopeObj)
- }
// Identifier is local to the closure.
if scope == nil && scopeObj == nil {
return true
}
+ // Ignore non-variable identifiers.
_, ok = scopeObj.(*types.Var)
if !ok {
return true
}
+ // Identifier was defined in a different scope.
if funcScope != scope {
pass.Reportf(
ident.Pos(),
@@ -134,100 +98,7 @@ func checkClosure(
)
}
- // TODO: Report references in argument list
-
return true
},
)
}
-
-func assignmentsInFunc(
- pass *analysis.Pass,
- funcLit *ast.FuncLit,
-) []string {
- assignments := []string{}
- // ) []*ast.Object {
- // assignments := []*ast.Object{}
-
- ast.Inspect(
- funcLit,
- func(node ast.Node) bool {
- // decl, ok := node.(*ast.GenDecl)
- // if !ok {
- // return true
- // }
- //
- // fmt.Printf("decl: %#v\n", decl)
- //
- // if decl.Tok != token.VAR {
- // 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)
- // }
-
- // decl, ok := node.(*ast.DeclStmt)
- // if !ok {
- // return true
- // }
- //
- // fmt.Printf("decl: %#v\n", decl)
-
- ident, ok := node.(*ast.Ident)
- if !ok {
- return true
- }
-
- if ident.Obj == nil || ident.Obj.Decl == nil {
- return true
- }
-
- assignment, ok := ident.Obj.Decl.(*ast.AssignStmt)
- if !ok {
- return true
- }
-
- // fmt.Printf("assignment: %#v\n", assignment.Tok)
- if assignment.Tok == token.DEFINE {
- fmt.Printf("assignment: %v is DEFINE\n", ident.Name)
- } else if assignment.Tok == token.ASSIGN {
- fmt.Printf("assignment: %v is ASSIGN\n", ident.Name)
- } else {
- fmt.Printf("assignment: %v\n", assignment.Tok)
- }
-
- if pass.TypesInfo.Defs[ident] != nil {
- fmt.Println("DEFINE:", ident)
- } else {
- fmt.Println("ASSIGN:", ident)
- }
-
- obj := pass.TypesInfo.ObjectOf(ident)
- if obj != nil {
- fmt.Printf("obj: %#v\n", obj)
-
- theVar, ok := obj.(*types.Var)
- if !ok {
- return true
- }
-
- fmt.Printf("obj origin: %#v\n", theVar.Origin())
- fmt.Printf("obj parent: %#v\n", theVar.Parent())
- }
-
- assignments = append(assignments, ident.Name)
-
- return true
- },
- )
-
- return assignments
-}