blob: 66cfafbb648ac731f139495e936ab7f4580a96c0 [file] [log] [blame]
Matteo Scandoloa6a3aee2019-11-26 13:30:14 -07001package source
2
3import (
4 "go/ast"
5 "go/token"
6
7 "github.com/pkg/errors"
8)
9
10func scanToDeferLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
11 var matchedNode ast.Node
12 ast.Inspect(node, func(node ast.Node) bool {
13 switch {
14 case node == nil || matchedNode != nil:
15 return false
16 case fileset.Position(node.End()).Line == lineNum:
17 if funcLit, ok := node.(*ast.FuncLit); ok {
18 matchedNode = funcLit
19 return false
20 }
21 }
22 return true
23 })
24 debug("defer line node: %s", debugFormatNode{matchedNode})
25 return matchedNode
26}
27
28func guessDefer(node ast.Node) (ast.Node, error) {
29 defers := collectDefers(node)
30 switch len(defers) {
31 case 0:
32 return nil, errors.New("failed to expression in defer")
33 case 1:
34 return defers[0].Call, nil
35 default:
36 return nil, errors.Errorf(
37 "ambiguous call expression: multiple (%d) defers in call block",
38 len(defers))
39 }
40}
41
42func collectDefers(node ast.Node) []*ast.DeferStmt {
43 var defers []*ast.DeferStmt
44 ast.Inspect(node, func(node ast.Node) bool {
45 if d, ok := node.(*ast.DeferStmt); ok {
46 defers = append(defers, d)
47 debug("defer: %s", debugFormatNode{d})
48 return false
49 }
50 return true
51 })
52 return defers
53}