This test checks basic completion snippet support, using placeholders.

Unlike the old marker tests, the new marker tests assume static configuration
(as defined by settings.json), and therefore there is duplication between this
test and snippet.txt. This is a price we pay so that we don't have to mutate
the server during testing.

-- flags --
-ignore_extra_diags

-- settings.json --
{
	"usePlaceholders": true
}

-- 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.
/* 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(re"() \\/\\/", snipFoo, "foo(${1:i int}, ${2:b bool})")

	bar //@snippet(re"() \\/\\/", snipBar, "bar(${1:fn func()})")

	baz //@snippet(re"() \\/\\/", snipBaz, "baz(${1:at AliasType}, ${2:b bool})")

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

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

	Foo{
		F //@snippet(re"() \\/\\/", snipFieldFunc, "Func: ${1:func(at AliasType) error},")
	}

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

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

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

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

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

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