diff options
-rw-r--r-- | defererr.go | 63 |
1 files changed, 32 insertions, 31 deletions
diff --git a/defererr.go b/defererr.go index 96c5569..c835131 100644 --- a/defererr.go +++ b/defererr.go @@ -2,7 +2,6 @@ package defererr import ( - "fmt" "go/ast" "go/token" "go/types" @@ -100,39 +99,13 @@ func checkFunctions(pass *analysis.Pass, node ast.Node) { fState := newFunctionState() - // Is it possible to generalise this to other types, and look for - // anything set in `defer` with the same type as a result in the - // return signature? - - // TODO: Move to checkDeferFunc() - // Should we make this an ast.Visitor to store some state for `return` checking? - ast.Inspect( + checkFunctionBody( + pass, 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 - } - - // TODO: funcall - checkErrorAssignedInDefer(pass, funcLit, errorReturnField, fState) - - return true - }, + errorReturnField, + fState, ) - fmt.Printf("fState: %#v\n", fState) - // Stop if the `defer` closure does not assign to an error // variable. if !fState.deferAssignsError() { @@ -147,6 +120,34 @@ func checkFunctions(pass *analysis.Pass, node ast.Node) { } // TODO: doc +func checkFunctionBody( + pass *analysis.Pass, + funcBody *ast.BlockStmt, + errorReturnField *ast.Field, + fState *functionState, +) { + ast.Inspect( + funcBody, + func(node ast.Node) bool { + deferStmt, ok := node.(*ast.DeferStmt) + if !ok { + return true + } + + // Get a function closure run by `defer`. + funcLit, ok := deferStmt.Call.Fun.(*ast.FuncLit) + if !ok { + return true + } + + checkErrorAssignedInDefer(pass, funcLit, errorReturnField, fState) + + return true + }, + ) +} + +// TODO: doc func checkFunctionReturns( pass *analysis.Pass, funcBody *ast.BlockStmt, |