2018-11-14 06:28:16 -05:00
|
|
|
package source
|
|
|
|
|
|
|
|
import (
|
2022-09-22 09:38:19 -04:00
|
|
|
"fmt"
|
2018-11-14 06:28:16 -05:00
|
|
|
"go/ast"
|
|
|
|
"go/token"
|
|
|
|
)
|
|
|
|
|
|
|
|
func scanToDeferLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
|
|
|
|
var matchedNode ast.Node
|
|
|
|
ast.Inspect(node, func(node ast.Node) bool {
|
|
|
|
switch {
|
|
|
|
case node == nil || matchedNode != nil:
|
|
|
|
return false
|
|
|
|
case fileset.Position(node.End()).Line == lineNum:
|
|
|
|
if funcLit, ok := node.(*ast.FuncLit); ok {
|
|
|
|
matchedNode = funcLit
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
debug("defer line node: %s", debugFormatNode{matchedNode})
|
|
|
|
return matchedNode
|
|
|
|
}
|
|
|
|
|
|
|
|
func guessDefer(node ast.Node) (ast.Node, error) {
|
|
|
|
defers := collectDefers(node)
|
|
|
|
switch len(defers) {
|
|
|
|
case 0:
|
2022-09-22 09:38:19 -04:00
|
|
|
return nil, fmt.Errorf("failed to find expression in defer")
|
2018-11-14 06:28:16 -05:00
|
|
|
case 1:
|
|
|
|
return defers[0].Call, nil
|
|
|
|
default:
|
2022-09-22 09:38:19 -04:00
|
|
|
return nil, fmt.Errorf(
|
2018-11-14 06:28:16 -05:00
|
|
|
"ambiguous call expression: multiple (%d) defers in call block",
|
|
|
|
len(defers))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func collectDefers(node ast.Node) []*ast.DeferStmt {
|
|
|
|
var defers []*ast.DeferStmt
|
|
|
|
ast.Inspect(node, func(node ast.Node) bool {
|
|
|
|
if d, ok := node.(*ast.DeferStmt); ok {
|
|
|
|
defers = append(defers, d)
|
|
|
|
debug("defer: %s", debugFormatNode{d})
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return true
|
|
|
|
})
|
|
|
|
return defers
|
|
|
|
}
|