gopls/internal: use generic methods in some places

Change-Id: Ib0c6012aa99fe41d48f9a50641fde43f93d7aab4
Reviewed-on: https://go-review.googlesource.com/c/tools/+/821162
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <mark@golang.org>
diff --git a/gopls/internal/golang/codeaction.go b/gopls/internal/golang/codeaction.go
index 937fedc..60fee8c 100644
--- a/gopls/internal/golang/codeaction.go
+++ b/gopls/internal/golang/codeaction.go
@@ -208,12 +208,10 @@
 
 // lazyInit[*T](ctx, req) returns a pointer to an instance of T,
 // calling new(T).init(ctx.req) on the first request.
-//
-// It is conceptually a (generic) method of req.
-func lazyInit[P interface {
+func (req *codeActionsRequest) lazyInit[P interface {
 	init(ctx context.Context, req *codeActionsRequest)
 	*T
-}, T any](ctx context.Context, req *codeActionsRequest) P {
+}, T any](ctx context.Context) P {
 	t := reflect.TypeFor[T]()
 	v, ok := req.lazy[t].(P)
 	if !ok {
@@ -280,7 +278,7 @@
 
 // sourceOrganizeImports produces "Organize Imports" code actions.
 func sourceOrganizeImports(ctx context.Context, req *codeActionsRequest) error {
-	res := lazyInit[*allImportsFixesResult](ctx, req)
+	res := req.lazyInit[*allImportsFixesResult](ctx)
 
 	// Send all of the import edits as one code action
 	// if the file is being organized.
@@ -301,7 +299,7 @@
 	}
 
 	// Process any missing imports and pair them with the diagnostics they fix.
-	res := lazyInit[*allImportsFixesResult](ctx, req)
+	res := req.lazyInit[*allImportsFixesResult](ctx)
 	if res.err != nil {
 		return nil
 	}
diff --git a/gopls/internal/test/marker/codeaction_test.go b/gopls/internal/test/marker/codeaction_test.go
index 9a6e084..48f8b9e 100644
--- a/gopls/internal/test/marker/codeaction_test.go
+++ b/gopls/internal/test/marker/codeaction_test.go
@@ -24,7 +24,7 @@
 		return
 	}
 
-	if end := namedArgFunc(mark, "end", convertNamedArgLocation, protocol.Location{}); end.URI != "" {
+	if end := mark.namedArgFunc("end", convertNamedArgLocation, protocol.Location{}); end.URI != "" {
 		if end.URI != loc.URI {
 			mark.errorf("end marker is in a different file (%s)", filepath.Base(loc.URI.Path()))
 			return
@@ -33,15 +33,15 @@
 	}
 
 	var (
-		edit       = namedArg(mark, "edit", expect.Identifier(""))
-		result     = namedArg(mark, "result", expect.Identifier(""))
-		wantAction = namedArg(mark, "action", expect.Identifier(""))
-		wantErr    = namedArgFunc(mark, "err", convertStringMatcher, stringMatcher{})
-		wantTitle  = namedArgFunc(mark, "title", convertStringMatcher, stringMatcher{})
+		edit       = mark.namedArg("edit", expect.Identifier(""))
+		result     = mark.namedArg("result", expect.Identifier(""))
+		wantAction = mark.namedArg("action", expect.Identifier(""))
+		wantErr    = mark.namedArgFunc("err", convertStringMatcher, stringMatcher{})
+		wantTitle  = mark.namedArgFunc("title", convertStringMatcher, stringMatcher{})
 	)
 
 	var diag *protocol.Diagnostic
-	if re := namedArg(mark, "diag", (*regexp.Regexp)(nil)); re != nil {
+	if re := mark.namedArg("diag", (*regexp.Regexp)(nil)); re != nil {
 		d, ok := removeDiagnostic(mark, loc, false, re)
 		if !ok {
 			mark.errorf("no diagnostic at %v matches %q", loc, re)
diff --git a/gopls/internal/test/marker/marker_test.go b/gopls/internal/test/marker/marker_test.go
index cb3b7ed..7166966 100644
--- a/gopls/internal/test/marker/marker_test.go
+++ b/gopls/internal/test/marker/marker_test.go
@@ -559,7 +559,7 @@
 }
 
 // namedArg returns the named argument for name, or the default value.
-func namedArg[T any](mark marker, name string, dflt T) T {
+func (mark marker) namedArg[T any](name string, dflt T) T {
 	if v, ok := mark.note.NamedArgs[name]; ok {
 		if e, ok := v.(T); ok {
 			return e
@@ -575,7 +575,7 @@
 	return dflt
 }
 
-func namedArgFunc[T any](mark marker, name string, f func(marker, any) (T, error), dflt T) T {
+func (mark marker) namedArgFunc[T any](name string, f func(marker, any) (T, error), dflt T) T {
 	if v, ok := mark.note.NamedArgs[name]; ok {
 		if v2, err := f(mark, v); err == nil {
 			return v2
@@ -1753,7 +1753,7 @@
 
 // typedefMarker implements the @typedef marker.
 func typedefMarker(mark marker, loc protocol.Location, want ...protocol.Location) {
-	wantErr := namedArgFunc(mark, "err", convertStringMatcher, stringMatcher{})
+	wantErr := mark.namedArgFunc("err", convertStringMatcher, stringMatcher{})
 
 	env := mark.run.env
 	got, err := env.Editor.TypeDefinitions(env.Ctx, loc)
@@ -1936,7 +1936,7 @@
 // diagMarker implements the @diag marker. It eliminates diagnostics from
 // the observed set in mark.test.
 func diagMarker(mark marker, loc protocol.Location, re *regexp.Regexp) {
-	exact := namedArg(mark, "exact", false)
+	exact := mark.namedArg("exact", false)
 	if _, ok := removeDiagnostic(mark, loc, exact, re); !ok {
 		mark.errorf("no diagnostic at %v matches %q", loc, re)
 	}
@@ -2361,7 +2361,7 @@
 
 // implementationMarker implements the @implementation marker.
 func implementationMarker(mark marker, src protocol.Location, want ...protocol.Location) {
-	wantErr := namedArgFunc(mark, "err", convertStringMatcher, stringMatcher{})
+	wantErr := mark.namedArgFunc("err", convertStringMatcher, stringMatcher{})
 
 	got, err := mark.server().Implementation(mark.ctx(), &protocol.ImplementationParams{
 		TextDocumentPositionParams: protocol.LocationTextDocumentPositionParams(src),
@@ -2413,7 +2413,7 @@
 		args[k] = substitutePaths(v)
 	}
 
-	if loc := namedArg(mark, "location", protocol.Location{}); loc != (protocol.Location{}) {
+	if loc := mark.namedArg("location", protocol.Location{}); loc != (protocol.Location{}) {
 		args["location"] = loc
 	}
 
@@ -2447,7 +2447,7 @@
 	// include absolute file paths in generated diffs.
 	got = strings.ReplaceAll(got, filepath.ToSlash(mark.run.env.Sandbox.Workdir.RootURI().Path()), "$WORKDIR")
 
-	output := namedArg(mark, "output", expect.Identifier(""))
+	output := mark.namedArg("output", expect.Identifier(""))
 	golden := mark.getGolden(output)
 	want, _ := golden.Get(mark.T(), "", []byte(got))
 	if diff := compare.Text(string(want), got); diff != "" {
@@ -2561,7 +2561,7 @@
 	want := &protocol.PrepareRenameResult{
 		Placeholder: placeholder,
 	}
-	if span := namedArg(mark, "span", protocol.Location{}); span != (protocol.Location{}) {
+	if span := mark.namedArg("span", protocol.Location{}); span != (protocol.Location{}) {
 		want.Range = span.Range
 	} else {
 		got.Range = protocol.Range{} // ignore Range