// 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

import (
	_ "embed"
	"go/types"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/buildssa"
	"golang.org/x/tools/go/analysis/passes/internal/analysisutil"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/internal/aliases"
	"golang.org/x/tools/internal/typeparams"
)

//go:embed doc.go
var doc string

// Analyzer reports instances of writes to struct fields and arrays
// that are never read.
var Analyzer = &analysis.Analyzer{
	Name:     "unusedwrite",
	Doc:      analysisutil.MustExtractDoc(doc, "unusedwrite"),
	URL:      "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/unusedwrite",
	Requires: []*analysis.Analyzer{buildssa.Analyzer},
	Run:      run,
}

func run(pass *analysis.Pass) (interface{}, error) {
	ssainput := pass.ResultOf[buildssa.Analyzer].(*buildssa.SSA)
	for _, fn := range ssainput.SrcFuncs {
		// TODO(taking): Iterate over fn._Instantiations() once exported. If so, have 1 report per Pos().
		reports := checkStores(fn)
		for _, store := range reports {
			switch addr := store.Addr.(type) {
			case *ssa.FieldAddr:
				field := typeparams.CoreType(typeparams.MustDeref(addr.X.Type())).(*types.Struct).Field(addr.Field)
				pass.Reportf(store.Pos(),
					"unused write to field %s", field.Name())
			case *ssa.IndexAddr:
				pass.Reportf(store.Pos(),
					"unused write to array index %s", addr.Index)
			}
		}
	}
	return nil, nil
}

// checkStores returns *Stores in fn whose address is written to but never used.
func checkStores(fn *ssa.Function) []*ssa.Store {
	var reports []*ssa.Store
	// 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 {
				// 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) {
						reports = append(reports, store)
					}
				case *ssa.IndexAddr:
					if isDeadStore(store, addr.X, addr) {
						reports = append(reports, store)
					}
				}
			}
		}
	}
	return reports
}

// 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 {
	switch tp.Underlying().(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 := aliases.Unalias(alloc.Type()).(*types.Pointer); ok {
				return isStructOrArray(tp.Elem())
			}
			return false
		}
	}
	return isStructOrArray(v.Type())
}
