(pass *analysis.Pass, body *ast.BlockStmt, ctx txContext, decls map[types.Object]*ast.FuncDecl, suppressed map[int]bool)
| 96 | } |
| 97 | |
| 98 | func inspectInTxBody(pass *analysis.Pass, body *ast.BlockStmt, ctx txContext, decls map[types.Object]*ast.FuncDecl, suppressed map[int]bool) { |
| 99 | ctx = ctx.withAliases(pass, body) |
| 100 | |
| 101 | ast.Inspect(body, func(n ast.Node) bool { |
| 102 | switch n := n.(type) { |
| 103 | case *ast.FuncLit: |
| 104 | return false |
| 105 | case *ast.GoStmt: |
| 106 | if funcLit, ok := funcLitCall(n.Call); ok { |
| 107 | reportCallMisuse(pass, n.Call, ctx, suppressed) |
| 108 | inspectInTxBody(pass, funcLit.Body, ctx, decls, suppressed) |
| 109 | return false |
| 110 | } |
| 111 | return true |
| 112 | case *ast.DeferStmt: |
| 113 | if funcLit, ok := funcLitCall(n.Call); ok { |
| 114 | reportCallMisuse(pass, n.Call, ctx, suppressed) |
| 115 | inspectInTxBody(pass, funcLit.Body, ctx, decls, suppressed) |
| 116 | return false |
| 117 | } |
| 118 | return true |
| 119 | } |
| 120 | |
| 121 | call, ok := n.(*ast.CallExpr) |
| 122 | if !ok { |
| 123 | return true |
| 124 | } |
| 125 | |
| 126 | reported := reportCallMisuse(pass, call, ctx, suppressed) |
| 127 | if funcLit, ok := funcLitCall(call); ok { |
| 128 | inspectInTxBody(pass, funcLit.Body, ctx, decls, suppressed) |
| 129 | return true |
| 130 | } |
| 131 | if reported { |
| 132 | return true |
| 133 | } |
| 134 | |
| 135 | callee, calleeOuterStore, ok := resolveSamePackageCallee(pass, call, ctx, decls) |
| 136 | if !ok || callee == nil || callee.Body == nil { |
| 137 | return true |
| 138 | } |
| 139 | if !bodyUsesOuterStore(pass, callee.Body, calleeOuterStore) { |
| 140 | return true |
| 141 | } |
| 142 | |
| 143 | reportIfNotSuppressed(pass, suppressed, call.Pos(), fmt.Sprintf( |
| 144 | "call to '%s' inside InTx uses outer store '%s'; pass '%s' through the helper or hoist the call", |
| 145 | exprString(call.Fun), |
| 146 | ctx.outerStore.display, |
| 147 | ctx.txName, |
| 148 | )) |
| 149 | return true |
| 150 | }) |
| 151 | } |
| 152 | |
| 153 | func reportCallMisuse(pass *analysis.Pass, call *ast.CallExpr, ctx txContext, suppressed map[int]bool) bool { |
| 154 | kind, pos := classifyCall(pass, call, ctx.outerStore) |
no test coverage detected