Skip to content

Commit b7532e6

Browse files
committed
gopls/doc: update relnotes for v0.17.0
Update release notes and feature documentation for change signature refactoring and support changes. For golang/go#70301 Change-Id: I1a4543e317f1016cdd5631640307b60435f1b23e Reviewed-on: https://go-review.googlesource.com/c/tools/+/633376 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com>
1 parent 44670c7 commit b7532e6

File tree

3 files changed

+187
-56
lines changed

3 files changed

+187
-56
lines changed

gopls/doc/features/transformation.md

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ formatting, simplifications), code repair (fixes), and editing support
66
(filling in struct literals and switch statements).
77

88
Code transformations are not a single category in the LSP:
9+
910
- A few, such as Formatting and Rename, are primary operations in the
1011
protocol.
1112
- Some transformations are exposed through [Code Lenses](../codelenses.md),
@@ -43,6 +44,7 @@ or to cause the server to send other requests to the client,
4344
such as a `showDocument` request to open a report in a web browser.
4445

4546
The main difference between code lenses and code actions is this:
47+
4648
- a `codeLens` request obtains commands for the entire file.
4749
Each command specifies its applicable source range,
4850
and typically appears as an annotation on that source range.
@@ -82,6 +84,8 @@ Gopls supports the following code actions:
8284
- [`refactor.rewrite.joinLines`](#refactor.rewrite.joinLines)
8385
- [`refactor.rewrite.removeUnusedParam`](#refactor.rewrite.removeUnusedParam)
8486
- [`refactor.rewrite.splitLines`](#refactor.rewrite.splitLines)
87+
- [`refactor.rewrite.moveParamLeft`](#refactor.rewrite.moveParamLeft)
88+
- [`refactor.rewrite.moveParamRight`](#refactor.rewrite.moveParamRight)
8589

8690
Gopls reports some code actions twice, with two different kinds, so
8791
that they appear in multiple UI elements: simplifications,
@@ -99,6 +103,7 @@ that, in the course of reporting a diagnostic about a problem,
99103
also suggest a fix.
100104
A `codeActions` request will return any fixes accompanying diagnostics
101105
for the current selection.
106+
102107
<!-- Some gopls-internal analyzers compute fixes lazily by
103108
reporting an empty list of TextEdits and a Diagnostic.Category
104109
recognized by gopls that enables corresponding logic in the
@@ -117,6 +122,7 @@ for the current selection.
117122
-->
118123

119124
Caveats:
125+
120126
- Many of gopls code transformations are limited by Go's syntax tree
121127
representation, which currently records comments not in the tree
122128
but in a side table; consequently, transformations such as Extract
@@ -158,10 +164,12 @@ Most clients are configured to format files and organize imports
158164
whenever a file is saved.
159165

160166
Settings:
167+
161168
- The [`gofumpt`](../settings.md#gofumpt) setting causes gopls to use an
162169
alternative formatter, [`github.com/mvdan/gofumpt`](https://pkg.go.dev/mvdan.cc/gofumpt).
163170

164171
Client support:
172+
165173
- **VS Code**: Formats on save by default. Use `Format document` menu item (`⌥⇧F`) to invoke manually.
166174
- **Emacs + eglot**: Use `M-x eglot-format-buffer` to format. Attach it to `before-save-hook` to format on save. For formatting combined with organize-imports, many users take the legacy approach of setting `"goimports"` as their `gofmt-command` using [go-mode](https://github.com/dominikh/go-mode.el), and adding `gofmt-before-save` to `before-save-hook`. An LSP-based solution requires code such as https://github.com/joaotavora/eglot/discussions/1409.
167175
- **CLI**: `gopls format file.go`
@@ -194,6 +202,7 @@ Settings:
194202
should appear after standard and third-party packages in the sort order.
195203

196204
Client support:
205+
197206
- **VS Code**: automatically invokes `source.organizeImports` before save.
198207
To disable it, use the snippet below, and invoke the "Organize Imports" command manually as needed.
199208
```
@@ -243,7 +252,7 @@ boolean.
243252

244253
**Method receivers**: When testing a method `T.F` or `(*T).F`, the test must
245254
construct an instance of T to pass as the receiver. Gopls searches the package
246-
for a suitable function that constructs a value of type T or *T, optionally with
255+
for a suitable function that constructs a value of type T or \*T, optionally with
247256
an error, preferring a function named `NewT`.
248257

249258
**Imports**: Gopls adds missing imports to the test file, using the last
@@ -305,9 +314,10 @@ Similar problems may arise with packages that use reflection, such as
305314
judgment and testing.
306315

307316
Some tips for best results:
317+
308318
- There is currently no special support for renaming all receivers of
309319
a family of methods at once, so you will need to rename one receiver
310-
one at a time (golang/go#41892).
320+
one at a time (golang/go#41892).
311321
- The safety checks performed by the Rename algorithm require type
312322
information. If the program is grossly malformed, there may be
313323
insufficient information for it to run (golang/go#41870),
@@ -328,12 +338,12 @@ in the latter half of this 2015 GothamGo talk:
328338
[Using go/types for Code Comprehension and Refactoring Tools](https://www.youtube.com/watch?v=p_cz7AxVdfg).
329339

330340
Client support:
341+
331342
- **VS Code**: Use "[Rename symbol](https://code.visualstudio.com/docs/editor/editingevolved#_rename-symbol)" menu item (`F2`).
332343
- **Emacs + eglot**: Use `M-x eglot-rename`, or `M-x go-rename` from [go-mode](https://github.com/dominikh/go-mode.el).
333344
- **Vim + coc.nvim**: Use the `coc-rename` command.
334345
- **CLI**: `gopls rename file.go:#offset newname`
335346

336-
337347
<a name='refactor.extract'></a>
338348
## `refactor.extract`: Extract function/method/variable
339349

@@ -392,7 +402,6 @@ The following Extract features are planned for 2024 but not yet supported:
392402
interface type with all the methods of the selected concrete type;
393403
see golang/go#65721 and golang/go#46665.
394404

395-
396405
<a name='refactor.extract.toNewFile'></a>
397406
## `refactor.extract.toNewFile`: Extract declarations to new file
398407

@@ -409,15 +418,16 @@ first token of the declaration, such as `func` or `type`.
409418
![Before: select the declarations to move](../assets/extract-to-new-file-before.png)
410419
![After: the new file is based on the first symbol name](../assets/extract-to-new-file-after.png)
411420

412-
413421
<a name='refactor.inline.call'></a>
422+
414423
## `refactor.inline.call`: Inline call to function
415424

416425
For a `codeActions` request where the selection is (or is within) a
417426
call of a function or method, gopls will return a command of kind
418427
`refactor.inline.call`, whose effect is to inline the function call.
419428

420429
The screenshots below show a call to `sum` before and after inlining:
430+
421431
<!-- source code used for images:
422432
423433
func six() int {
@@ -432,6 +442,7 @@ func sum(values ...int) int {
432442
return total
433443
}
434444
-->
445+
435446
![Before: select Refactor... Inline call to sum](../inline-before.png)
436447
![After: the call has been replaced by the sum logic](../inline-after.png)
437448

@@ -484,13 +495,16 @@ func f(s string) {
484495
fmt.Println(s)
485496
}
486497
```
498+
487499
a call `f("hello")` will be inlined to:
500+
488501
```go
489502
func() {
490503
defer fmt.Println("goodbye")
491504
fmt.Println("hello")
492505
}()
493506
```
507+
494508
Although the parameter was eliminated, the function call remains.
495509

496510
An inliner is a bit like an optimizing compiler.
@@ -539,18 +553,17 @@ Here are some of the technical challenges involved in sound inlining:
539553
`Printf` by qualified references such as `fmt.Printf`, and add an
540554
import of package `fmt` as needed.
541555

542-
- **Implicit conversions:** When passing an argument to a function, it
543-
is implicitly converted to the parameter type.
544-
If we eliminate the parameter variable, we don't want to
545-
lose the conversion as it may be important.
546-
For example, in `func f(x any) { y := x; fmt.Printf("%T", &y) }` the
547-
type of variable y is `any`, so the program prints `"*interface{}"`.
548-
But if inlining the call `f(1)` were to produce the statement `y :=
549-
1`, then the type of y would have changed to `int`, which could
550-
cause a compile error or, as in this case, a bug, as the program
551-
now prints `"*int"`. When the inliner substitutes a parameter variable
552-
by its argument value, it may need to introduce explicit conversions
553-
of each value to the original parameter type, such as `y := any(1)`.
556+
- **Implicit conversions:** When passing an argument to a function, it is
557+
implicitly converted to the parameter type. If we eliminate the parameter
558+
variable, we don't want to lose the conversion as it may be important. For
559+
example, in `func f(x any) { y := x; fmt.Printf("%T", &y) }` the type of
560+
variable y is `any`, so the program prints `"*interface{}"`. But if inlining
561+
the call `f(1)` were to produce the statement `y := 1`, then the type of y
562+
would have changed to `int`, which could cause a compile error or, as in this
563+
case, a bug, as the program now prints `"*int"`. When the inliner substitutes
564+
a parameter variable by its argument value, it may need to introduce explicit
565+
conversions of each value to the original parameter type, such as `y :=
566+
any(1)`.
554567

555568
- **Last reference:** When an argument expression has no effects
556569
and its corresponding parameter is never used, the expression
@@ -577,6 +590,7 @@ code actions whose kinds are children of `refactor.rewrite`.
577590
The [`unusedparams` analyzer](../analyzers.md#unusedparams) reports a
578591
diagnostic for each parameter that is not used within the function body.
579592
For example:
593+
580594
```go
581595
func f(x, y int) { // "unused parameter: x"
582596
fmt.Println(y)
@@ -607,6 +621,50 @@ Observe that in the first call, the argument `chargeCreditCard()` was
607621
not deleted because of potential side effects, whereas in the second
608622
call, the argument 2, a constant, was safely deleted.
609623

624+
<a name='refactor.rewrite.moveParamLeft'></a>
625+
<a name='refactor.rewrite.moveParamRight'></a>
626+
### `refactor.rewrite.moveParam{Left,Right}`: Move function parameters
627+
628+
When the selection is a parameter in a function or method signature, gopls
629+
offers a code action to move the parameter left or right (if feasible),
630+
updating all callers accordingly.
631+
632+
For example:
633+
634+
```go
635+
func Foo(x, y int) int {
636+
return x + y
637+
}
638+
639+
func _() {
640+
_ = Foo(0, 1)
641+
}
642+
```
643+
644+
becomes
645+
646+
```go
647+
func Foo(y, x int) int {
648+
return x + y
649+
}
650+
651+
func _() {
652+
_ = Foo(1, 0)
653+
}
654+
```
655+
656+
following a request to move `x` right, or `y` left.
657+
658+
This is a primitive building block of more general "Change signature"
659+
operations. We plan to generalize this to arbitrary signature rewriting, but
660+
the language server protocol does not currently offer good support for user
661+
input into refactoring operations (see
662+
[microsoft/language-server-protocol#1164](https://github.com/microsoft/language-server-protocol/issues/1164)).
663+
Therefore, any such refactoring will require custom client-side logic. (As a
664+
very hacky workaround, you can express arbitrary parameter movement by invoking
665+
Rename on the `func` keyword of a function declaration, but this interface is
666+
just a temporary stopgap.)
667+
610668
<a name='refactor.rewrite.changeQuote'></a>
611669
### `refactor.rewrite.changeQuote`: Convert string literal between raw and interpreted
612670

@@ -673,6 +731,7 @@ func() (
673731
z rune,
674732
)
675733
```
734+
676735
Observe that in the last two cases, each
677736
[group](https://pkg.go.dev/go/ast#Field) of parameters or results is
678737
treated as a single item.
@@ -683,6 +742,7 @@ respectively, or trivial (fewer than two items).
683742

684743
These code actions are not offered for lists containing `//`-style
685744
comments, which run to the end of the line.
745+
686746
<!-- Strictly, line comments make only "join" (but not "split") infeasible. -->
687747

688748
<a name='refactor.rewrite.fillStruct'></a>

gopls/doc/release/v0.16.0.md

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
# gopls/v0.16.0
22

3-
<!-- TODO: update this instruction once v0.16.0 is released.
4-
5-
Also, tweak the img URLs when publishing to GitHub Releases:
6-
https://raw.githubusercontent.com/golang/v0.16.0/gopls/doc/ etc
7-
-->
83
```
9-
go install golang.org/x/tools/gopls@v0.16.0-pre.2
4+
go install golang.org/x/tools/gopls@v0.16.2
105
```
116

127
This release includes several features and bug fixes, and is the first
@@ -24,6 +19,7 @@ and also the last to support integrating with go command versions 1.19 and
2419
a message advising the user to upgrade.
2520

2621
When using gopls, there are three versions to be aware of:
22+
2723
1. The _gopls build go version_: the version of Go used to build gopls.
2824
2. The _go command version_: the version of the go list command executed by
2925
gopls to load information about your workspace.
@@ -97,6 +93,7 @@ cause your editor to navigate to the declaration.
9793
<img title="Symbol links navigate your editor to the declaration" src="../assets/browse-pkg-doc.png" width="80%">
9894

9995
Editor support:
96+
10097
- VS Code: use the "Source action > Browse documentation for func fmt.Println" menu item.
10198
Note: source links navigate the editor but don't yet raise the window yet.
10299
Please upvote microsoft/vscode#208093 and microsoft/vscode#207634 (temporarily closed).
@@ -106,7 +103,6 @@ The `linksInHover` setting now supports a new value, `"gopls"`,
106103
that causes documentation links in the the Markdown output
107104
of the Hover operation to link to gopls' internal doc viewer.
108105

109-
110106
### Browse free symbols
111107

112108
Gopls offers another web-based code action, "Browse free symbols",
@@ -133,6 +129,7 @@ the function by choosing a different type for that parameter.
133129
<img title="Browse free symbols" src="../assets/browse-free-symbols.png" width="80%">
134130

135131
Editor support:
132+
136133
- VS Code: use the `Source action > Browse free symbols` menu item.
137134
- Emacs: requires eglot v1.17. Use `M-x go-browse-freesymbols` from github.com/dominikh/go-mode.el.
138135

@@ -157,12 +154,14 @@ Gopls cannot yet display assembly for generic functions:
157154
generic functions are not fully compiled until they are instantiated,
158155
but any function declaration enclosing the selection cannot be an
159156
instantiated generic function.
157+
160158
<!-- Clearly the ideal UX for generic functions is to use the function
161159
symbol under the cursor, e.g. Vector[string], rather than the
162160
enclosing function; but computing the name of the linker symbol
163161
remains a challenge. -->
164162

165163
Editor support:
164+
166165
- VS Code: use the "Source action > Browse assembly for f" menu item.
167166
- Emacs: requires eglot v1.17. Use `M-x go-browse-assembly` from github.com/dominikh/go-mode.el.
168167

@@ -252,8 +251,7 @@ suboptimal ordering of struct fields, if this figure is 20% or higher:
252251
<img title="a struct with wasted space" src="../assets/hover-size-wasteful.png">
253252

254253
In the struct above, alignment rules require each of the two boolean
255-
fields (1 byte) to occupy a complete word (8 bytes), leading to (7 +
256-
7) / (3 * 8) = 58% waste.
254+
fields (1 byte) to occupy a complete word (8 bytes), leading to (7 + 7) / (3 \* 8) = 58% waste.
257255
Placing the two booleans together would save a word.
258256

259257
This information may be helpful when making space optimizations to

0 commit comments

Comments
 (0)