// Copyright 2020 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 ifaceassert defines an Analyzer that flags
// impossible interface-interface type assertions.
package ifaceassert

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

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

const Doc = `detect impossible interface-to-interface type assertions

This checker flags type assertions v.(T) and corresponding type-switch cases
in which the static type V of v is an interface that cannot possibly implement
the target interface T. This occurs when V and T contain methods with the same
name but different signatures. Example:

	var v interface {
		Read()
	}
	_ = v.(io.Reader)

The Read method in v has a different signature than the Read method in
io.Reader, so this assertion cannot succeed.
`

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

// assertableTo checks whether interface v can be asserted into t. It returns
// nil on success, or the first conflicting method on failure.
func assertableTo(v, t types.Type) *types.Func {
	// ensure that v and t are interfaces
	V, _ := v.Underlying().(*types.Interface)
	T, _ := t.Underlying().(*types.Interface)
	if V == nil || T == nil {
		return nil
	}
	if f, wrongType := types.MissingMethod(V, T, false); wrongType {
		return f
	}
	return nil
}

func run(pass *analysis.Pass) (interface{}, error) {
	inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
	nodeFilter := []ast.Node{
		(*ast.TypeAssertExpr)(nil),
		(*ast.TypeSwitchStmt)(nil),
	}
	inspect.Preorder(nodeFilter, func(n ast.Node) {
		var (
			assert  *ast.TypeAssertExpr // v.(T) expression
			targets []ast.Expr          // interfaces T in v.(T)
		)
		switch n := n.(type) {
		case *ast.TypeAssertExpr:
			// take care of v.(type) in *ast.TypeSwitchStmt
			if n.Type == nil {
				return
			}
			assert = n
			targets = append(targets, n.Type)
		case *ast.TypeSwitchStmt:
			// retrieve type assertion from type switch's 'assign' field
			switch t := n.Assign.(type) {
			case *ast.ExprStmt:
				assert = t.X.(*ast.TypeAssertExpr)
			case *ast.AssignStmt:
				assert = t.Rhs[0].(*ast.TypeAssertExpr)
			}
			// gather target types from case clauses
			for _, c := range n.Body.List {
				targets = append(targets, c.(*ast.CaseClause).List...)
			}
		}
		V := pass.TypesInfo.TypeOf(assert.X)
		for _, target := range targets {
			T := pass.TypesInfo.TypeOf(target)
			if f := assertableTo(V, T); f != nil {
				pass.Reportf(
					target.Pos(),
					"impossible type assertion: no type can implement both %v and %v (conflicting types for %v method)",
					V, T, f.Name(),
				)
			}
		}
	})
	return nil, nil
}
