This test checks basic completion snippet support.

-- flags --
-ignore_extra_diags

-- go.mod --
module golang.org/lsptests/snippet

-- snippet.go --
package snippets

// Pre-set this marker, as we don't have a "source" for it in this package.
// The comment is used to create a synthetic completion item.
//
// TODO(rfindley): allow completion markers to refer to ad-hoc items inline,
// without this trick.
/* Error() */ //@item(Error, "Error", "func() string", "method")

type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type")

func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func")
func bar(fn func()) func()    {} //@item(snipBar, "bar", "func(fn func())", "func")
func baz(at AliasType, b bool) {} //@item(snipBaz, "baz", "func(at AliasType, b bool)", "func")

type Foo struct {
	Bar int //@item(snipFieldBar, "Bar", "int", "field")
	Func func(at AliasType) error //@item(snipFieldFunc, "Func", "func(at AliasType) error", "field")
}

func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method")
func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method")
func (Foo) BazBaz(at AliasType) func() {} //@item(snipMethodBazBaz, "BazBaz", "func(at AliasType) func()", "method")

func _() {
	f //@snippet(" //", snipFoo, "foo(${1:})")

	bar //@snippet(" //", snipBar, "bar(${1:})")

	baz //@snippet(" //", snipBaz, "baz(${1:})")
	baz() //@signature("(", "baz(at AliasType, b bool)", 0)

	bar(nil) //@snippet("(", snipBar, "bar")
	bar(ba) //@snippet(")", snipBar, "bar(${1:})")
	var f Foo
	bar(f.Ba) //@snippet(")", snipMethodBaz, "Baz()")
	(bar)(nil) //@snippet(")", snipBar, "bar(${1:})")
	(f.Ba)() //@snippet(")", snipMethodBaz, "Baz()")

	Foo{
		B //@snippet(" //", snipFieldBar, "Bar: ${1:},")
	}

	Foo{
		F //@snippet(" //", snipFieldFunc, "Func: ${1:},")
	}

	Foo{B} //@snippet("}", snipFieldBar, "Bar: ${1:}")
	Foo{} //@snippet("}", snipFieldBar, "Bar: ${1:}")

	Foo{Foo{}.B} //@snippet("} ", snipFieldBar, "Bar")

	var err error
	err.Error() //@snippet("E", Error, "Error()")
	f.Baz()     //@snippet("B", snipMethodBaz, "Baz()")

	f.Baz()     //@snippet("(", snipMethodBazBar, "BazBar")

	f.Baz()     //@snippet("B", snipMethodBazBaz, "BazBaz(${1:})")
}

func _() {
	type bar struct {
		a int
		b float64 //@item(snipBarB, "b", "float64")
	}
	bar{b} //@snippet("}", snipBarB, "b: ${1:}")
}
