This test exercises the textDocument/typeDefinition action.

-- typedef.go --
package typedef

type Struct struct { //@loc(Struct, "Struct"),
	Field string
}

type Int int //@loc(Int, "Int")

func _() {
	var (
		value Struct
		point *Struct
	)
	_ = value //@typedef(re"value()", Struct)
	_ = point //@typedef(re"point()", Struct)

	var (
		array   [3]Struct
		slice   []Struct
		ch      chan Struct
		complex [3]chan *[5][]Int
	)
	_ = array   //@typedef(re"array()", Struct)
	_ = slice   //@typedef(re"slice()", Struct)
	_ = ch      //@typedef(re"ch()", Struct)
	_ = complex //@typedef(re"complex()", Int)

	var s struct {
		x struct {
			xx struct {
				field1 []Struct
				field2 []Int
			}
		}
	}
	_ = s.x.xx.field1 //@typedef(re"field1()", Struct)
	_ = s.x.xx.field2 //@typedef(re"field2()", Int)
}

// type def returns function return types' location.

func F1() Int                              { return 0 }
func F2() error                            { return nil }
func F3() (Int, float64)                   { return 0, 0 }
func F4() (Int, error)                     { return 0, nil }
func F5() (Struct, int, bool, error)       { return Struct{}, 0, false, nil }
func F6() (**int, Int, bool, *error)       { return nil, 0, false, nil }
func F7() (int, float64, error, Struct)    { return 0, 0, nil, Struct{} }
func F8() (int, float64, ***Struct, error) { return 0, 0, nil, nil }

// type def returns error.

func E1() {}
func E2() (int, bool) { return 0, true }

func _() {
	F1() //@typedef(re"F1()", Int)
	F2() //@typedef(re"F2()", BUILTIN)
	F3() //@typedef(re"F3()", Int, BUILTIN)
	F4() //@typedef(re"F4()", Int, BUILTIN)
	F5() //@typedef(re"F5()", Struct, BUILTIN, BUILTIN, BUILTIN)
	F6() //@typedef(re"F6()", BUILTIN, Int, BUILTIN, BUILTIN)
	F7() //@typedef(re"F7()", BUILTIN, BUILTIN, BUILTIN, Struct)
	F8() //@typedef(re"F8()", BUILTIN, BUILTIN, Struct, BUILTIN)

	E1() //@typedef(re"E1()", err="cannot find type name(s)")
	E2() //@typedef(re"E2()", BUILTIN, BUILTIN)

	f := func() Int { return 0 }
	f() //@typedef(re"f()", Int)
}

// https://github.com/golang/go/issues/38589#issuecomment-620350922
func _() {
	type myFunc func(int) Int //@loc(myFunc, "myFunc")

	var foo myFunc
	_ = foo() //@typedef(re"foo()", myFunc), diag(")", re"not enough arguments")
}

func _() {
	// Any expression is fair game for typeDefinition;
	// it needn't be a referring identifier.
	// In this example it's the r-paren of a call expr.
	func() Struct {
		panic(0)
	}() //@typedef(re"\\)()", Struct)

	// And in this one, it's the composite literal enclosing the
	// KeyValueExpr denoted by the colon (which must not be adjacent
	// to either they key or the value!).
	_ = Struct{Field  :  ""} //@typedef(re":", Struct)
}

// edge case: type-switch implicits.
// y in "switch y" has no type; use x instead.
func _(x any) {
	switch y := x.(type) { //@typedef(re"y()", BUILTIN)
	case Int:
		_ = y //@typedef(re"y()", Int)
	case Struct:
		_ = y //@typedef(re"y()", Struct)
	}
}
