// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package unusedwrite checks for unused writes to the elements of a struct or array object.
package unusedwrite

import (
	"fmt"
	"go/types"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/buildssa"
	"golang.org/x/tools/go/ssa"
)

// Doc is a documentation string.
const Doc = `checks for unused writes

The analyzer reports instances of writes to struct fields and
arrays that are never read. Specifically, when a struct object
or an array is copied, its elements are copied implicitly by
the compiler, and any element write to this copy does nothing
with the original object.

For example:

	type T struct { x int }
	func f(input []T) {
		for i, v := range input {  // v is a copy
			v.x = i  // unused write to field x
		}
	}

Another example is about non-pointer receiver:

	type T struct { x int }
	func (t T) f() {  // t is a copy
		t.x = i  // unused write to field x
	}
`

// Analyzer reports instances of writes to struct fields and arrays
// that are never read.
var Analyzer = &analysis.Analyzer{
	Name:     "unusedwrite",
	Doc:      Doc,
	Requires: []*analysis.Analyzer{buildssa.Analyzer},
	Run:      run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	// Check the writes to struct and array objects.
	checkStore := func(store *ssa.Store) {
		// Consider field/index writes to an object whose elements are copied and not shared.
		// MapUpdate is excluded since only the reference of the map is copied.
		switch addr := store.Addr.(type) {
		case *ssa.FieldAddr:
			if isDeadStore(store, addr.X, addr) {
				// Report the bug.
				pass.Reportf(store.Pos(),
					"unused write to field %s",
					getFieldName(addr.X.Type(), addr.Field))
			}
		case *ssa.IndexAddr:
			if isDeadStore(store, addr.X, addr) {
				// Report the bug.
				pass.Reportf(store.Pos(),
					"unused write to array index %s", addr.Index)
			}
		}
	}

	ssainput := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
	for _, fn := range ssainput.SrcFuncs {
		// Visit each block. No need to visit fn.Recover.
		for _, blk := range fn.Blocks {
			for _, instr := range blk.Instrs {
				// Identify writes.
				if store, ok := instr.(*ssa.Store); ok {
					checkStore(store)
				}
			}
		}
	}
	return nil, nil
}

// isDeadStore determines whether a field/index write to an object is dead.
// Argument "obj" is the object, and "addr" is the instruction fetching the field/index.
func isDeadStore(store *ssa.Store, obj ssa.Value, addr ssa.Instruction) bool {
	// Consider only struct or array objects.
	if !hasStructOrArrayType(obj) {
		return false
	}
	// Check liveness: if the value is used later, then don't report the write.
	for _, ref := range *obj.Referrers() {
		if ref == store || ref == addr {
			continue
		}
		switch ins := ref.(type) {
		case ssa.CallInstruction:
			return false
		case *ssa.FieldAddr:
			// Check whether the same field is used.
			if ins.X == obj {
				if faddr, ok := addr.(*ssa.FieldAddr); ok {
					if faddr.Field == ins.Field {
						return false
					}
				}
			}
			// Otherwise another field is used, and this usage doesn't count.
			continue
		case *ssa.IndexAddr:
			if ins.X == obj {
				return false
			}
			continue // Otherwise another object is used
		case *ssa.Lookup:
			if ins.X == obj {
				return false
			}
			continue // Otherwise another object is used
		case *ssa.Store:
			if ins.Val == obj {
				return false
			}
			continue // Otherwise other object is stored
		default: // consider live if the object is used in any other instruction
			return false
		}
	}
	return true
}

// isStructOrArray returns whether the underlying type is struct or array.
func isStructOrArray(tp types.Type) bool {
	if named, ok := tp.(*types.Named); ok {
		tp = named.Underlying()
	}
	switch tp.(type) {
	case *types.Array:
		return true
	case *types.Struct:
		return true
	}
	return false
}

// hasStructOrArrayType returns whether a value is of struct or array type.
func hasStructOrArrayType(v ssa.Value) bool {
	if instr, ok := v.(ssa.Instruction); ok {
		if alloc, ok := instr.(*ssa.Alloc); ok {
			// Check the element type of an allocated register (which always has pointer type)
			// e.g., for
			//   func (t T) f() { ...}
			// the receiver object is of type *T:
			//   t0 = local T (t)   *T
			if tp, ok := alloc.Type().(*types.Pointer); ok {
				return isStructOrArray(tp.Elem())
			}
			return false
		}
	}
	return isStructOrArray(v.Type())
}

// getFieldName returns the name of a field in a struct.
// It the field is not found, then it returns the string format of the index.
//
// For example, for struct T {x int, y int), getFieldName(*T, 1) returns "y".
func getFieldName(tp types.Type, index int) string {
	if pt, ok := tp.(*types.Pointer); ok {
		tp = pt.Elem()
	}
	if named, ok := tp.(*types.Named); ok {
		tp = named.Underlying()
	}
	if stp, ok := tp.(*types.Struct); ok {
		return stp.Field(index).Name()
	}
	return fmt.Sprintf("%d", index)
}
