Gopls release v0.18.0

配置更改

  • hoverKind 选项的实验性 Structured 值不再受支持。

  • gc_details 代码提示已被删除。(它之前默认是禁用的。)现在可以通过 toggleCompilerOptDetails 代码操作(下文有说明)来获得此功能,因为代码操作在各种客户端中的支持程度比代码提示更好。

    VS Code 的特殊命令“Go: Toggle GC details”仍然有效。

  • 实验性的 semanticTokenTypessemanticTokenModifiers 选项允许在 textDocument/semanticTokens 响应中选择性地禁用某些类型的 token 或 token modifiers。

    这些选项取代了现在已弃用的 noSemanticStringnoSemanticTokenNumber 选项。用户现在可以设置 “semanticTokenTypes”: {“string”: false, “number”: false} 来达到相同的结果。目前,gopls 仍然支持 noSemanticTokenStringnoSemanticToken,但在未来的版本中将停止支持它们。

  • 新的 workspaceFiles 选项允许配置匹配定义工作区逻辑构建文件的 glob 模式。此选项仅在使用自定义 golang.org/x/tools/go/packages 驱动程序的环境中需要。

新功能

“{显示,隐藏}编译器优化详细信息” 代码操作

此代码操作可以通过 VS Code 中的“Source Action”菜单访问,它会切换一个每目录的标志,导致 Go 编译器优化详细信息作为诊断报告。例如,它会指示哪些变量会逃逸到堆中,以及哪些数组访问需要边界检查。

TODO:为每个项目添加指向完整手册的链接。

新的 modernize 分析器

Gopls 现在会报告代码何时可以通过使用更现代的 Go 功能来简化或澄清,并提供一个快速修复来应用更改。

例如,使用 if/else 语句的条件赋值可以被 Go 1.18 中添加的 minmax 内置函数调用所取代。

使用此命令大规模应用现代化修复

$ go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -test ./...

新的 unusedfunc 分析器

Gopls 现在会报告未使用的函数和方法,为你提供关于可安全删除的死代码的近乎实时反馈。由于分析仅限于每个包,只有未导出的函数和方法是候选者。(要进行更精确的分析,可能报告未使用的已导出函数,请使用 golang.org/x/tools/cmd/deadcode 命令。)

新的 hostport 分析器

随着 IPv6 使用的日益广泛,使用 fmt.Sprintf("%s:%d") 构造“host:port”字符串已不再合适,因为主机名可能包含冒号。Gopls 现在会报告以这种方式(或使用 %s 作为端口)构造的字符串传递给 net.Dial 或相关函数的地方,并提供一个使用 net.JoinHostPort 的修复。

其他分析器更改

  • unusedvariable 快速修复现在默认开启。
  • unusedparams 分析器不再报告生成文件的发现。

新的 gofix 分析器

Gopls 现在会报告函数调用或常量使用何时应该被内联。这些诊断和相关的代码操作由函数和常量定义处的“//go:fix inline”指令触发。(请参阅 go:fix 提案。)

例如,考虑一个名为 intmath 的包,其中有一个函数 Square(int) int。后来引入了更通用的 Pow(int, int) int,并将 Square 弃用,改为调用第二个参数为 2 的 Powintmath 的作者可以写成这样

//go:fix inline
func Square(x int) int { return Pow(x, 2) }

如果 gopls 在你的代码中看到对 intmath.Square 的调用,它会建议内联它,并提供一个代码操作来完成。

同样的功能也适用于常量。对于像这样的常量定义

//go:fix inline
const Ptr = Pointer

gopls 会建议在你的代码中将 Ptr 替换为 Pointer

使用此命令大规模应用此类修复

$ go run golang.org/x/tools/gopls/internal/analysis/gofix/cmd/gofix@latest -test -fix ./...

“实现”支持泛型

终于,“Go to Implementations”功能现在完全支持泛型类型和函数(#59224)。

例如,在下面的接口方法 Stack.Push 上调用此功能会报告具体的类型为 C[T].Push 的方法,反之亦然。

package p

type Stack[T any] interface {
    Push(T) error
    Pop() (T, bool)
}

type C[T any] struct{}

func (C[T]) Push(t T) error { ... }
func (C[T]) Pop() (T, bool) { ... }

var _ Stack[int] = C[int]{}

提取所选内容下的所有相同表达式实例

当你在一个函数中有多个相同的表达式实例时,你可以使用此代码操作将其提取到一个变量中。表达式的所有实例都将被替换为对新变量的引用。

“Definition”改进

Definition 查询现在支持附加位置

  • 当在 return 语句上调用时,它会报告函数结果变量的位置。
  • 当在 break、goto 或 continue 语句上调用时,它分别报告标签的位置、相关块语句的结束大括号,或相关循环的开始位置。

“Hover”改进

当在 return 语句上调用时,hover 会报告函数结果变量的类型。

格式字符串的用户体验改进

“DocumentHighlight”

当你的光标位于 printf 类函数内时,gopls 现在会突出显示格式化动词和参数之间的关系,作为视觉提示,以区分格式字符串中操作数的使用方式。

fmt.Printf("Hello %s, you scored %d", name, score)

如果光标位于 %sname 上,gopls 会将 %s 突出显示为写操作,将 name 突出显示为读操作。

“SemanticHighlight”

与 DocumentHighlight 的改进类似,gopls 还将格式化动词报告为“string” token 类型的“format”修饰符,以便更好地将其与其他格式字符串部分区分开来。

fmt.Printf("Hello %s, you scored %d", name, score)

%s%d 将具有 token 类型“string”和修饰符“format”。


本文档的源代码可以在 golang.org/x/tools/gopls/doc 下找到。