diff options
-rw-r--r-- | gocapturedrefrace.go | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/gocapturedrefrace.go b/gocapturedrefrace.go index cdc6486..3f776e0 100644 --- a/gocapturedrefrace.go +++ b/gocapturedrefrace.go @@ -85,13 +85,12 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { // Get the closure's scope. funcScope := pass.TypesInfo.Scopes[funcLit.Type] + localAssignments := checkShadowing(pass, funcLit) + fmt.Printf("localAssignments: %#v\n", localAssignments) + ast.Inspect( funcLit, func(node ast.Node) bool { - if isShadowingDeclaration(pass, node, funcScope) { - return true - } - ident, ok := node.(*ast.Ident) if !ok { return true @@ -101,6 +100,13 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { return true } + // Ignore shadowed variables. + for _, localAssignmentIdent := range localAssignments { + if ident == localAssignmentIdent { + return true + } + } + // Find out whether `ident` was defined in an outer scope. scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) @@ -140,43 +146,52 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) { } // TODO: doc -func isShadowingDeclaration( +func checkShadowing( pass *analysis.Pass, - node ast.Node, - funcScope *types.Scope, -) bool { + funcLit *ast.FuncLit, + // funcScope *types.Scope, +) (localAssignments []*ast.Ident) { // TODO: Plan: Change this function to checkShadowing. Call ast.Inspect and build a list of local assignments in the closure. Then in checkClosure, ignore objects in the local assignments list. - assignStmt, ok := node.(*ast.AssignStmt) - if !ok { - return false - } + localAssignments = []*ast.Ident{} - if assignStmt.Tok != token.DEFINE { - return false - } + ast.Inspect( + funcLit, + func(node ast.Node) bool { + assignStmt, ok := node.(*ast.AssignStmt) + if !ok { + return true + } - for _, lhs := range assignStmt.Lhs { - ident, ok := lhs.(*ast.Ident) - if !ok { - return false - } - fmt.Printf("assignStmt: %#v\n", ident) - - if ident == nil { - return false - } - - return true - - // TODO: If ident is in parent, ignore it an move on. - // scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) - // - // // Identifier is local to the closure. - // if scope == nil && scopeObj == nil { - // return - // } - } + if assignStmt.Tok != token.DEFINE { + return true + } + + for _, lhs := range assignStmt.Lhs { + ident, ok := lhs.(*ast.Ident) + if !ok { + return true + } + fmt.Printf("assignStmt: %#v\n", ident) + + if ident == nil { + return true + } + + localAssignments = append(localAssignments, ident) + + // TODO: If ident is in parent, ignore it an move on. + // scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) + // + // // Identifier is local to the closure. + // if scope == nil && scopeObj == nil { + // return + // } + } + + return true + }, + ) - return false + return localAssignments } |