From 50faa40e7d2f0504794523ffb480bc88ea968aaf Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Sun, 21 May 2023 00:41:09 +0200 Subject: Move function `ast.Inspect` to new function Give it a name. --- defererr.go | 162 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 83 insertions(+), 79 deletions(-) (limited to 'defererr.go') diff --git a/defererr.go b/defererr.go index f7e1e49..4455ec6 100644 --- a/defererr.go +++ b/defererr.go @@ -23,103 +23,107 @@ func run(pass *analysis.Pass) (interface{}, error) { // Is err variable returned after closure? for _, file := range pass.Files { - ast.Inspect( - file, - func(node ast.Node) bool { - funcDecl, ok := node.(*ast.FuncDecl) + checkFunctions(pass, file) + } + + return nil, nil +} + +func checkFunctions(pass *analysis.Pass, node ast.Node) { + ast.Inspect( + node, + func(node ast.Node) bool { + funcDecl, ok := node.(*ast.FuncDecl) + if !ok { + return true + } + + if funcDecl.Type.Results == nil { + return true + } + + funcReturnsError := false + errorReturnIndex := -1 + for i, returnVal := range funcDecl.Type.Results.List { + fmt.Printf("returnVal Type: %#v\n", returnVal.Type) + + returnIdent, ok := returnVal.Type.(*ast.Ident) if !ok { return true } - if funcDecl.Type.Results == nil { - return true + if returnIdent.Name == "error" { + funcReturnsError = true + errorReturnIndex = i } + } - funcReturnsError := false - errorReturnIndex := -1 - for i, returnVal := range funcDecl.Type.Results.List { - fmt.Printf("returnVal Type: %#v\n", returnVal.Type) + // Can we do the same for non-error types? + // for _, returnVal := range funcType.Results.List { + // } - returnIdent, ok := returnVal.Type.(*ast.Ident) + if !funcReturnsError || errorReturnIndex == -1 { + return true + } + + if len(funcDecl.Type.Results.List[errorReturnIndex].Names) > 0 { + fmt.Printf("return error var name: %#v\n", funcDecl.Type.Results.List[errorReturnIndex].Names[0]) + } + errorReturnField := funcDecl.Type.Results.List[errorReturnIndex] + + ast.Inspect( + funcDecl.Body, + func(node ast.Node) bool { + // fmt.Printf("node: %#v\n", node) + deferStmt, ok := node.(*ast.DeferStmt) if !ok { return true } - if returnIdent.Name == "error" { - funcReturnsError = true - errorReturnIndex = i - } - } - - // Can we do the same for non-error types? - // for _, returnVal := range funcType.Results.List { - // } + fmt.Printf("defer: %#v\n", deferStmt) - if !funcReturnsError || errorReturnIndex == -1 { - return true - } + // TODO: Find out if defer uses assigns an error variable without declaring it - if len(funcDecl.Type.Results.List[errorReturnIndex].Names) > 0 { - fmt.Printf("return error var name: %#v\n", funcDecl.Type.Results.List[errorReturnIndex].Names[0]) - } - errorReturnField := funcDecl.Type.Results.List[errorReturnIndex] - - ast.Inspect( - funcDecl.Body, - func(node ast.Node) bool { - // fmt.Printf("node: %#v\n", node) - deferStmt, ok := node.(*ast.DeferStmt) - if !ok { - return true - } - - fmt.Printf("defer: %#v\n", deferStmt) - - // TODO: Find out if defer uses assigns an error variable without declaring it + funcLit, ok := deferStmt.Call.Fun.(*ast.FuncLit) + if !ok { + return true + } - funcLit, ok := deferStmt.Call.Fun.(*ast.FuncLit) - if !ok { - return true - } + // TODO: funcall + checkErrorAssignedInDefer(pass, funcLit, errorReturnField) - // TODO: funcall - checkErrorAssignedInDefer(pass, funcLit, errorReturnField) + return true + }, + ) - return true - }, - ) - - // // Look for a function literal after the `defer` statement. - // funcLit, ok := deferStmt.Call.Fun.(*ast.FuncLit) - // if !ok { - // return true - // } - // - // funcScope := pass.TypesInfo.Scopes[funcLit.Type] - // - // // Try to find the function where the defer is defined. Note, defer can be defined in an inner block. - // funcType, ok := funcScope.Parent().(*ast.FuncType) - // if !ok { - // return true - // } - // fmt.Printf("func: %#v\n", funcType) - // - // if funcLit.Type.Results == nil { - // return true - // } - // - // for _, returnVal := range funcLit.Type.Results.List { - // fmt.Printf("returnVal: %#v\n", returnVal) - // } - - fmt.Println() + // // Look for a function literal after the `defer` statement. + // funcLit, ok := deferStmt.Call.Fun.(*ast.FuncLit) + // if !ok { + // return true + // } + // + // funcScope := pass.TypesInfo.Scopes[funcLit.Type] + // + // // Try to find the function where the defer is defined. Note, defer can be defined in an inner block. + // funcType, ok := funcScope.Parent().(*ast.FuncType) + // if !ok { + // return true + // } + // fmt.Printf("func: %#v\n", funcType) + // + // if funcLit.Type.Results == nil { + // return true + // } + // + // for _, returnVal := range funcLit.Type.Results.List { + // fmt.Printf("returnVal: %#v\n", returnVal) + // } - return true - }, - ) - } + fmt.Println() - return nil, nil + return true + }, + ) } // TODO: doc -- cgit v1.2.3