Source file src/cmd/vendor/golang.org/x/tools/go/analysis/passes/defers/defers.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package defers
     6  
     7  import (
     8  	_ "embed"
     9  	"go/ast"
    10  
    11  	"golang.org/x/tools/go/analysis"
    12  	"golang.org/x/tools/go/analysis/passes/inspect"
    13  	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
    14  	"golang.org/x/tools/go/ast/inspector"
    15  	"golang.org/x/tools/go/types/typeutil"
    16  )
    17  
    18  //go:embed doc.go
    19  var doc string
    20  
    21  // Analyzer is the defers analyzer.
    22  var Analyzer = &analysis.Analyzer{
    23  	Name:     "defers",
    24  	Requires: []*analysis.Analyzer{inspect.Analyzer},
    25  	URL:      "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/defers",
    26  	Doc:      analysisutil.MustExtractDoc(doc, "defers"),
    27  	Run:      run,
    28  }
    29  
    30  func run(pass *analysis.Pass) (interface{}, error) {
    31  	if !analysisutil.Imports(pass.Pkg, "time") {
    32  		return nil, nil
    33  	}
    34  
    35  	checkDeferCall := func(node ast.Node) bool {
    36  		switch v := node.(type) {
    37  		case *ast.CallExpr:
    38  			if analysisutil.IsFunctionNamed(typeutil.StaticCallee(pass.TypesInfo, v), "time", "Since") {
    39  				pass.Reportf(v.Pos(), "call to time.Since is not deferred")
    40  			}
    41  		case *ast.FuncLit:
    42  			return false // prune
    43  		}
    44  		return true
    45  	}
    46  
    47  	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
    48  
    49  	nodeFilter := []ast.Node{
    50  		(*ast.DeferStmt)(nil),
    51  	}
    52  
    53  	inspect.Preorder(nodeFilter, func(n ast.Node) {
    54  		d := n.(*ast.DeferStmt)
    55  		ast.Inspect(d.Call, checkDeferCall)
    56  	})
    57  
    58  	return nil, nil
    59  }
    60  

View as plain text