// Copyright 2019 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 golang

import (
	"context"
	"errors"
	"fmt"
	"go/ast"
	"go/token"
	"go/types"
	"reflect"
	"slices"
	"sort"
	"strings"
	"sync"

	"golang.org/x/sync/errgroup"
	"golang.org/x/tools/go/types/typeutil"
	"golang.org/x/tools/gopls/internal/cache"
	"golang.org/x/tools/gopls/internal/cache/metadata"
	"golang.org/x/tools/gopls/internal/cache/methodsets"
	"golang.org/x/tools/gopls/internal/cache/parsego"
	"golang.org/x/tools/gopls/internal/file"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/gopls/internal/util/safetoken"
	"golang.org/x/tools/internal/astutil/cursor"
	"golang.org/x/tools/internal/astutil/edge"
	"golang.org/x/tools/internal/event"
)

// This file defines the new implementation of the 'implementation'
// operator that does not require type-checker data structures for an
// unbounded number of packages.
//
// TODO(adonovan):
// - Audit to ensure robustness in face of type errors.
// - Eliminate false positives due to 'tricky' cases of the global algorithm.
// - Ensure we have test coverage of:
//      type aliases
//      nil, PkgName, Builtin (all errors)
//      any (empty result)
//      method of unnamed interface type (e.g. var x interface { f() })
//        (the global algorithm may find implementations of this type
//         but will not include it in the index.)

// Implementation returns a new sorted array of locations of
// declarations of types that implement (or are implemented by) the
// type referred to at the given position.
//
// If the position denotes a method, the computation is applied to its
// receiver type and then its corresponding methods are returned.
func Implementation(ctx context.Context, snapshot *cache.Snapshot, f file.Handle, pp protocol.Position) ([]protocol.Location, error) {
	ctx, done := event.Start(ctx, "golang.Implementation")
	defer done()

	locs, err := implementations(ctx, snapshot, f, pp)
	if err != nil {
		return nil, err
	}

	// Sort and de-duplicate locations.
	sort.Slice(locs, func(i, j int) bool {
		return protocol.CompareLocation(locs[i], locs[j]) < 0
	})
	out := locs[:0]
	for _, loc := range locs {
		if len(out) == 0 || out[len(out)-1] != loc {
			out = append(out, loc)
		}
	}
	locs = out

	return locs, nil
}

func implementations(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle, pp protocol.Position) ([]protocol.Location, error) {
	// Type check the current package.
	pkg, pgf, err := NarrowestPackageForFile(ctx, snapshot, fh.URI())
	if err != nil {
		return nil, err
	}
	pos, err := pgf.PositionPos(pp)
	if err != nil {
		return nil, err
	}

	// Find implementations based on func signatures.
	if locs, err := implFuncs(pkg, pgf, pos); err != errNotHandled {
		return locs, err
	}

	// Find implementations based on method sets.

	// First, find the object referenced at the cursor.
	// The object may be declared in a different package.
	obj, err := implementsObj(pkg, pgf, pos)
	if err != nil {
		return nil, err
	}

	// If the resulting object has a position, we can expand the search to types
	// in the declaring package(s). In this case, we must re-type check these
	// packages in the same realm.
	var (
		declOffset int
		declURI    protocol.DocumentURI
		localPkgs  []*cache.Package
	)
	if obj.Pos().IsValid() { // no local package for error or error.Error
		declPosn := safetoken.StartPosition(pkg.FileSet(), obj.Pos())
		declOffset = declPosn.Offset
		// Type-check the declaring package (incl. variants) for use
		// by the "local" search, which uses type information to
		// enumerate all types within the package that satisfy the
		// query type, even those defined local to a function.
		declURI = protocol.URIFromPath(declPosn.Filename)
		declMPs, err := snapshot.MetadataForFile(ctx, declURI)
		if err != nil {
			return nil, err
		}
		metadata.RemoveIntermediateTestVariants(&declMPs)
		if len(declMPs) == 0 {
			return nil, fmt.Errorf("no packages for file %s", declURI)
		}
		ids := make([]PackageID, len(declMPs))
		for i, mp := range declMPs {
			ids[i] = mp.ID
		}
		localPkgs, err = snapshot.TypeCheck(ctx, ids...)
		if err != nil {
			return nil, err
		}
	}

	pkg = nil // no longer used

	// Is the selected identifier a type name or method?
	// (For methods, report the corresponding method names.)
	//
	// This logic is reused for local queries.
	typeOrMethod := func(obj types.Object) (types.Type, *types.Func) {
		switch obj := obj.(type) {
		case *types.TypeName:
			return obj.Type(), nil
		case *types.Func:
			// For methods, use the receiver type, which may be anonymous.
			if recv := obj.Signature().Recv(); recv != nil {
				return recv.Type(), obj
			}
		}
		return nil, nil
	}
	queryType, queryMethod := typeOrMethod(obj)
	if queryType == nil {
		return nil, bug.Errorf("%s is not a type or method", obj.Name()) // should have been handled by implementsObj
	}

	// Compute the method-set fingerprint used as a key to the global search.
	key, hasMethods := methodsets.KeyOf(queryType)
	if !hasMethods {
		// A type with no methods yields an empty result.
		// (No point reporting that every type satisfies 'any'.)
		return nil, nil
	}

	// The global search needs to look at every package in the
	// forward transitive closure of the workspace; see package
	// ./methodsets.
	//
	// For now we do all the type checking before beginning the search.
	// TODO(adonovan): opt: search in parallel topological order
	// so that we can overlap index lookup with typechecking.
	// I suspect a number of algorithms on the result of TypeCheck could
	// be optimized by being applied as soon as each package is available.
	globalMetas, err := snapshot.AllMetadata(ctx)
	if err != nil {
		return nil, err
	}
	metadata.RemoveIntermediateTestVariants(&globalMetas)
	globalIDs := make([]PackageID, 0, len(globalMetas))

	var pkgPath PackagePath
	if obj.Pkg() != nil { // nil for error
		pkgPath = PackagePath(obj.Pkg().Path())
	}
	for _, mp := range globalMetas {
		if mp.PkgPath == pkgPath {
			continue // declaring package is handled by local implementation
		}
		globalIDs = append(globalIDs, mp.ID)
	}
	indexes, err := snapshot.MethodSets(ctx, globalIDs...)
	if err != nil {
		return nil, fmt.Errorf("querying method sets: %v", err)
	}

	// Search local and global packages in parallel.
	var (
		group  errgroup.Group
		locsMu sync.Mutex
		locs   []protocol.Location
	)
	// local search
	for _, localPkg := range localPkgs {
		// The localImplementations algorithm assumes needle and haystack
		// belong to a single package (="realm" of types symbol identities),
		// so we need to recompute obj for each local package.
		// (By contrast the global algorithm is name-based.)
		declPkg := localPkg
		group.Go(func() error {
			pkgID := declPkg.Metadata().ID
			declFile, err := declPkg.File(declURI)
			if err != nil {
				return err // "can't happen"
			}

			// Find declaration of corresponding object
			// in this package based on (URI, offset).
			pos, err := safetoken.Pos(declFile.Tok, declOffset)
			if err != nil {
				return err // also "can't happen"
			}
			// TODO(adonovan): simplify: use objectsAt?
			path := pathEnclosingObjNode(declFile.File, pos)
			if path == nil {
				return ErrNoIdentFound // checked earlier
			}
			id, ok := path[0].(*ast.Ident)
			if !ok {
				return ErrNoIdentFound // checked earlier
			}
			// Shadow obj, queryType, and queryMethod in this package.
			obj := declPkg.TypesInfo().ObjectOf(id) // may be nil
			queryType, queryMethod := typeOrMethod(obj)
			if queryType == nil {
				return fmt.Errorf("querying method sets in package %q: %v", pkgID, err)
			}
			localLocs, err := localImplementations(ctx, snapshot, declPkg, queryType, queryMethod)
			if err != nil {
				return fmt.Errorf("querying local implementations %q: %v", pkgID, err)
			}
			locsMu.Lock()
			locs = append(locs, localLocs...)
			locsMu.Unlock()
			return nil
		})
	}
	// global search
	for _, index := range indexes {
		index := index
		group.Go(func() error {
			for _, res := range index.Search(key, queryMethod) {
				loc := res.Location
				// Map offsets to protocol.Locations in parallel (may involve I/O).
				group.Go(func() error {
					ploc, err := offsetToLocation(ctx, snapshot, loc.Filename, loc.Start, loc.End)
					if err != nil {
						return err
					}
					locsMu.Lock()
					locs = append(locs, ploc)
					locsMu.Unlock()
					return nil
				})
			}
			return nil
		})
	}
	if err := group.Wait(); err != nil {
		return nil, err
	}

	return locs, nil
}

// offsetToLocation converts an offset-based position to a protocol.Location,
// which requires reading the file.
func offsetToLocation(ctx context.Context, snapshot *cache.Snapshot, filename string, start, end int) (protocol.Location, error) {
	uri := protocol.URIFromPath(filename)
	fh, err := snapshot.ReadFile(ctx, uri)
	if err != nil {
		return protocol.Location{}, err // cancelled, perhaps
	}
	content, err := fh.Content()
	if err != nil {
		return protocol.Location{}, err // nonexistent or deleted ("can't happen")
	}
	m := protocol.NewMapper(uri, content)
	return m.OffsetLocation(start, end)
}

// implementsObj returns the object to query for implementations,
// which is a type name or method.
func implementsObj(pkg *cache.Package, pgf *parsego.File, pos token.Pos) (types.Object, error) {
	// This function inherits the limitation of its predecessor in
	// requiring the selection to be an identifier (of a type or
	// method). But there's no fundamental reason why one could
	// not pose this query about any selected piece of syntax that
	// has a type and thus a method set.
	// (If LSP was more thorough about passing text selections as
	// intervals to queries, you could ask about the method set of a
	// subexpression such as x.f().)

	// TODO(adonovan): simplify: use objectsAt?
	path := pathEnclosingObjNode(pgf.File, pos)
	if path == nil {
		return nil, ErrNoIdentFound
	}
	id, ok := path[0].(*ast.Ident)
	if !ok {
		return nil, ErrNoIdentFound
	}

	// Is the object a type or method? Reject other kinds.
	obj := pkg.TypesInfo().Uses[id]
	if obj == nil {
		// Check uses first (unlike ObjectOf) so that T in
		// struct{T} is treated as a reference to a type,
		// not a declaration of a field.
		obj = pkg.TypesInfo().Defs[id]
	}
	switch obj := obj.(type) {
	case *types.TypeName:
		// ok
	case *types.Func:
		if obj.Signature().Recv() == nil {
			return nil, fmt.Errorf("%s is a function, not a method (query at 'func' token to find matching signatures)", id.Name)
		}
	case nil:
		return nil, fmt.Errorf("%s denotes unknown object", id.Name)
	default:
		// e.g. *types.Var -> "var".
		kind := strings.ToLower(strings.TrimPrefix(reflect.TypeOf(obj).String(), "*types."))
		// TODO(adonovan): improve upon "nil is a nil, not a type".
		return nil, fmt.Errorf("%s is a %s, not a type", id.Name, kind)
	}

	return obj, nil
}

// localImplementations searches within pkg for declarations of all
// types that are assignable to/from the query type, and returns a new
// unordered array of their locations.
//
// If method is non-nil, the function instead returns the location
// of each type's method (if any) of that ID.
//
// ("Local" refers to the search within the same package, but this
// function's results may include type declarations that are local to
// a function body. The global search index excludes such types
// because reliably naming such types is hard.)
func localImplementations(ctx context.Context, snapshot *cache.Snapshot, pkg *cache.Package, queryType types.Type, method *types.Func) ([]protocol.Location, error) {
	queryType = methodsets.EnsurePointer(queryType)

	var msets typeutil.MethodSetCache

	// Scan through all type declarations in the syntax.
	var locs []protocol.Location
	var methodLocs []methodsets.Location
	for _, pgf := range pkg.CompiledGoFiles() {
		for cur := range pgf.Cursor.Preorder((*ast.TypeSpec)(nil)) {
			spec := cur.Node().(*ast.TypeSpec)
			def := pkg.TypesInfo().Defs[spec.Name]
			if def == nil {
				continue // "can't happen" for types
			}
			if def.(*types.TypeName).IsAlias() {
				continue // skip type aliases to avoid duplicate reporting
			}
			candidateType := methodsets.EnsurePointer(def.Type())

			// The historical behavior enshrined by this
			// function rejects cases where both are
			// (nontrivial) interface types?
			// That seems like useful information; see #68641.
			// TODO(adonovan): UX: report I/I pairs too?
			// The same question appears in the global algorithm (methodsets).
			if !concreteImplementsIntf(&msets, candidateType, queryType) {
				continue // not assignable
			}

			// Ignore types with empty method sets.
			// (No point reporting that every type satisfies 'any'.)
			mset := msets.MethodSet(candidateType)
			if mset.Len() == 0 {
				continue
			}

			if method == nil {
				// Found matching type.
				locs = append(locs, mustLocation(pgf, spec.Name))
				continue
			}

			// Find corresponding method.
			//
			// We can't use LookupFieldOrMethod because it requires
			// the methodID's types.Package, which we don't know.
			// We could recursively search pkg.Imports for it,
			// but it's easier to walk the method set.
			for i := 0; i < mset.Len(); i++ {
				m := mset.At(i).Obj()
				if m.Id() == method.Id() {
					posn := safetoken.StartPosition(pkg.FileSet(), m.Pos())
					methodLocs = append(methodLocs, methodsets.Location{
						Filename: posn.Filename,
						Start:    posn.Offset,
						End:      posn.Offset + len(m.Name()),
					})
					break
				}
			}
		}
	}

	// Finally convert method positions to protocol form by reading the files.
	for _, mloc := range methodLocs {
		loc, err := offsetToLocation(ctx, snapshot, mloc.Filename, mloc.Start, mloc.End)
		if err != nil {
			return nil, err
		}
		locs = append(locs, loc)
	}

	// Special case: for types that satisfy error, report builtin.go (see #59527).
	if types.Implements(queryType, errorInterfaceType) {
		loc, err := errorLocation(ctx, snapshot)
		if err != nil {
			return nil, err
		}
		locs = append(locs, loc)
	}

	return locs, nil
}

var errorInterfaceType = types.Universe.Lookup("error").Type().Underlying().(*types.Interface)

// errorLocation returns the location of the 'error' type in builtin.go.
func errorLocation(ctx context.Context, snapshot *cache.Snapshot) (protocol.Location, error) {
	pgf, err := snapshot.BuiltinFile(ctx)
	if err != nil {
		return protocol.Location{}, err
	}
	for _, decl := range pgf.File.Decls {
		if decl, ok := decl.(*ast.GenDecl); ok {
			for _, spec := range decl.Specs {
				if spec, ok := spec.(*ast.TypeSpec); ok && spec.Name.Name == "error" {
					return pgf.NodeLocation(spec.Name)
				}
			}
		}
	}
	return protocol.Location{}, fmt.Errorf("built-in error type not found")
}

// concreteImplementsIntf reports whether x is an interface type
// implemented by concrete type y, or vice versa.
//
// If one or both types are generic, the result indicates whether the
// interface may be implemented under some instantiation.
func concreteImplementsIntf(msets *typeutil.MethodSetCache, x, y types.Type) bool {
	xiface := types.IsInterface(x)
	yiface := types.IsInterface(y)

	// Make sure exactly one is an interface type.
	// TODO(adonovan): rescind this policy choice and report
	// I/I relationships. See CL 619719 + issue #68641.
	if xiface == yiface {
		return false
	}

	// Rearrange if needed so x is the concrete type.
	if xiface {
		x, y = y, x
	}
	// Inv: y is an interface type.

	// For each interface method of y, check that x has it too.
	// It is not necessary to compute x's complete method set.
	//
	// If y is a constraint interface (!y.IsMethodSet()), we
	// ignore non-interface terms, leading to occasional spurious
	// matches. We could in future filter based on them, but it
	// would lead to divergence with the global (fingerprint-based)
	// algorithm, which operates only on methodsets.
	ymset := msets.MethodSet(y)
	for i := range ymset.Len() {
		ym := ymset.At(i).Obj().(*types.Func)

		xobj, _, _ := types.LookupFieldOrMethod(x, false, ym.Pkg(), ym.Name())
		xm, ok := xobj.(*types.Func)
		if !ok {
			return false // x lacks a method of y
		}
		if !unify(xm.Signature(), ym.Signature()) {
			return false // signatures do not match
		}
	}
	return true // all methods found
}

// unify reports whether the types of x and y match, allowing free
// type parameters to stand for anything at all, without regard to
// consistency of substitutions.
//
// TODO(adonovan): implement proper unification (#63982), finding the
// most general unifier across all the interface methods.
//
// See also: unify in cache/methodsets/fingerprint, which uses a
// similar ersatz unification approach on type fingerprints, for
// the global index.
func unify(x, y types.Type) bool {
	x = types.Unalias(x)
	y = types.Unalias(y)

	// For now, allow a type parameter to match anything,
	// without regard to consistency of substitutions.
	if is[*types.TypeParam](x) || is[*types.TypeParam](y) {
		return true
	}

	if reflect.TypeOf(x) != reflect.TypeOf(y) {
		return false // mismatched types
	}

	switch x := x.(type) {
	case *types.Array:
		y := y.(*types.Array)
		return x.Len() == y.Len() &&
			unify(x.Elem(), y.Elem())

	case *types.Basic:
		y := y.(*types.Basic)
		return x.Kind() == y.Kind()

	case *types.Chan:
		y := y.(*types.Chan)
		return x.Dir() == y.Dir() &&
			unify(x.Elem(), y.Elem())

	case *types.Interface:
		y := y.(*types.Interface)
		// TODO(adonovan): fix: for correctness, we must check
		// that both interfaces have the same set of methods
		// modulo type parameters, while avoiding the risk of
		// unbounded interface recursion.
		//
		// Since non-empty interface literals are vanishingly
		// rare in methods signatures, we ignore this for now.
		// If more precision is needed we could compare method
		// names and arities, still without full recursion.
		return x.NumMethods() == y.NumMethods()

	case *types.Map:
		y := y.(*types.Map)
		return unify(x.Key(), y.Key()) &&
			unify(x.Elem(), y.Elem())

	case *types.Named:
		y := y.(*types.Named)
		if x.Origin() != y.Origin() {
			return false // different named types
		}
		xtargs := x.TypeArgs()
		ytargs := y.TypeArgs()
		if xtargs.Len() != ytargs.Len() {
			return false // arity error (ill-typed)
		}
		for i := range xtargs.Len() {
			if !unify(xtargs.At(i), ytargs.At(i)) {
				return false // mismatched type args
			}
		}
		return true

	case *types.Pointer:
		y := y.(*types.Pointer)
		return unify(x.Elem(), y.Elem())

	case *types.Signature:
		y := y.(*types.Signature)
		return x.Variadic() == y.Variadic() &&
			unify(x.Params(), y.Params()) &&
			unify(x.Results(), y.Results())

	case *types.Slice:
		y := y.(*types.Slice)
		return unify(x.Elem(), y.Elem())

	case *types.Struct:
		y := y.(*types.Struct)
		if x.NumFields() != y.NumFields() {
			return false
		}
		for i := range x.NumFields() {
			xf := x.Field(i)
			yf := y.Field(i)
			if xf.Embedded() != yf.Embedded() ||
				xf.Name() != yf.Name() ||
				x.Tag(i) != y.Tag(i) ||
				!xf.Exported() && xf.Pkg() != yf.Pkg() ||
				!unify(xf.Type(), yf.Type()) {
				return false
			}
		}
		return true

	case *types.Tuple:
		y := y.(*types.Tuple)
		if x.Len() != y.Len() {
			return false
		}
		for i := range x.Len() {
			if !unify(x.At(i).Type(), y.At(i).Type()) {
				return false
			}
		}
		return true

	default: // incl. *Union, *TypeParam
		panic(fmt.Sprintf("unexpected Type %#v", x))
	}
}

var (
	// TODO(adonovan): why do various RPC handlers related to
	// IncomingCalls return (nil, nil) on the protocol in response
	// to this error? That seems like a violation of the protocol.
	// Is it perhaps a workaround for VSCode behavior?
	errNoObjectFound = errors.New("no object found")
)

// pathEnclosingObjNode returns the AST path to the object-defining
// node associated with pos. "Object-defining" means either an
// *ast.Ident mapped directly to a types.Object or an ast.Node mapped
// implicitly to a types.Object.
func pathEnclosingObjNode(f *ast.File, pos token.Pos) []ast.Node {
	var (
		path  []ast.Node
		found bool
	)

	ast.Inspect(f, func(n ast.Node) bool {
		if found {
			return false
		}

		if n == nil {
			path = path[:len(path)-1]
			return false
		}

		path = append(path, n)

		switch n := n.(type) {
		case *ast.Ident:
			// Include the position directly after identifier. This handles
			// the common case where the cursor is right after the
			// identifier the user is currently typing. Previously we
			// handled this by calling astutil.PathEnclosingInterval twice,
			// once for "pos" and once for "pos-1".
			found = n.Pos() <= pos && pos <= n.End()
		case *ast.ImportSpec:
			if n.Path.Pos() <= pos && pos < n.Path.End() {
				found = true
				// If import spec has a name, add name to path even though
				// position isn't in the name.
				if n.Name != nil {
					path = append(path, n.Name)
				}
			}
		case *ast.StarExpr:
			// Follow star expressions to the inner identifier.
			if pos == n.Star {
				pos = n.X.Pos()
			}
		}

		return !found
	})

	if len(path) == 0 {
		return nil
	}

	// Reverse path so leaf is first element.
	slices.Reverse(path)

	return path
}

// --- Implementations based on signature types --

// implFuncs finds Implementations based on func types.
//
// Just as an interface type abstracts a set of concrete methods, a
// function type abstracts a set of concrete functions. Gopls provides
// analogous operations for navigating from abstract to concrete and
// back in the domain of function types.
//
// A single type (for example http.HandlerFunc) can have both an
// underlying type of function (types.Signature) and have methods that
// cause it to implement an interface. To avoid a confusing user
// interface we want to separate the two operations so that the user
// can unambiguously specify the query they want.
//
// So, whereas Implementations queries on interface types are usually
// keyed by an identifier of a named type, Implementations queries on
// function types are keyed by the "func" keyword, or by the "(" of a
// call expression. The query relates two sets of locations:
//
//  1. the "func" token of each function declaration (FuncDecl or
//     FuncLit). These are analogous to declarations of concrete
//     methods.
//
//  2. uses of abstract functions:
//
//     (a) the "func" token of each FuncType that is not part of
//     Func{Decl,Lit}. These are analogous to interface{...} types.
//
//     (b) the "(" paren of each dynamic call on a value of an
//     abstract function type. These are analogous to references to
//     interface method names, but no names are involved, which has
//     historically made them hard to search for.
//
// An Implementations query on a location in set 1 returns set 2,
// and vice versa.
//
// implFuncs returns errNotHandled to indicate that we should try the
// regular method-sets algorithm.
func implFuncs(pkg *cache.Package, pgf *parsego.File, pos token.Pos) ([]protocol.Location, error) {
	curSel, ok := pgf.Cursor.FindPos(pos, pos)
	if !ok {
		return nil, fmt.Errorf("no code selected")
	}

	info := pkg.TypesInfo()

	// Find innermost enclosing FuncType or CallExpr.
	//
	// We are looking for specific tokens (FuncType.Func and
	// CallExpr.Lparen), but FindPos prefers an adjoining
	// subexpression: given f(x) without additional spaces between
	// tokens, FindPos always returns either f or x, never the
	// CallExpr itself. Thus we must ascend the tree.
	//
	// Another subtlety: due to an edge case in go/ast, FindPos at
	// FuncDecl.Type.Func does not return FuncDecl.Type, only the
	// FuncDecl, because the orders of tree positions and tokens
	// are inconsistent. Consequently, the ancestors for a "func"
	// token of Func{Lit,Decl} do not include FuncType, hence the
	// explicit cases below.
	for _, cur := range curSel.Stack(nil) {
		switch n := cur.Node().(type) {
		case *ast.FuncDecl, *ast.FuncLit:
			if inToken(n.Pos(), "func", pos) {
				// Case 1: concrete function declaration.
				// Report uses of corresponding function types.
				switch n := n.(type) {
				case *ast.FuncDecl:
					return funcUses(pkg, info.Defs[n.Name].Type())
				case *ast.FuncLit:
					return funcUses(pkg, info.TypeOf(n.Type))
				}
			}

		case *ast.FuncType:
			if n.Func.IsValid() && inToken(n.Func, "func", pos) && !beneathFuncDef(cur) {
				// Case 2a: function type.
				// Report declarations of corresponding concrete functions.
				return funcDefs(pkg, info.TypeOf(n))
			}

		case *ast.CallExpr:
			if inToken(n.Lparen, "(", pos) {
				t := dynamicFuncCallType(info, n)
				if t == nil {
					return nil, fmt.Errorf("not a dynamic function call")
				}
				// Case 2b: dynamic call of function value.
				// Report declarations of corresponding concrete functions.
				return funcDefs(pkg, t)
			}
		}
	}

	// It's probably a query of a named type or method.
	// Fall back to the method-sets computation.
	return nil, errNotHandled
}

var errNotHandled = errors.New("not handled")

// funcUses returns all locations in the workspace that are dynamic
// uses of the specified function type.
func funcUses(pkg *cache.Package, t types.Type) ([]protocol.Location, error) {
	var locs []protocol.Location

	// local search
	for _, pgf := range pkg.CompiledGoFiles() {
		for cur := range pgf.Cursor.Preorder((*ast.CallExpr)(nil), (*ast.FuncType)(nil)) {
			var pos, end token.Pos
			var ftyp types.Type
			switch n := cur.Node().(type) {
			case *ast.CallExpr:
				ftyp = dynamicFuncCallType(pkg.TypesInfo(), n)
				pos, end = n.Lparen, n.Lparen+token.Pos(len("("))

			case *ast.FuncType:
				if !beneathFuncDef(cur) {
					// func type (not def)
					ftyp = pkg.TypesInfo().TypeOf(n)
					pos, end = n.Func, n.Func+token.Pos(len("func"))
				}
			}
			if ftyp == nil {
				continue // missing type information
			}
			if unify(t, ftyp) {
				loc, err := pgf.PosLocation(pos, end)
				if err != nil {
					return nil, err
				}
				locs = append(locs, loc)
			}
		}
	}

	// TODO(adonovan): implement global search

	return locs, nil
}

// funcDefs returns all locations in the workspace that define
// functions of the specified type.
func funcDefs(pkg *cache.Package, t types.Type) ([]protocol.Location, error) {
	var locs []protocol.Location

	// local search
	for _, pgf := range pkg.CompiledGoFiles() {
		for curFn := range pgf.Cursor.Preorder((*ast.FuncDecl)(nil), (*ast.FuncLit)(nil)) {
			fn := curFn.Node()
			var ftyp types.Type
			switch fn := fn.(type) {
			case *ast.FuncDecl:
				ftyp = pkg.TypesInfo().Defs[fn.Name].Type()
			case *ast.FuncLit:
				ftyp = pkg.TypesInfo().TypeOf(fn)
			}
			if ftyp == nil {
				continue // missing type information
			}
			if unify(t, ftyp) {
				pos := fn.Pos()
				loc, err := pgf.PosLocation(pos, pos+token.Pos(len("func")))
				if err != nil {
					return nil, err
				}
				locs = append(locs, loc)
			}
		}
	}

	// TODO(adonovan): implement global search, by analogy with
	// methodsets algorithm.
	//
	// One optimization: if any signature type has free package
	// names, look for matches only in packages among the rdeps of
	// those packages.

	return locs, nil
}

// beneathFuncDef reports whether the specified FuncType cursor is a
// child of Func{Decl,Lit}.
func beneathFuncDef(cur cursor.Cursor) bool {
	ek, _ := cur.Edge()
	switch ek {
	case edge.FuncDecl_Type, edge.FuncLit_Type:
		return true
	}
	return false
}

// dynamicFuncCallType reports whether call is a dynamic (non-method) function call.
// If so, it returns the function type, otherwise nil.
//
// Tested via ../test/marker/testdata/implementation/signature.txt.
func dynamicFuncCallType(info *types.Info, call *ast.CallExpr) types.Type {
	fun := ast.Unparen(call.Fun)
	tv := info.Types[fun]

	// Reject conversion, or call to built-in.
	if !tv.IsValue() {
		return nil
	}

	// Reject call to named func/method.
	if id, ok := fun.(*ast.Ident); ok && is[*types.Func](info.Uses[id]) {
		return nil
	}

	// Reject method selections (T.method() or x.method())
	if sel, ok := fun.(*ast.SelectorExpr); ok {
		seln, ok := info.Selections[sel]
		if !ok || seln.Kind() != types.FieldVal {
			return nil
		}
	}

	// TODO(adonovan): consider x() where x : TypeParam.
	return tv.Type.Underlying() // e.g. x() or x.field()
}

// inToken reports whether pos is within the token of
// the specified position and string.
func inToken(tokPos token.Pos, tokStr string, pos token.Pos) bool {
	return tokPos <= pos && pos <= tokPos+token.Pos(len(tokStr))
}
