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