...

Source file src/gotest.tools/v3/internal/source/defers.go

Documentation: gotest.tools/v3/internal/source

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

View as plain text