...

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

     1	// Copyright 2013 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 nilfunc defines an Analyzer that checks for useless
     6	// comparisons against nil.
     7	package nilfunc
     8	
     9	import (
    10		"go/ast"
    11		"go/token"
    12		"go/types"
    13	
    14		"golang.org/x/tools/go/analysis"
    15		"golang.org/x/tools/go/analysis/passes/inspect"
    16		"golang.org/x/tools/go/ast/inspector"
    17	)
    18	
    19	const Doc = `check for useless comparisons between functions and nil
    20	
    21	A useless comparison is one like f == nil as opposed to f() == nil.`
    22	
    23	var Analyzer = &analysis.Analyzer{
    24		Name:     "nilfunc",
    25		Doc:      Doc,
    26		Requires: []*analysis.Analyzer{inspect.Analyzer},
    27		Run:      run,
    28	}
    29	
    30	func run(pass *analysis.Pass) (interface{}, error) {
    31		inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
    32	
    33		nodeFilter := []ast.Node{
    34			(*ast.BinaryExpr)(nil),
    35		}
    36		inspect.Preorder(nodeFilter, func(n ast.Node) {
    37			e := n.(*ast.BinaryExpr)
    38	
    39			// Only want == or != comparisons.
    40			if e.Op != token.EQL && e.Op != token.NEQ {
    41				return
    42			}
    43	
    44			// Only want comparisons with a nil identifier on one side.
    45			var e2 ast.Expr
    46			switch {
    47			case pass.TypesInfo.Types[e.X].IsNil():
    48				e2 = e.Y
    49			case pass.TypesInfo.Types[e.Y].IsNil():
    50				e2 = e.X
    51			default:
    52				return
    53			}
    54	
    55			// Only want identifiers or selector expressions.
    56			var obj types.Object
    57			switch v := e2.(type) {
    58			case *ast.Ident:
    59				obj = pass.TypesInfo.Uses[v]
    60			case *ast.SelectorExpr:
    61				obj = pass.TypesInfo.Uses[v.Sel]
    62			default:
    63				return
    64			}
    65	
    66			// Only want functions.
    67			if _, ok := obj.(*types.Func); !ok {
    68				return
    69			}
    70	
    71			pass.Reportf(e.Pos(), "comparison of function %v %v nil is always %v", obj.Name(), e.Op, e.Op == token.NEQ)
    72		})
    73		return nil, nil
    74	}
    75	

View as plain text