...

Source file src/pkg/cmd/vendor/golang.org/x/tools/go/analysis/passes/assign/assign.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 assign defines an Analyzer that detects useless assignments.
     6	package assign
     7	
     8	// TODO(adonovan): check also for assignments to struct fields inside
     9	// methods that are on T instead of *T.
    10	
    11	import (
    12		"go/ast"
    13		"go/token"
    14		"reflect"
    15	
    16		"golang.org/x/tools/go/analysis"
    17		"golang.org/x/tools/go/analysis/passes/inspect"
    18		"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
    19		"golang.org/x/tools/go/ast/inspector"
    20	)
    21	
    22	const Doc = `check for useless assignments
    23	
    24	This checker reports assignments of the form x = x or a[i] = a[i].
    25	These are almost always useless, and even when they aren't they are
    26	usually a mistake.`
    27	
    28	var Analyzer = &analysis.Analyzer{
    29		Name:     "assign",
    30		Doc:      Doc,
    31		Requires: []*analysis.Analyzer{inspect.Analyzer},
    32		Run:      run,
    33	}
    34	
    35	func run(pass *analysis.Pass) (interface{}, error) {
    36		inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
    37	
    38		nodeFilter := []ast.Node{
    39			(*ast.AssignStmt)(nil),
    40		}
    41		inspect.Preorder(nodeFilter, func(n ast.Node) {
    42			stmt := n.(*ast.AssignStmt)
    43			if stmt.Tok != token.ASSIGN {
    44				return // ignore :=
    45			}
    46			if len(stmt.Lhs) != len(stmt.Rhs) {
    47				// If LHS and RHS have different cardinality, they can't be the same.
    48				return
    49			}
    50			for i, lhs := range stmt.Lhs {
    51				rhs := stmt.Rhs[i]
    52				if analysisutil.HasSideEffects(pass.TypesInfo, lhs) ||
    53					analysisutil.HasSideEffects(pass.TypesInfo, rhs) {
    54					continue // expressions may not be equal
    55				}
    56				if reflect.TypeOf(lhs) != reflect.TypeOf(rhs) {
    57					continue // short-circuit the heavy-weight gofmt check
    58				}
    59				le := analysisutil.Format(pass.Fset, lhs)
    60				re := analysisutil.Format(pass.Fset, rhs)
    61				if le == re {
    62					pass.Reportf(stmt.Pos(), "self-assignment of %s to %s", re, le)
    63				}
    64			}
    65		})
    66	
    67		return nil, nil
    68	}
    69	

View as plain text