x/tools/gopls:重新排列结构体字段会删除注解

bwleehnv  于 3个月前  发布在  Go
关注(0)|答案(7)|浏览(47)

你使用的Go版本、VS Code和VS Code Go扩展是什么?

  • 运行 go version 以获取Go的版本
  • go1.15.6 darwin/amd64
  • 如果你使用的是 the language server,运行 gopls -v version 以获取Gopls的版本。
Build info
----------
golang.org/x/tools/gopls v0.6.3
    golang.org/x/tools/gopls@v0.6.3 h1:FCjXQzsa/jFSqbp2McJowMeshacTc8jhmMdJ22HpqiE=
    github.com/BurntSushi/toml@v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
    github.com/google/go-cmp@v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
    github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    golang.org/x/mod@v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
    golang.org/x/sync@v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
    golang.org/x/tools@v0.0.0-20210112235408-75fd75db8797 h1:kcvRujT1OsSzHGjvqsV0XWy92+z4TUgV2YwQH9aQt8I=
    golang.org/x/xerrors@v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
    honnef.co/go/tools@v0.0.1-2020.1.6 h1:W18jzjh8mfPez+AwGLxmOImucz/IFjpNlrKVnaj2YVc=
    mvdan.cc/gofumpt@v0.1.0 h1:hsVv+Y9UsZ/mFZTxJZuHVI6shSQCtzZ11h1JEFPAZLw=
    mvdan.cc/xurls/v2@v2.2.0 h1:NSZPykBXJFCetGZykLAxaL6SIpvbVy/UFEniIfHAa8A=
  • 运行 code -vcode-insiders -v 以获取VS Code或VS Code Insiders的版本。
1.52.1
ea3859d4ba2f3e577a159bc91e3074c5d85c0523
x64
  • 检查已安装的扩展以获取VS Code Go扩展的版本。
  • 0.20.2
  • 运行 go env 以获取go开发环境的详细信息。
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/rogandhi/Library/Caches/go-build"
GOENV="/Users/rogandhi/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/rogandhi/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/rogandhi/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.15.6/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.15.6/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/rogandhi/work/test/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/f1/d20cq36s6gn1kj0vgdv855t00000gn/T/go-build048821892=/tmp/go-build -gno-record-gcc-switches -fno-common"

分享你添加/编辑过的与Go相关的设置

运行 Preferences: Open Settings (JSON) 命令以打开settings.json文件。
使用 go.["go"]gopls 前缀与其他人共享所有设置。

{
    "[go]": {
        "editor.codeActionsOnSave": {
            "source.fixAll": true,
            "source.organizeImports": true
        },
        "editor.formatOnSave": true
    },
    "go.addTags": {
        "transform": "camelcase"
    },
    "go.autocompleteUnimportedPackages": true,
    "go.buildOnSave": "workspace",
    "go.coverOnSingleTest": true,
    "go.coverOnSingleTestFile": true,
    "go.coverOnTestPackage": true,
    "go.coverShowCounts": false,
    "go.coverageDecorator": {
        "type": "highlight"
    },
    "go.editorContextMenuCommands": {
        "addImport": true,
        "addTags": true,
        "debugTestAtCursor": true,
        "generateTestForFile": true,
        "generateTestForFunction": true,
        "generateTestForPackage": true,
        "playground": true,
        "removeTags": true,
        "testAtCursor": true,
        "testCoverage": true,
        "testFile": true,
        "testPackage": true,
        "toggleTestFile": true
    },
    "go.enableCodeLens": {
        "references": false,
        "runtest": true
    },
    "go.formatTool": "goimports",
    "go.gotoSymbol.ignoreFolders": [
        "vendor"
    ],
    "go.gotoSymbol.includeImports": true,
    "go.languageServerExperimentalFeatures": {
        "diagnostics": true,
        "documentLink": true
    },
    "go.lintOnSave": "workspace",
    "go.lintTool": "golangci-lint",
    "go.testFlags": [
        "-v"
    ],
    "go.testTimeout": "10m",
    "go.useCodeSnippetsOnFunctionSuggestWithoutType": true,
    "go.useLanguageServer": true,
    "gopls": {
        "analyses": {
            "fillreturns": true,
            "nonewvars": true,
            "undeclaredname": true,
            "unreachable": true,
            "unusedparams": true,
            "fieldalignment": true,
            "shadow": true
        },
        "gofumpt": true,
        "usePlaceholders": true
    },
    "search.exclude": {
        "**/vendor": true
    },
    "editor.wordWrap": "bounded",
    "editor.wordWrapColumn": 100
}

描述bug

推荐的重构操作之一是重新排列结构体字段以更好地对齐并节省内存。当执行此操作时,为字段编写的注解会被删除。

重现行为的方法:

示例结构体:

type foo struct {
	timeout time.Duration // timeout
	flag1   bool          // flag1
	name1   string        // name1
	flag2   bool          // flag2
	name2   string        // name2
	value   int           // value1
	u       url.URL       // url
}

如果你使用建议的操作重新排列结构体字段,注解将被删除(请查看附加的录制)。

截图或录制

Screen.Recording.2021-01-15.at.2.10.16.PM.mov

jgovgodb

jgovgodb2#

我认为我们不应该有一个意外删除用户代码的功能。如果go/ast太不实用,也许我们可以更改建议修复的标题为“重新排列字段(可能删除评论)”或类似名称?

ljo96ir5

ljo96ir53#

是的,根据CL 278872,这确实是它的工作原理(也请参见#20744)。我同意这不是最优的。
鉴于这个分析器的专用性(以及它是可选的),我们是否可以在文档中添加一条注解?那将是用户的入口点。
将标题更新为“重新排列字段(删除注解)”可能会引起混淆,尤其是那些没有注意到的人,因为他们没有评论。在这种情况下,我宁愿看到我们只在有任何评论时才更新标题。
长期目标是保留评论,但在我看来(对AST的经验非常有限),这并不简单。如果有人有关于如何实现这一点的想法,请告诉我。

oymdgrw7

oymdgrw74#

FWIW,我认为只有在有注解将被删除时才显示后缀是一个好主意,并且应该是完全可能的。
我的理解与你的相符:goimports中有一个长期存在的功能请求,由于AST中的注解支持不佳而被阻止。因此,我认为在标题中指出这个问题实际上是实现默认情况下解决这个问题的最佳途径:-/

roejwanj

roejwanj5#

为了澄清,我认为fieldalignment有点过于专业化,以至于默认情况下不会被启用。它确实有其位置,但可能会为普通用户生成过多的无关噪音。在大多数情况下,按可读性排序的结构比最优对齐的结构更具优势。我会看看是否可以在时间允许的情况下发送一个CL来更新标题,基于评论的删除。

nwwlzxa7

nwwlzxa76#

为了澄清,我认为fieldalignment定位过于狭窄,默认情况下不太可能开启。它确实有其作用,但可能会为普通用户生成过多无关的噪音。在大多数情况下,可读性排序的结构提供了比最优对齐更好的效果。我会尝试在时间允许的情况下发送一个CL来更新标题,基于评论删除。

这个检查的严重程度是否可以从warning更改为info?如果是这样的话,我可以将其默认开启,但它似乎只是一种提醒,而不是警告。

nfg76nw0

nfg76nw07#

关于这个,我同意。

相关问题