Skip to content

Commit 4d89d8a

Browse files
committed
all: merge master (82473ce) into gopls-release-branch.0.19
Merge List: + 2025-06-04 82473ce gopls/doc/release: tweak v0.19 + 2025-06-04 f3c581f gopls/internal/protocol: add DocumentURI.Base accessor + 2025-06-04 d9bacab gopls/internal/server: improve "editing generated file" warning + 2025-06-04 1afeefa internal/mcp: unexport FileResourceHandler + 2025-06-04 33d5988 gopls/internal/server: Organize Imports of generated files + 2025-06-04 cb39a5f gopls/internal/golang: Format generated files + 2025-06-04 e43ca0c internal/mcp: validate tool input schemas + 2025-06-04 61f37dc gopls: use new gomodcache index + 2025-06-04 fed8cc8 internal/refactor: keep comments with same import + 2025-06-03 c7873a3 gopls/internal/golang: eliminate dot import: skip keyed fields Updates golang/go#73965 Change-Id: I0a76ac5e1fbfc367635a685ac3f69ff1ea874b99
2 parents af7c7d5 + 82473ce commit 4d89d8a

36 files changed

+591
-177
lines changed

gopls/doc/release/v0.19.0.md

Lines changed: 102 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,15 @@
11
# Configuration Changes
22

3-
- The `gopls check` subcommant now accepts a `-severity` flag to set a minimum
3+
- The `gopls check` subcommand now accepts a `-severity` flag to set a minimum
44
severity for the diagnostics it reports. By default, the minimum severity
55
is "warning", so `gopls check` may report fewer diagnostics than before. Set
66
`-severity=hint` to reproduce the previous behavior.
77

8-
# New features
8+
# Navigation features
99

10-
## "Rename" of method receivers
10+
## "Implementations" supports signature types (within same package)
1111

12-
The Rename operation, when applied to the declaration of a method
13-
receiver, now also attempts to rename the receivers of all other
14-
methods associated with the same named type. Each other receiver that
15-
cannot be fully renamed is quietly skipped.
16-
17-
Renaming a _use_ of a method receiver continues to affect only that
18-
variable.
19-
20-
```go
21-
type Counter struct { x int }
22-
23-
Rename here to affect only this method
24-
25-
func (c *Counter) Inc() { c.x++ }
26-
func (c *Counter) Dec() { c.x++ }
27-
28-
Rename here to affect all methods
29-
```
30-
31-
## Many `staticcheck` analyzers are enabled by default
32-
33-
Slightly more than half of the analyzers in the
34-
[Staticcheck](https://staticcheck.dev/docs/checks) suite are now
35-
enabled by default. This subset has been chosen for precision and
36-
efficiency.
37-
38-
Previously, Staticcheck analyzers (all of them) would be run only if
39-
the experimental `staticcheck` boolean option was set to `true`. This
40-
value continues to enable the complete set, and a value of `false`
41-
continues to disable the complete set. Leaving the option unspecified
42-
enables the preferred subset of analyzers.
43-
44-
Staticcheck analyzers, like all other analyzers, can be explicitly
45-
enabled or disabled using the `analyzers` configuration setting; this
46-
setting now takes precedence over the `staticcheck` setting, so,
47-
regardless of what value of `staticcheck` you use (true/false/unset),
48-
you can make adjustments to your preferred set of analyzers.
49-
50-
## "Inefficient recursive iterator" analyzer
51-
52-
A common pitfall when writing a function that returns an iterator
53-
(iter.Seq) for a recursive data type is to recursively call the
54-
function from its own implementation, leading to a stack of nested
55-
coroutines, which is inefficient.
56-
57-
The new `recursiveiter` analyzer detects such mistakes; see
58-
[https://golang.org/x/tools/gopls/internal/analysis/recursiveiter](its
59-
documentation) for details, including tips on how to define simple and
60-
efficient recursive iterators.
61-
62-
## "Inefficient range over maps.Keys/Values" analyzer
63-
64-
This analyzer detects redundant calls to `maps.Keys` or `maps.Values`
65-
as the operand of a range loop; maps can of course be ranged over
66-
directly.
67-
68-
## "Implementations" supports signature types
12+
<!-- golang/go#56572 -->
6913

7014
The Implementations query reports the correspondence between abstract
7115
and concrete types and their methods based on their method sets.
@@ -89,9 +33,11 @@ Queries using method-sets should be invoked on the type or method name,
8933
and queries using signatures should be invoked on a `func` or `(` token.
9034

9135
Only the local (same-package) algorithm is currently supported.
92-
TODO: implement global.
36+
(https://go.dev/issue/56572 tracks the global algorithm.)
37+
38+
## "Go to Implementation" reports interface-to-interface relations
9339

94-
## Go to Implementation
40+
<!-- golang/go#68641 -->
9541

9642
The "Go to Implementation" operation now reports relationships between
9743
interfaces. Gopls now uses the concreteness of the query type to
@@ -126,19 +72,102 @@ of the selected named type.
12672

12773
<img title="Type Hierarchy: subtypes of io.Writer" src="../assets/subtypes.png" width="400">
12874

129-
## "Eliminate dot import" code action
13075

131-
This code action, available on a dotted import, will offer to replace
132-
the import with a regular one and qualify each use of the package
133-
with its name.
76+
# Editing features
13477

135-
### Auto-complete package clause for new Go files
78+
## Completion: auto-complete package clause for new Go files
13679

13780
Gopls now automatically adds the appropriate `package` clause to newly created Go files,
13881
so that you can immediately get started writing the interesting part.
13982

14083
It requires client support for `workspace/didCreateFiles`
14184

85+
## New GOMODCACHE index for faster Organize Imports and unimported completions
86+
87+
By default, gopls now builds and maintains a persistent index of
88+
packages in the module cache (GOMODCACHE). The operations of Organize
89+
Imports and completion of symbols from unimported pacakges are an
90+
order of magnitude faster.
91+
92+
To revert to the old behavior, set the `importsSource` option (whose
93+
new default is `"gopls"`) to `"goimports"`. Users who don't want the
94+
module cache used at all for imports or completions can change the
95+
option to "off".
96+
97+
# Analysis features
98+
99+
## Most `staticcheck` analyzers are enabled by default
100+
101+
Slightly more than half of the analyzers in the
102+
[Staticcheck](https://staticcheck.dev/docs/checks) suite are now
103+
enabled by default. This subset has been chosen for precision and
104+
efficiency.
105+
106+
Previously, Staticcheck analyzers (all of them) would be run only if
107+
the experimental `staticcheck` boolean option was set to `true`. This
108+
value continues to enable the complete set, and a value of `false`
109+
continues to disable the complete set. Leaving the option unspecified
110+
enables the preferred subset of analyzers.
111+
112+
Staticcheck analyzers, like all other analyzers, can be explicitly
113+
enabled or disabled using the `analyzers` configuration setting; this
114+
setting now takes precedence over the `staticcheck` setting, so,
115+
regardless of what value of `staticcheck` you use (true/false/unset),
116+
you can make adjustments to your preferred set of analyzers.
117+
118+
## `recursiveiter`: "inefficient recursive iterator"
119+
120+
A common pitfall when writing a function that returns an iterator
121+
(`iter.Seq`) for a recursive data type is to recursively call the
122+
function from its own implementation, leading to a stack of nested
123+
coroutines, which is inefficient.
124+
125+
The new `recursiveiter` analyzer detects such mistakes; see
126+
[its documentation](https://golang.org/x/tools/gopls/internal/analysis/recursiveiter)
127+
for details, including tips on how to define simple and efficient
128+
recursive iterators.
129+
130+
## `maprange`: "inefficient range over maps.Keys/Values"
131+
132+
The new `maprange` analyzer detects redundant calls to `maps.Keys` or
133+
`maps.Values` as the operand of a range loop; maps can of course be
134+
ranged over directly. See
135+
[its documentation](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/maprange)
136+
for details).
137+
138+
# Code transformation features
139+
140+
## Rename method receivers
141+
142+
<!-- golang/go#41892 -->
143+
144+
The Rename operation, when applied to the declaration of a method
145+
receiver, now also attempts to rename the receivers of all other
146+
methods associated with the same named type. Each other receiver that
147+
cannot be fully renamed is quietly skipped.
148+
149+
Renaming a _use_ of a method receiver continues to affect only that
150+
variable.
151+
152+
```go
153+
type Counter struct { x int }
154+
155+
Rename here to affect only this method
156+
157+
func (c *Counter) Inc() { c.x++ }
158+
func (c *Counter) Dec() { c.x++ }
159+
160+
Rename here to affect all methods
161+
```
162+
163+
## "Eliminate dot import" code action
164+
165+
<!-- golang/go#70319 -->
166+
167+
This code action, available on a dotted import, will offer to replace
168+
the import with a regular one and qualify each use of the package
169+
with its name.
170+
142171
## Add/remove tags from struct fields
143172

144173
Gopls now provides two new code actions, available on an entire struct
@@ -156,6 +185,8 @@ type Info struct {
156185

157186
## Inline local variable
158187

188+
<!-- golang/go#70085 -->
189+
159190
The new `refactor.inline.variable` code action replaces a reference to
160191
a local variable by that variable's initializer expression. For
161192
example, when applied to `s` in `println(s)`:
@@ -173,3 +204,7 @@ func f(x int) {
173204
println(fmt.Sprintf("+%d", x))
174205
}
175206
```
207+
208+
Only a single reference is replaced; issue https://go.dev/issue/70085
209+
tracks the feature to "inline all" uses of the variable and eliminate
210+
it.

gopls/internal/cache/snapshot.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,7 @@ https://github.com/golang/tools/blob/master/gopls/doc/workspace.md.`, modDir, fi
14211421
fix = `This file may be excluded due to its build tags; try adding "-tags=<build tag>" to your gopls "buildFlags" configuration
14221422
See the documentation for more information on working with build tags:
14231423
https://github.com/golang/tools/blob/master/gopls/doc/settings.md#buildflags.`
1424-
} else if strings.Contains(filepath.Base(fh.URI().Path()), "_") {
1424+
} else if strings.Contains(fh.URI().Base(), "_") {
14251425
fix = `This file may be excluded due to its GOOS/GOARCH, or other build constraints.`
14261426
} else {
14271427
fix = `This file is ignored by your gopls build.` // we don't know why

gopls/internal/cache/workspace.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818

1919
// isGoWork reports if uri is a go.work file.
2020
func isGoWork(uri protocol.DocumentURI) bool {
21-
return filepath.Base(uri.Path()) == "go.work"
21+
return uri.Base() == "go.work"
2222
}
2323

2424
// goWorkModules returns the URIs of go.mod files named by the go.work file.
@@ -63,7 +63,7 @@ func localModFiles(relativeTo string, goWorkOrModPaths []string) map[protocol.Do
6363

6464
// isGoMod reports if uri is a go.mod file.
6565
func isGoMod(uri protocol.DocumentURI) bool {
66-
return filepath.Base(uri.Path()) == "go.mod"
66+
return uri.Base() == "go.mod"
6767
}
6868

6969
// isWorkspaceFile reports if uri matches a set of globs defined in workspaceFiles

gopls/internal/cmd/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ func (f *cmdFile) spanRange(s span) (protocol.Range, error) {
903903
// case-sensitive directories. The authoritative answer
904904
// requires querying the file system, and we don't want
905905
// to do that.
906-
if !strings.EqualFold(filepath.Base(string(f.mapper.URI)), filepath.Base(string(s.URI()))) {
906+
if !strings.EqualFold(f.mapper.URI.Base(), s.URI().Base()) {
907907
return protocol.Range{}, bugpkg.Errorf("mapper is for file %q instead of %q", f.mapper.URI, s.URI())
908908
}
909909
start, err := pointPosition(f.mapper, s.Start())

gopls/internal/golang/addtest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ func AddTestForFunc(ctx context.Context, snapshot *cache.Snapshot, loc protocol.
265265
return nil, err
266266
}
267267

268-
testBase := strings.TrimSuffix(filepath.Base(loc.URI.Path()), ".go") + "_test.go"
268+
testBase := strings.TrimSuffix(loc.URI.Base(), ".go") + "_test.go"
269269
goTestFileURI := protocol.URIFromPath(filepath.Join(loc.URI.DirPath(), testBase))
270270

271271
testFH, err := snapshot.ReadFile(ctx, goTestFileURI)

gopls/internal/golang/call_hierarchy.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"go/ast"
1212
"go/token"
1313
"go/types"
14-
"path/filepath"
1514

1615
"golang.org/x/tools/go/ast/astutil"
1716
"golang.org/x/tools/go/types/typeutil"
@@ -59,7 +58,7 @@ func PrepareCallHierarchy(ctx context.Context, snapshot *cache.Snapshot, fh file
5958
Name: obj.Name(),
6059
Kind: protocol.Function,
6160
Tags: []protocol.SymbolTag{},
62-
Detail: fmt.Sprintf("%s • %s", obj.Pkg().Path(), filepath.Base(declLoc.URI.Path())),
61+
Detail: fmt.Sprintf("%s • %s", obj.Pkg().Path(), declLoc.URI.Base()),
6362
URI: declLoc.URI,
6463
Range: rng,
6564
SelectionRange: rng,
@@ -182,7 +181,7 @@ func enclosingNodeCallItem(ctx context.Context, snapshot *cache.Snapshot, pkgPat
182181
Name: name,
183182
Kind: kind,
184183
Tags: []protocol.SymbolTag{},
185-
Detail: fmt.Sprintf("%s • %s", pkgPath, filepath.Base(fh.URI().Path())),
184+
Detail: fmt.Sprintf("%s • %s", pkgPath, fh.URI().Base()),
186185
URI: loc.URI,
187186
Range: rng,
188187
SelectionRange: rng,
@@ -283,7 +282,7 @@ func OutgoingCalls(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle
283282
Name: obj.Name(),
284283
Kind: protocol.Function,
285284
Tags: []protocol.SymbolTag{},
286-
Detail: fmt.Sprintf("%s • %s", obj.Pkg().Path(), filepath.Base(loc.URI.Path())),
285+
Detail: fmt.Sprintf("%s • %s", obj.Pkg().Path(), loc.URI.Base()),
287286
URI: loc.URI,
288287
Range: loc.Range,
289288
SelectionRange: loc.Range,

gopls/internal/golang/codeaction.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ import (
1111
"go/ast"
1212
"go/token"
1313
"go/types"
14-
"path/filepath"
1514
"reflect"
1615
"slices"
1716
"strings"
1817

1918
"golang.org/x/tools/go/ast/astutil"
19+
"golang.org/x/tools/go/ast/edge"
2020
"golang.org/x/tools/go/ast/inspector"
2121
"golang.org/x/tools/gopls/internal/analysis/fillstruct"
2222
"golang.org/x/tools/gopls/internal/analysis/fillswitch"
@@ -733,11 +733,15 @@ func refactorRewriteEliminateDotImport(ctx context.Context, req *codeActionsRequ
733733
continue
734734
}
735735

736-
// Only qualify unqualified identifiers (due to dot imports).
736+
// Only qualify unqualified identifiers (due to dot imports)
737+
// that reference package-level symbols.
737738
// All other references to a symbol imported from another package
738739
// are nested within a select expression (pkg.Foo, v.Method, v.Field).
739-
if is[*ast.SelectorExpr](curId.Parent().Node()) {
740-
continue
740+
if ek, _ := curId.ParentEdge(); ek == edge.SelectorExpr_Sel {
741+
continue // qualified identifier (pkg.X) or selector (T.X or e.X)
742+
}
743+
if !typesinternal.IsPackageLevel(use) {
744+
continue // unqualified field reference T{X: ...}
741745
}
742746

743747
// Make sure that the package name will not be shadowed by something else in scope.
@@ -1103,7 +1107,7 @@ func toggleCompilerOptDetails(ctx context.Context, req *codeActionsRequest) erro
11031107

11041108
title := fmt.Sprintf("%s compiler optimization details for %q",
11051109
cond(req.snapshot.WantCompilerOptDetails(dir), "Hide", "Show"),
1106-
filepath.Base(dir.Path()))
1110+
dir.Base())
11071111
cmd := command.NewGCDetailsCommand(title, req.fh.URI())
11081112
req.addCommandAction(cmd, false)
11091113
}

gopls/internal/golang/completion/unimported.go

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,21 +52,6 @@ func (c *completer) unimported(ctx context.Context, pkgname metadata.PackageName
5252
}
5353
}
5454
// do the stdlib next.
55-
// For now, use the workspace version of stdlib packages
56-
// to get function snippets. CL 665335 will fix this.
57-
var x []metadata.PackageID
58-
for _, mp := range stdpkgs {
59-
if slices.Contains(wsIDs, metadata.PackageID(mp)) {
60-
x = append(x, metadata.PackageID(mp))
61-
}
62-
}
63-
if len(x) > 0 {
64-
items := c.pkgIDmatches(ctx, x, pkgname, prefix)
65-
if c.scoreList(items) {
66-
return
67-
}
68-
}
69-
// just use the stdlib
7055
items := c.stdlibMatches(stdpkgs, pkgname, prefix)
7156
if c.scoreList(items) {
7257
return
@@ -164,7 +149,7 @@ func (c *completer) pkgIDmatches(ctx context.Context, ids []metadata.PackageID,
164149
}
165150
kind = protocol.FunctionCompletion
166151
detail = fmt.Sprintf("func (from %q)", pkg.PkgPath)
167-
case protocol.Variable:
152+
case protocol.Variable, protocol.Struct:
168153
kind = protocol.VariableCompletion
169154
detail = fmt.Sprintf("var (from %q)", pkg.PkgPath)
170155
case protocol.Constant:
@@ -264,6 +249,9 @@ func (c *completer) modcacheMatches(pkg metadata.PackageName, prefix string) ([]
264249
case modindex.Const:
265250
kind = protocol.ConstantCompletion
266251
detail = fmt.Sprintf("const (from %s)", cand.ImportPath)
252+
case modindex.Type: // might be a type alias
253+
kind = protocol.VariableCompletion
254+
detail = fmt.Sprintf("type (from %s)", cand.ImportPath)
267255
default:
268256
continue
269257
}

gopls/internal/golang/format.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,6 @@ func Format(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle) ([]pr
4040
return nil, err
4141
}
4242

43-
// Generated files shouldn't be edited. So, don't format them.
44-
if ast.IsGenerated(pgf.File) {
45-
return nil, fmt.Errorf("can't format %q: file is generated", fh.URI().Path())
46-
}
47-
4843
// Even if this file has parse errors, it might still be possible to format it.
4944
// Using format.Node on an AST with errors may result in code being modified.
5045
// Attempt to format the source of this file instead.

0 commit comments

Comments
 (0)