// Copyright 2013 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 shadow

import (
	"go/ast"
	"go/token"
	"go/types"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/go/analysis/passes/inspect"
	"golang.org/x/tools/go/ast/inspector"
)

// NOTE: Experimental. Not part of the vet suite.

const Doc = `check for possible unintended shadowing of variables

This analyzer check for shadowed variables.
A shadowed variable is a variable declared in an inner scope
with the same name and type as a variable in an outer scope,
and where the outer variable is mentioned after the inner one
is declared.

(This definition can be refined; the module generates too many
false positives and is not yet enabled by default.)

For example:

	func BadRead(f *os.File, buf []byte) error {
		var err error
		for {
			n, err := f.Read(buf) // shadows the function variable 'err'
			if err != nil {
				break // causes return of wrong value
			}
			foo(buf)
		}
		return err
	}
`

var Analyzer = &analysis.Analyzer{
	Name:     "shadow",
	Doc:      Doc,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
	Run:      run,
}

// flags
var strict = false

func init() {
	Analyzer.Flags.BoolVar(&strict, "strict", strict, "whether to be strict about shadowing; can be noisy")
}

func run(pass *analysis.Pass) (interface{}, error) {
	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

	spans := make(map[types.Object]span)
	for id, obj := range pass.TypesInfo.Defs {
		// Ignore identifiers that don't denote objects
		// (package names, symbolic variables such as t
		// in t := x.(type) of type switch headers).
		if obj != nil {
			growSpan(spans, obj, id.Pos(), id.End())
		}
	}
	for id, obj := range pass.TypesInfo.Uses {
		growSpan(spans, obj, id.Pos(), id.End())
	}
	for node, obj := range pass.TypesInfo.Implicits {
		// A type switch with a short variable declaration
		// such as t := x.(type) doesn't declare the symbolic
		// variable (t in the example) at the switch header;
		// instead a new variable t (with specific type) is
		// declared implicitly for each case. Such variables
		// are found in the types.Info.Implicits (not Defs)
		// map. Add them here, assuming they are declared at
		// the type cases' colon ":".
		if cc, ok := node.(*ast.CaseClause); ok {
			growSpan(spans, obj, cc.Colon, cc.Colon)
		}
	}

	nodeFilter := []ast.Node{
		(*ast.AssignStmt)(nil),
		(*ast.GenDecl)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		switch n := n.(type) {
		case *ast.AssignStmt:
			checkShadowAssignment(pass, spans, n)
		case *ast.GenDecl:
			checkShadowDecl(pass, spans, n)
		}
	})
	return nil, nil
}

// A span stores the minimum range of byte positions in the file in which a
// given variable (types.Object) is mentioned. It is lexically defined: it spans
// from the beginning of its first mention to the end of its last mention.
// A variable is considered shadowed (if strict is off) only if the
// shadowing variable is declared within the span of the shadowed variable.
// In other words, if a variable is shadowed but not used after the shadowed
// variable is declared, it is inconsequential and not worth complaining about.
// This simple check dramatically reduces the nuisance rate for the shadowing
// check, at least until something cleverer comes along.
//
// One wrinkle: A "naked return" is a silent use of a variable that the Span
// will not capture, but the compilers catch naked returns of shadowed
// variables so we don't need to.
//
// Cases this gets wrong (TODO):
// - If a for loop's continuation statement mentions a variable redeclared in
// the block, we should complain about it but don't.
// - A variable declared inside a function literal can falsely be identified
// as shadowing a variable in the outer function.
//
type span struct {
	min token.Pos
	max token.Pos
}

// contains reports whether the position is inside the span.
func (s span) contains(pos token.Pos) bool {
	return s.min <= pos && pos < s.max
}

// growSpan expands the span for the object to contain the source range [pos, end).
func growSpan(spans map[types.Object]span, obj types.Object, pos, end token.Pos) {
	if strict {
		return // No need
	}
	s, ok := spans[obj]
	if ok {
		if s.min > pos {
			s.min = pos
		}
		if s.max < end {
			s.max = end
		}
	} else {
		s = span{pos, end}
	}
	spans[obj] = s
}

// checkShadowAssignment checks for shadowing in a short variable declaration.
func checkShadowAssignment(pass *analysis.Pass, spans map[types.Object]span, a *ast.AssignStmt) {
	if a.Tok != token.DEFINE {
		return
	}
	if idiomaticShortRedecl(pass, a) {
		return
	}
	for _, expr := range a.Lhs {
		ident, ok := expr.(*ast.Ident)
		if !ok {
			pass.ReportRangef(expr, "invalid AST: short variable declaration of non-identifier")
			return
		}
		checkShadowing(pass, spans, ident)
	}
}

// idiomaticShortRedecl reports whether this short declaration can be ignored for
// the purposes of shadowing, that is, that any redeclarations it contains are deliberate.
func idiomaticShortRedecl(pass *analysis.Pass, a *ast.AssignStmt) bool {
	// Don't complain about deliberate redeclarations of the form
	//	i := i
	// Such constructs are idiomatic in range loops to create a new variable
	// for each iteration. Another example is
	//	switch n := n.(type)
	if len(a.Rhs) != len(a.Lhs) {
		return false
	}
	// We know it's an assignment, so the LHS must be all identifiers. (We check anyway.)
	for i, expr := range a.Lhs {
		lhs, ok := expr.(*ast.Ident)
		if !ok {
			pass.ReportRangef(expr, "invalid AST: short variable declaration of non-identifier")
			return true // Don't do any more processing.
		}
		switch rhs := a.Rhs[i].(type) {
		case *ast.Ident:
			if lhs.Name != rhs.Name {
				return false
			}
		case *ast.TypeAssertExpr:
			if id, ok := rhs.X.(*ast.Ident); ok {
				if lhs.Name != id.Name {
					return false
				}
			}
		default:
			return false
		}
	}
	return true
}

// idiomaticRedecl reports whether this declaration spec can be ignored for
// the purposes of shadowing, that is, that any redeclarations it contains are deliberate.
func idiomaticRedecl(d *ast.ValueSpec) bool {
	// Don't complain about deliberate redeclarations of the form
	//	var i, j = i, j
	// Don't ignore redeclarations of the form
	//	var i = 3
	if len(d.Names) != len(d.Values) {
		return false
	}
	for i, lhs := range d.Names {
		rhs, ok := d.Values[i].(*ast.Ident)
		if !ok || lhs.Name != rhs.Name {
			return false
		}
	}
	return true
}

// checkShadowDecl checks for shadowing in a general variable declaration.
func checkShadowDecl(pass *analysis.Pass, spans map[types.Object]span, d *ast.GenDecl) {
	if d.Tok != token.VAR {
		return
	}
	for _, spec := range d.Specs {
		valueSpec, ok := spec.(*ast.ValueSpec)
		if !ok {
			pass.ReportRangef(spec, "invalid AST: var GenDecl not ValueSpec")
			return
		}
		// Don't complain about deliberate redeclarations of the form
		//	var i = i
		if idiomaticRedecl(valueSpec) {
			return
		}
		for _, ident := range valueSpec.Names {
			checkShadowing(pass, spans, ident)
		}
	}
}

// checkShadowing checks whether the identifier shadows an identifier in an outer scope.
func checkShadowing(pass *analysis.Pass, spans map[types.Object]span, ident *ast.Ident) {
	if ident.Name == "_" {
		// Can't shadow the blank identifier.
		return
	}
	obj := pass.TypesInfo.Defs[ident]
	if obj == nil {
		return
	}
	// obj.Parent.Parent is the surrounding scope. If we can find another declaration
	// starting from there, we have a shadowed identifier.
	_, shadowed := obj.Parent().Parent().LookupParent(obj.Name(), obj.Pos())
	if shadowed == nil {
		return
	}
	// Don't complain if it's shadowing a universe-declared identifier; that's fine.
	if shadowed.Parent() == types.Universe {
		return
	}
	if strict {
		// The shadowed identifier must appear before this one to be an instance of shadowing.
		if shadowed.Pos() > ident.Pos() {
			return
		}
	} else {
		// Don't complain if the span of validity of the shadowed identifier doesn't include
		// the shadowing identifier.
		span, ok := spans[shadowed]
		if !ok {
			pass.ReportRangef(ident, "internal error: no range for %q", ident.Name)
			return
		}
		if !span.contains(ident.Pos()) {
			return
		}
	}
	// Don't complain if the types differ: that implies the programmer really wants two different things.
	if types.Identical(obj.Type(), shadowed.Type()) {
		line := pass.Fset.Position(shadowed.Pos()).Line
		pass.ReportRangef(ident, "declaration of %q shadows declaration at line %d", obj.Name(), line)
	}
}
