[tools] internal/lsp: apply go.sum fixes to all modules in multi-module module

646 views
Skip to first unread message

Rebecca Stambler (Gerrit)

unread,
Feb 4, 2021, 9:41:15 PM2/4/21
to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Attention is currently required from: Rebecca Stambler.

Rebecca Stambler uploaded patch set #2 to this change.

View Change

internal/lsp: apply go.sum fixes to all modules in multi-module module

When go.sum updates are needed in experimental workspace module mode, we
don't necessarily know which module needs the correction. As a fix,
apply all of these fixes to each module in the multi-module workspace.

Fixes golang/go#44097

Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
---
M gopls/internal/regtest/workspace/workspace_test.go
M internal/lsp/cache/mod.go
M internal/lsp/cache/mod_tidy.go
M internal/lsp/cache/snapshot.go
M internal/lsp/code_action.go
M internal/lsp/command.go
6 files changed, 160 insertions(+), 79 deletions(-)

To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: tools
Gerrit-Branch: master
Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
Gerrit-Change-Number: 289772
Gerrit-PatchSet: 2
Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
Gerrit-Reviewer: Go Bot <go...@golang.org>
Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
Gerrit-Reviewer: kokoro <noreply...@google.com>
Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
Gerrit-MessageType: newpatchset

kokoro (Gerrit)

unread,
Feb 4, 2021, 9:49:18 PM2/4/21
to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, golang-co...@googlegroups.com

Attention is currently required from: Rebecca Stambler.

Kokoro presubmit build finished with status: FAILURE
Logs at: https://source.cloud.google.com/results/invocations/a57191f1-76d9-4713-af15-6240caa0cfbf

Patch set 2:gopls-CI -1

View Change

    To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
    Gerrit-Change-Number: 289772
    Gerrit-PatchSet: 2
    Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
    Gerrit-Reviewer: Go Bot <go...@golang.org>
    Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
    Gerrit-Reviewer: kokoro <noreply...@google.com>
    Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
    Gerrit-Comment-Date: Fri, 05 Feb 2021 02:49:14 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    Rebecca Stambler (Gerrit)

    unread,
    Feb 4, 2021, 10:23:08 PM2/4/21
    to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

    Attention is currently required from: Rebecca Stambler.

    Rebecca Stambler uploaded patch set #3 to this change.

    View Change

    internal/lsp: apply go.sum fixes to all modules in multi-module module

    When go.sum updates are needed in experimental workspace module mode, we
    don't necessarily know which module needs the correction. As a fix,
    apply all of these fixes to each module in the multi-module workspace.

    Fixes golang/go#44097

    Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
    ---
    M gopls/internal/regtest/workspace/workspace_test.go
    M internal/lsp/cache/mod.go
    M internal/lsp/cache/mod_tidy.go
    M internal/lsp/cache/snapshot.go
    M internal/lsp/code_action.go
    M internal/lsp/command.go
    6 files changed, 163 insertions(+), 79 deletions(-)

    To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: tools
    Gerrit-Branch: master
    Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
    Gerrit-Change-Number: 289772
    Gerrit-PatchSet: 3
    Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
    Gerrit-Reviewer: Go Bot <go...@golang.org>
    Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
    Gerrit-Reviewer: kokoro <noreply...@google.com>
    Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
    Gerrit-MessageType: newpatchset

    kokoro (Gerrit)

    unread,
    Feb 4, 2021, 10:29:26 PM2/4/21
    to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, golang-co...@googlegroups.com

    Attention is currently required from: Rebecca Stambler.

    Kokoro presubmit build finished with status: SUCCESS
    Logs at: https://source.cloud.google.com/results/invocations/2ce82926-fa42-4055-9cb3-07041fb6a842

    Patch set 3:gopls-CI +1

    View Change

      To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
      Gerrit-Change-Number: 289772
      Gerrit-PatchSet: 3
      Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
      Gerrit-Reviewer: Go Bot <go...@golang.org>
      Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
      Gerrit-Comment-Date: Fri, 05 Feb 2021 03:29:21 +0000

      Rebecca Stambler (Gerrit)

      unread,
      Feb 4, 2021, 10:49:24 PM2/4/21
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Rebecca Stambler.

      Rebecca Stambler uploaded patch set #4 to this change.

      View Change

      internal/lsp: apply go.sum fixes to all modules in multi-module module

      When go.sum updates are needed in experimental workspace module mode, we
      don't necessarily know which module needs the correction. As a fix,
      apply all of these fixes to each module in the multi-module workspace.

      Fixes golang/go#44097

      Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
      ---
      M gopls/internal/regtest/workspace/workspace_test.go
      M internal/lsp/cache/mod.go
      M internal/lsp/cache/mod_tidy.go
      M internal/lsp/cache/snapshot.go
      M internal/lsp/code_action.go
      M internal/lsp/command.go
      6 files changed, 163 insertions(+), 79 deletions(-)

      To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
      Gerrit-Change-Number: 289772
      Gerrit-PatchSet: 4
      Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
      Gerrit-Reviewer: Go Bot <go...@golang.org>
      Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
      Gerrit-Reviewer: kokoro <noreply...@google.com>
      Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
      Gerrit-MessageType: newpatchset

      Rebecca Stambler (Gerrit)

      unread,
      Feb 4, 2021, 10:50:26 PM2/4/21
      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

      Attention is currently required from: Rebecca Stambler.

      Rebecca Stambler uploaded patch set #5 to this change.

      View Change

      internal/lsp: apply go.sum fixes to all modules in multi-module module

      When go.sum updates are needed in experimental workspace module mode, we
      don't necessarily know which module needs the correction. As a fix,
      apply all of these fixes to each module in the multi-module workspace.

      Fixes golang/go#44097

      Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
      ---
      M gopls/internal/regtest/workspace/workspace_test.go
      M internal/lsp/cache/mod.go
      M internal/lsp/cache/mod_tidy.go
      M internal/lsp/cache/snapshot.go
      M internal/lsp/code_action.go
      M internal/lsp/command.go
      6 files changed, 163 insertions(+), 79 deletions(-)

      To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

      Gerrit-Project: tools
      Gerrit-Branch: master
      Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
      Gerrit-Change-Number: 289772
      Gerrit-PatchSet: 5

      kokoro (Gerrit)

      unread,
      Feb 4, 2021, 10:59:05 PM2/4/21
      to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, golang-co...@googlegroups.com

      Attention is currently required from: Rebecca Stambler.

      Kokoro presubmit build finished with status: SUCCESS
      Logs at: https://source.cloud.google.com/results/invocations/94be616e-75a8-4f76-a29a-ab7f532c6ca1

      Patch set 5:gopls-CI +1

      View Change

        To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: tools
        Gerrit-Branch: master
        Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
        Gerrit-Change-Number: 289772
        Gerrit-PatchSet: 5
        Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
        Gerrit-Reviewer: Go Bot <go...@golang.org>
        Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
        Gerrit-Comment-Date: Fri, 05 Feb 2021 03:59:00 +0000

        Rebecca Stambler (Gerrit)

        unread,
        Feb 5, 2021, 12:17:29 AM2/5/21
        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

        Attention is currently required from: Rebecca Stambler.

        Rebecca Stambler uploaded patch set #6 to this change.

        View Change

        internal/lsp: apply go.sum fixes to all modules in multi-module module

        When go.sum updates are needed in experimental workspace module mode, we
        don't necessarily know which module needs the correction. As a fix,
        apply all of these fixes to each module in the multi-module workspace.

        The "add dependency" quick fix also seems to be broken, but I'll fix
        that in a separate CL.


        Fixes golang/go#44097

        Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
        ---
        M gopls/internal/regtest/codelens/codelens_test.go
        M gopls/internal/regtest/diagnostics/diagnostics_test.go
        M gopls/internal/regtest/misc/imports_test.go
        M gopls/internal/regtest/misc/vendor_test.go
        M gopls/internal/regtest/modfile/modfile_test.go
        M gopls/internal/regtest/workspace/workspace_test.go
        M gopls/internal/regtest/wrappers.go

        M internal/lsp/cache/mod.go
        M internal/lsp/cache/mod_tidy.go
        M internal/lsp/cache/snapshot.go
        M internal/lsp/code_action.go
        M internal/lsp/command.go
        12 files changed, 191 insertions(+), 99 deletions(-)

        To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

        Gerrit-Project: tools
        Gerrit-Branch: master
        Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
        Gerrit-Change-Number: 289772
        Gerrit-PatchSet: 6
        Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
        Gerrit-Reviewer: Go Bot <go...@golang.org>
        Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
        Gerrit-Reviewer: kokoro <noreply...@google.com>
        Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
        Gerrit-MessageType: newpatchset

        kokoro (Gerrit)

        unread,
        Feb 5, 2021, 12:24:36 AM2/5/21
        to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, golang-co...@googlegroups.com

        Attention is currently required from: Rebecca Stambler.

        Kokoro presubmit build finished with status: SUCCESS
        Logs at: https://source.cloud.google.com/results/invocations/3802f583-7d0e-45e3-a759-b040e0a77cda

        Patch set 6:gopls-CI +1

        View Change

          To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
          Gerrit-Change-Number: 289772
          Gerrit-PatchSet: 6
          Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: Go Bot <go...@golang.org>
          Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: kokoro <noreply...@google.com>
          Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Comment-Date: Fri, 05 Feb 2021 05:24:31 +0000

          Heschi Kreinick (Gerrit)

          unread,
          Feb 5, 2021, 1:41:14 PM2/5/21
          to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, kokoro, golang-co...@googlegroups.com

          Attention is currently required from: Rebecca Stambler.

          Patch set 6:Code-Review +2

          View Change

          8 comments:

          • File gopls/internal/regtest/workspace/workspace_test.go:

            • Patch Set #6, Line 791: func TestOneUntidyModule(t *testing.T) {

              The module may in some sense be untidy, but I think it would be more descriptive to call it broken or needing a go.sum update or something.

            • Patch Set #6, Line 828: // TODO(rstambler): The "add dependency" diagnostic is also broken.

              This is a strange place to put a todo for add dependency, so I'd probably get rid of it. But if you want to keep it, please actually describe how it's broken; as is this is basically just FUD.

          • File gopls/internal/regtest/wrappers.go:

            • Patch Set #6, Line 196: func (e *Env) ApplyQuickFixes(path string, diagnostics ...protocol.Diagnostic) {

              This change seems to have made more places worse than it made better, and caused a fair bit of churn.

          • File internal/lsp/cache/mod.go:

            • Patch Set #6, Line 221:

              Don't pass a file
              // handle in, as it might not be the file associated with the error

              I have no idea what this part of the comment means, so I'm pretty sure it's obsolete?

          • File internal/lsp/cache/mod_tidy.go:

            • Patch Set #6, Line 168: if isInconsistentVendor && len(s.ModFiles()) > 1 {

              Wouldn't this belong in the isInconsistentVendor case?

              I'm also fairly certain it's impossible, since we should never be running with -mod=vendor in workspace module mode.

            • Patch Set #6, Line 214: Message: `go.sum is out of sync with go.mod. Please update it or run "go list -mod=mod ./...".`,

              This message is pretty unhelpful in the multiple module case, given that we're going to splatter it across all the modules. I think we have to either say to accept the quick fix, or say to run the command in each module in the workspace.

          • File internal/lsp/code_action.go:

            • Patch Set #6, Line 529: // Don't offer fixes for diagnostics in other go.mod files.

              Shouldn't this be handled by sameDiagnostic? Why would we ever want to show diagnostics for another file, mod or not?

          • File internal/lsp/command.go:

            • Patch Set #6, Line 193: for _, arg := range args {

              No other command passes its arguments like this, but I guess it works. Hopefully it's not a problem for Rob's stuff.

          To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
          Gerrit-Change-Number: 289772
          Gerrit-PatchSet: 6
          Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: Go Bot <go...@golang.org>
          Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
          Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: kokoro <noreply...@google.com>
          Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Comment-Date: Fri, 05 Feb 2021 18:41:10 +0000
          Gerrit-HasComments: Yes
          Gerrit-Has-Labels: Yes
          Gerrit-MessageType: comment

          Rebecca Stambler (Gerrit)

          unread,
          Feb 6, 2021, 2:11:18 AM2/6/21
          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

          Attention is currently required from: Rebecca Stambler.

          Rebecca Stambler uploaded patch set #7 to this change.

          View Change

          internal/lsp: apply go.sum fixes to all modules in multi-module module

          When go.sum updates are needed in experimental workspace module mode, we
          don't necessarily know which module needs the correction. As a fix,
          apply all of these fixes to each module in the multi-module workspace.

          The "add dependency" quick fix also seems to be broken, but I'll fix
          that in a separate CL.

          Fixes golang/go#44097

          Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
          ---
          M gopls/internal/regtest/workspace/workspace_test.go

          M internal/lsp/cache/mod.go
          M internal/lsp/cache/mod_tidy.go
          M internal/lsp/cache/snapshot.go
          M internal/lsp/code_action.go
          M internal/lsp/command.go
          6 files changed, 177 insertions(+), 85 deletions(-)

          To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

          Gerrit-Project: tools
          Gerrit-Branch: master
          Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
          Gerrit-Change-Number: 289772
          Gerrit-PatchSet: 7
          Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: Go Bot <go...@golang.org>
          Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
          Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
          Gerrit-Reviewer: kokoro <noreply...@google.com>
          Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
          Gerrit-MessageType: newpatchset

          kokoro (Gerrit)

          unread,
          Feb 6, 2021, 2:17:50 AM2/6/21
          to Rebecca Stambler, goph...@pubsubhelper.golang.org, Heschi Kreinick, Go Bot, golang-co...@googlegroups.com

          Attention is currently required from: Rebecca Stambler.

          Kokoro presubmit build finished with status: FAILURE
          Logs at: https://source.cloud.google.com/results/invocations/7f47da8d-32c7-4be0-9dd5-d1c29c86cfb1

          Patch set 7:gopls-CI -1

          View Change

            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: tools
            Gerrit-Branch: master
            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
            Gerrit-Change-Number: 289772
            Gerrit-PatchSet: 7
            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
            Gerrit-Reviewer: Go Bot <go...@golang.org>
            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
            Gerrit-Reviewer: kokoro <noreply...@google.com>
            Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
            Gerrit-Comment-Date: Sat, 06 Feb 2021 07:17:46 +0000

            Rebecca Stambler (Gerrit)

            unread,
            Feb 6, 2021, 4:59:47 PM2/6/21
            to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

            Attention is currently required from: Rebecca Stambler.

            Rebecca Stambler uploaded patch set #8 to this change.

            View Change

            internal/lsp: apply go.sum fixes to all modules in multi-module module

            When go.sum updates are needed in experimental workspace module mode, we
            don't necessarily know which module needs the correction. As a fix,
            apply all of these fixes to each module in the multi-module workspace.

            The "add dependency" quick fix also seems to be broken, but I'll fix
            that in a separate CL.

            Fixes golang/go#44097

            Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
            ---
            M gopls/internal/regtest/workspace/workspace_test.go
            M internal/lsp/cache/mod.go
            M internal/lsp/cache/mod_tidy.go
            M internal/lsp/cache/snapshot.go
            M internal/lsp/command.go
            5 files changed, 161 insertions(+), 82 deletions(-)

            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

            Gerrit-Project: tools
            Gerrit-Branch: master
            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
            Gerrit-Change-Number: 289772
            Gerrit-PatchSet: 8
            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
            Gerrit-Reviewer: Go Bot <go...@golang.org>
            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
            Gerrit-Reviewer: kokoro <noreply...@google.com>
            Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
            Gerrit-MessageType: newpatchset

            kokoro (Gerrit)

            unread,
            Feb 6, 2021, 5:09:22 PM2/6/21
            to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

            Attention is currently required from: Rebecca Stambler.

            Kokoro presubmit build finished with status: SUCCESS
            Logs at: https://source.cloud.google.com/results/invocations/3e237681-8e15-440b-b0fa-2c0b117bf255

            Patch set 8:gopls-CI +1

            View Change

              To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
              Gerrit-Change-Number: 289772
              Gerrit-PatchSet: 8
              Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: Go Bot <go...@golang.org>
              Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
              Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: kokoro <noreply...@google.com>
              Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Comment-Date: Sat, 06 Feb 2021 22:09:18 +0000

              Rebecca Stambler (Gerrit)

              unread,
              Feb 6, 2021, 6:32:51 PM2/6/21
              to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

              Attention is currently required from: Rebecca Stambler.

              Rebecca Stambler uploaded patch set #9 to this change.

              View Change

              internal/lsp: apply go.sum fixes to all modules in multi-module module

              When go.sum updates are needed in experimental workspace module mode, we
              don't necessarily know which module needs the correction. As a fix,
              apply all of these fixes to each module in the multi-module workspace.

              The "add dependency" quick fix also seems to be broken, but I'll fix
              that in a separate CL.

              Fixes golang/go#44097

              Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
              ---
              M gopls/internal/regtest/workspace/workspace_test.go
              M gopls/internal/regtest/wrappers.go

              M internal/lsp/cache/mod.go
              M internal/lsp/cache/mod_tidy.go
              M internal/lsp/cache/snapshot.go
              M internal/lsp/code_action.go
              M internal/lsp/command.go
              M internal/lsp/fake/editor.go
              M internal/lsp/mod/diagnostics.go
              9 files changed, 204 insertions(+), 97 deletions(-)

              To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
              Gerrit-Change-Number: 289772
              Gerrit-PatchSet: 9
              Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: Go Bot <go...@golang.org>
              Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
              Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: kokoro <noreply...@google.com>
              Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
              Gerrit-MessageType: newpatchset

              Rebecca Stambler (Gerrit)

              unread,
              Feb 6, 2021, 6:33:30 PM2/6/21
              to goph...@pubsubhelper.golang.org, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

              View Change

              8 comments:

              • File gopls/internal/regtest/workspace/workspace_test.go:

                • The module may in some sense be untidy, but I think it would be more descriptive to call it broken o […]

                  Done

                • This is a strange place to put a todo for add dependency, so I'd probably get rid of it. […]

                  Filed golang/go#44132

              • File gopls/internal/regtest/wrappers.go:

                • This change seems to have made more places worse than it made better, and caused a fair bit of churn […]

                  Reverted.

              • File internal/lsp/cache/mod.go:

                • Patch Set #6, Line 221:

                  Don't pass a file
                  // handle in, as it might not be the file associated with the error

                  I have no idea what this part of the comment means, so I'm pretty sure it's obsolete?

                • Done

              • File internal/lsp/cache/mod_tidy.go:

                • Wouldn't this belong in the isInconsistentVendor case? […]

                  Done

                • Patch Set #6, Line 214: Message: `go.sum is out of sync with go.mod. Please update it or run "go list -mod=mod ./...".`,

                • This message is pretty unhelpful in the multiple module case, given that we're going to splatter it […]

                  Done

              • File internal/lsp/code_action.go:

                • Shouldn't this be handled by sameDiagnostic? Why would we ever want to show diagnostics for another […]

                  Some Go file diagnostics fix issues by doing suggested fixes in go.mod files, so those won't match. I moved this logic to a different function.

              • File internal/lsp/command.go:

                • No other command passes its arguments like this, but I guess it works. […]

                  Yeah, I know it's weird, but I didn't want to force all callers to change to a slice. Maybe I can wait to merge until Rob's stuff is in?

              To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

              Gerrit-Project: tools
              Gerrit-Branch: master
              Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
              Gerrit-Change-Number: 289772
              Gerrit-PatchSet: 9
              Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: Go Bot <go...@golang.org>
              Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
              Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
              Gerrit-Reviewer: kokoro <noreply...@google.com>
              Gerrit-Comment-Date: Sat, 06 Feb 2021 23:33:26 +0000
              Gerrit-HasComments: Yes
              Gerrit-Has-Labels: No
              Comment-In-Reply-To: Heschi Kreinick <hes...@google.com>
              Gerrit-MessageType: comment

              kokoro (Gerrit)

              unread,
              Feb 6, 2021, 6:39:28 PM2/6/21
              to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

              Kokoro presubmit build finished with status: SUCCESS

              Logs at: https://source.cloud.google.com/results/invocations/6172d60e-167d-4607-b0b1-c2c71122e48d

              Patch set 9:gopls-CI +1

              View Change

                To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: tools
                Gerrit-Branch: master
                Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                Gerrit-Change-Number: 289772
                Gerrit-PatchSet: 9
                Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: Go Bot <go...@golang.org>
                Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: kokoro <noreply...@google.com>
                Gerrit-Comment-Date: Sat, 06 Feb 2021 23:39:24 +0000

                Heschi Kreinick (Gerrit)

                unread,
                Feb 8, 2021, 6:01:43 PM2/8/21
                to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, kokoro, golang-co...@googlegroups.com

                Attention is currently required from: Rebecca Stambler.

                View Change

                2 comments:

                • File gopls/internal/regtest/wrappers.go:

                  • Patch Set #9, Line 203: // ApplyQuickFixes processes the quickfix codeAction, calling t.Fatal on any error.

                    needs updating

                • File internal/lsp/fake/editor.go:

                To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: tools
                Gerrit-Branch: master
                Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                Gerrit-Change-Number: 289772
                Gerrit-PatchSet: 9
                Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: Go Bot <go...@golang.org>
                Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: kokoro <noreply...@google.com>
                Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Comment-Date: Mon, 08 Feb 2021 23:01:39 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: No
                Gerrit-MessageType: comment

                Rebecca Stambler (Gerrit)

                unread,
                Feb 8, 2021, 9:35:42 PM2/8/21
                to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                Attention is currently required from: Rebecca Stambler.

                Rebecca Stambler uploaded patch set #10 to this change.

                View Change

                internal/lsp: apply go.sum fixes to all modules in multi-module module

                When go.sum updates are needed in experimental workspace module mode, we
                don't necessarily know which module needs the correction. As a fix,
                apply all of these fixes to each module in the multi-module workspace.

                The "add dependency" quick fix also seems to be broken, but I'll fix
                that in a separate CL.

                Fixes golang/go#44097

                Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                ---
                M gopls/internal/regtest/workspace/workspace_test.go
                M gopls/internal/regtest/wrappers.go
                M internal/lsp/cache/mod.go
                M internal/lsp/cache/mod_tidy.go
                M internal/lsp/cache/snapshot.go
                M internal/lsp/code_action.go
                M internal/lsp/command.go
                M internal/lsp/fake/editor.go
                M internal/lsp/mod/diagnostics.go
                9 files changed, 204 insertions(+), 97 deletions(-)

                To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: tools
                Gerrit-Branch: master
                Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                Gerrit-Change-Number: 289772
                Gerrit-PatchSet: 10
                Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: Go Bot <go...@golang.org>
                Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: kokoro <noreply...@google.com>
                Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                Gerrit-MessageType: newpatchset

                Rebecca Stambler (Gerrit)

                unread,
                Feb 8, 2021, 9:36:02 PM2/8/21
                to goph...@pubsubhelper.golang.org, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                View Change

                2 comments:

                • File gopls/internal/regtest/wrappers.go:

                  • Patch Set #9, Line 203: // ApplyQuickFixes processes the quickfix codeAction, calling t.Fatal on any error.

                    needs updating

                  • Done

                • File internal/lsp/fake/editor.go:

                  • Done

                To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                Gerrit-Project: tools
                Gerrit-Branch: master
                Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                Gerrit-Change-Number: 289772
                Gerrit-PatchSet: 10
                Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: Go Bot <go...@golang.org>
                Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                Gerrit-Reviewer: kokoro <noreply...@google.com>
                Gerrit-Comment-Date: Tue, 09 Feb 2021 02:35:58 +0000
                Gerrit-HasComments: Yes
                Gerrit-Has-Labels: No

                kokoro (Gerrit)

                unread,
                Feb 8, 2021, 9:44:29 PM2/8/21
                to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                Kokoro presubmit build finished with status: SUCCESS

                Logs at: https://source.cloud.google.com/results/invocations/a01d4959-e689-4afc-938d-af18a713db7b

                Patch set 10:gopls-CI +1

                View Change

                  To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                  Gerrit-Change-Number: 289772
                  Gerrit-PatchSet: 10
                  Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                  Gerrit-Reviewer: Go Bot <go...@golang.org>
                  Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                  Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                  Gerrit-Reviewer: kokoro <noreply...@google.com>
                  Gerrit-Comment-Date: Tue, 09 Feb 2021 02:44:25 +0000

                  Rebecca Stambler (Gerrit)

                  unread,
                  Feb 9, 2021, 6:25:15 PM2/9/21
                  to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                  Rebecca Stambler uploaded patch set #11 to this change.

                  View Change

                  internal/lsp: apply go.sum fixes to all modules in multi-module module

                  When go.sum updates are needed in experimental workspace module mode, we
                  don't necessarily know which module needs the correction. As a fix,
                  apply all of these fixes to each module in the multi-module workspace.

                  The "add dependency" quick fix also seems to be broken, but I'll fix
                  that in a separate CL.

                  Fixes golang/go#44097

                  Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                  ---
                  M gopls/internal/regtest/workspace/workspace_test.go
                  M gopls/internal/regtest/wrappers.go
                  M internal/lsp/cache/mod.go
                  M internal/lsp/cache/mod_tidy.go
                  M internal/lsp/cache/snapshot.go
                  M internal/lsp/code_action.go
                  M internal/lsp/command.go
                  M internal/lsp/command/command_gen.go
                  M internal/lsp/command/interface.go
                  M internal/lsp/fake/editor.go
                  M internal/lsp/mod/code_lens.go
                  M internal/lsp/mod/diagnostics.go
                  12 files changed, 195 insertions(+), 80 deletions(-)

                  To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                  Gerrit-Project: tools
                  Gerrit-Branch: master
                  Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                  Gerrit-Change-Number: 289772
                  Gerrit-PatchSet: 11
                  Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                  Gerrit-Reviewer: Go Bot <go...@golang.org>
                  Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                  Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                  Gerrit-Reviewer: kokoro <noreply...@google.com>
                  Gerrit-MessageType: newpatchset

                  Rebecca Stambler (Gerrit)

                  unread,
                  Feb 9, 2021, 6:28:52 PM2/9/21
                  to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                  Rebecca Stambler uploaded patch set #12 to this change.

                  Gerrit-PatchSet: 12

                  Rebecca Stambler (Gerrit)

                  unread,
                  Feb 9, 2021, 6:31:03 PM2/9/21
                  to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                  Rebecca Stambler uploaded patch set #13 to this change.

                  Gerrit-PatchSet: 13

                  kokoro (Gerrit)

                  unread,
                  Feb 9, 2021, 6:33:41 PM2/9/21
                  to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                  Attention is currently required from: Rebecca Stambler.

                  Kokoro presubmit build finished with status: FAILURE
                  Logs at: https://source.cloud.google.com/results/invocations/83027cfc-8062-48f4-8546-a11c19a8ac27

                  Patch set 11:gopls-CI -1

                  View Change

                    To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                    Gerrit-Project: tools
                    Gerrit-Branch: master
                    Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                    Gerrit-Change-Number: 289772
                    Gerrit-PatchSet: 11
                    Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                    Gerrit-Reviewer: Go Bot <go...@golang.org>
                    Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                    Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                    Gerrit-Reviewer: kokoro <noreply...@google.com>
                    Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                    Gerrit-Comment-Date: Tue, 09 Feb 2021 23:33:36 +0000

                    kokoro (Gerrit)

                    unread,
                    Feb 9, 2021, 6:38:29 PM2/9/21
                    to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                    Attention is currently required from: Rebecca Stambler.

                    Kokoro presubmit build finished with status: FAILURE

                    Logs at: https://source.cloud.google.com/results/invocations/8ce3b6f8-04a5-4c5f-8535-6aa062067c0d

                    Patch set 13:gopls-CI -1

                    View Change

                      To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                      Gerrit-Project: tools
                      Gerrit-Branch: master
                      Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                      Gerrit-Change-Number: 289772
                      Gerrit-PatchSet: 13
                      Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-Reviewer: Go Bot <go...@golang.org>
                      Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                      Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-Reviewer: kokoro <noreply...@google.com>
                      Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-Comment-Date: Tue, 09 Feb 2021 23:38:24 +0000

                      Rebecca Stambler (Gerrit)

                      unread,
                      Feb 9, 2021, 7:00:17 PM2/9/21
                      to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                      Attention is currently required from: Rebecca Stambler.

                      Rebecca Stambler uploaded patch set #14 to this change.

                      View Change

                      internal/lsp: apply go.sum fixes to all modules in multi-module module

                      When go.sum updates are needed in experimental workspace module mode, we
                      don't necessarily know which module needs the correction. As a fix,
                      apply all of these fixes to each module in the multi-module workspace.

                      The "add dependency" quick fix also seems to be broken, but I'll fix
                      that in a separate CL.

                      Fixes golang/go#44097

                      Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                      ---
                      M gopls/doc/commands.md

                      M gopls/internal/regtest/workspace/workspace_test.go
                      M gopls/internal/regtest/wrappers.go
                      M internal/lsp/cache/mod.go
                      M internal/lsp/cache/mod_tidy.go
                      M internal/lsp/cache/snapshot.go
                      M internal/lsp/code_action.go
                      M internal/lsp/command.go
                      M internal/lsp/command/command_gen.go
                      M internal/lsp/command/interface.go
                      M internal/lsp/fake/editor.go
                      M internal/lsp/mod/code_lens.go
                      M internal/lsp/mod/diagnostics.go
                      M internal/lsp/source/api_json.go
                      14 files changed, 199 insertions(+), 90 deletions(-)

                      To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                      Gerrit-Project: tools
                      Gerrit-Branch: master
                      Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                      Gerrit-Change-Number: 289772
                      Gerrit-PatchSet: 14
                      Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-Reviewer: Go Bot <go...@golang.org>
                      Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                      Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-Reviewer: kokoro <noreply...@google.com>
                      Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                      Gerrit-MessageType: newpatchset

                      kokoro (Gerrit)

                      unread,
                      Feb 9, 2021, 7:08:34 PM2/9/21
                      to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                      Attention is currently required from: Rebecca Stambler.

                      Kokoro presubmit build finished with status: SUCCESS
                      Logs at: https://source.cloud.google.com/results/invocations/76435092-bd20-4fae-b0c0-6e3bd123bb59

                      Patch set 14:gopls-CI +1

                      View Change

                        To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                        Gerrit-Project: tools
                        Gerrit-Branch: master
                        Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                        Gerrit-Change-Number: 289772
                        Gerrit-PatchSet: 14
                        Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-Reviewer: Go Bot <go...@golang.org>
                        Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                        Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-Reviewer: kokoro <noreply...@google.com>
                        Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-Comment-Date: Wed, 10 Feb 2021 00:08:28 +0000

                        Rebecca Stambler (Gerrit)

                        unread,
                        Feb 9, 2021, 7:42:57 PM2/9/21
                        to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                        Attention is currently required from: Rebecca Stambler.

                        Rebecca Stambler uploaded patch set #15 to this change.

                        View Change

                        internal/lsp: apply go.sum fixes to all modules in multi-module module

                        When go.sum updates are needed in experimental workspace module mode, we
                        don't necessarily know which module needs the correction. As a fix,
                        apply all of these fixes to each module in the multi-module workspace.

                        The "add dependency" quick fix also seems to be broken, but I'll fix
                        that in a separate CL.

                        Fixes golang/go#44097

                        Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                        ---
                        M gopls/doc/commands.md
                        M gopls/internal/regtest/workspace/workspace_test.go
                        M gopls/internal/regtest/wrappers.go
                        M internal/lsp/cache/mod.go
                        M internal/lsp/cache/mod_tidy.go
                        M internal/lsp/cache/snapshot.go
                        M internal/lsp/code_action.go
                        M internal/lsp/command.go
                        M internal/lsp/command/command_gen.go
                        M internal/lsp/command/interface.go
                        M internal/lsp/fake/editor.go
                        M internal/lsp/mod/code_lens.go
                        M internal/lsp/mod/diagnostics.go
                        M internal/lsp/source/api_json.go
                        14 files changed, 204 insertions(+), 84 deletions(-)

                        To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                        Gerrit-Project: tools
                        Gerrit-Branch: master
                        Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                        Gerrit-Change-Number: 289772
                        Gerrit-PatchSet: 15
                        Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-Reviewer: Go Bot <go...@golang.org>
                        Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                        Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-Reviewer: kokoro <noreply...@google.com>
                        Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                        Gerrit-MessageType: newpatchset

                        kokoro (Gerrit)

                        unread,
                        Feb 9, 2021, 7:48:16 PM2/9/21
                        to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                        Attention is currently required from: Rebecca Stambler.

                        Kokoro presubmit build finished with status: SUCCESS
                        Logs at: https://source.cloud.google.com/results/invocations/c76a92ad-bded-4e77-9b48-3bf9190b6472

                        Patch set 15:gopls-CI +1

                        View Change

                          To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                          Gerrit-Project: tools
                          Gerrit-Branch: master
                          Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                          Gerrit-Change-Number: 289772
                          Gerrit-PatchSet: 15
                          Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-Reviewer: Go Bot <go...@golang.org>
                          Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                          Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-Reviewer: kokoro <noreply...@google.com>
                          Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-Comment-Date: Wed, 10 Feb 2021 00:48:13 +0000

                          Rebecca Stambler (Gerrit)

                          unread,
                          Feb 9, 2021, 8:14:52 PM2/9/21
                          to goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

                          Attention is currently required from: Rebecca Stambler.

                          Rebecca Stambler uploaded patch set #16 to this change.

                          View Change

                          internal/lsp: apply go.sum fixes to all modules in multi-module module

                          When go.sum updates are needed in experimental workspace module mode, we
                          don't necessarily know which module needs the correction. As a fix,
                          apply all of these fixes to each module in the multi-module workspace.

                          The "add dependency" quick fix also seems to be broken, but I'll fix
                          that in a separate CL.

                          Fixes golang/go#44097

                          Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                          ---
                          M gopls/doc/commands.md
                          M gopls/doc/generate.go

                          M gopls/internal/regtest/workspace/workspace_test.go
                          M gopls/internal/regtest/wrappers.go
                          M internal/lsp/cache/mod.go
                          M internal/lsp/cache/mod_tidy.go
                          M internal/lsp/cache/snapshot.go
                          M internal/lsp/code_action.go
                          M internal/lsp/command.go
                          M internal/lsp/command/command_gen.go
                          M internal/lsp/command/interface.go
                          M internal/lsp/fake/editor.go
                          M internal/lsp/mod/code_lens.go
                          M internal/lsp/mod/diagnostics.go
                          M internal/lsp/source/api_json.go
                          15 files changed, 208 insertions(+), 84 deletions(-)

                          To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                          Gerrit-Project: tools
                          Gerrit-Branch: master
                          Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                          Gerrit-Change-Number: 289772
                          Gerrit-PatchSet: 16
                          Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-Reviewer: Go Bot <go...@golang.org>
                          Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                          Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-Reviewer: kokoro <noreply...@google.com>
                          Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                          Gerrit-MessageType: newpatchset

                          kokoro (Gerrit)

                          unread,
                          Feb 9, 2021, 8:23:34 PM2/9/21
                          to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, Heschi Kreinick, golang-co...@googlegroups.com

                          Attention is currently required from: Rebecca Stambler.

                          Kokoro presubmit build finished with status: SUCCESS
                          Logs at: https://source.cloud.google.com/results/invocations/9bf17f50-7908-44b2-a90a-1862105d5705

                          Patch set 16:gopls-CI +1

                          View Change

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 16
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Comment-Date: Wed, 10 Feb 2021 01:23:29 +0000

                            Rebecca Stambler (Gerrit)

                            unread,
                            Feb 9, 2021, 8:33:29 PM2/9/21
                            to goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                            Rebecca Stambler submitted this change.

                            View Change

                            Approvals: Heschi Kreinick: Looks good to me, approved Rebecca Stambler: Trusted; Run TryBots Go Bot: TryBots succeeded kokoro: gopls CI succeeded
                            internal/lsp: apply go.sum fixes to all modules in multi-module module

                            When go.sum updates are needed in experimental workspace module mode, we
                            don't necessarily know which module needs the correction. As a fix,
                            apply all of these fixes to each module in the multi-module workspace.

                            The "add dependency" quick fix also seems to be broken, but I'll fix
                            that in a separate CL.

                            Fixes golang/go#44097

                            Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Reviewed-on: https://go-review.googlesource.com/c/tools/+/289772
                            Trust: Rebecca Stambler <rsta...@golang.org>
                            Run-TryBot: Rebecca Stambler <rsta...@golang.org>
                            gopls-CI: kokoro <noreply...@google.com>
                            TryBot-Result: Go Bot <go...@golang.org>
                            Reviewed-by: Heschi Kreinick <hes...@google.com>

                            ---
                            M gopls/doc/commands.md
                            M gopls/doc/generate.go
                            M gopls/internal/regtest/workspace/workspace_test.go
                            M gopls/internal/regtest/wrappers.go
                            M internal/lsp/cache/mod.go
                            M internal/lsp/cache/mod_tidy.go
                            M internal/lsp/cache/snapshot.go
                            M internal/lsp/code_action.go
                            M internal/lsp/command.go
                            M internal/lsp/command/command_gen.go
                            M internal/lsp/command/interface.go
                            M internal/lsp/fake/editor.go
                            M internal/lsp/mod/code_lens.go
                            M internal/lsp/mod/diagnostics.go
                            M internal/lsp/source/api_json.go
                            15 files changed, 208 insertions(+), 84 deletions(-)

                            diff --git a/gopls/doc/commands.md b/gopls/doc/commands.md
                            index 70153df..8c5a06d 100644
                            --- a/gopls/doc/commands.md
                            +++ b/gopls/doc/commands.md
                            @@ -194,7 +194,7 @@
                            ```
                            {
                            // The file URI.
                            - "URI": string,
                            + "URIs": []string,
                            }
                            ```

                            @@ -222,7 +222,7 @@
                            ```
                            {
                            // The file URI.
                            - "URI": string,
                            + "URIs": []string,
                            }
                            ```

                            diff --git a/gopls/doc/generate.go b/gopls/doc/generate.go
                            index 90014a8..d6bd1ab 100644
                            --- a/gopls/doc/generate.go
                            +++ b/gopls/doc/generate.go
                            @@ -410,6 +410,10 @@
                            return "{ ... }"
                            }
                            under := arg.Type.Underlying()
                            + switch u := under.(type) {
                            + case *types.Slice:
                            + return fmt.Sprintf("[]%s", u.Elem().Underlying().String())
                            + }
                            return types.TypeString(under, nil)
                            }

                            diff --git a/gopls/internal/regtest/workspace/workspace_test.go b/gopls/internal/regtest/workspace/workspace_test.go
                            index 98eea27..f3f1a77 100644
                            --- a/gopls/internal/regtest/workspace/workspace_test.go
                            +++ b/gopls/internal/regtest/workspace/workspace_test.go
                            @@ -782,3 +782,61 @@
                            env.Await(env.DiagnosticAtRegexp("include/include.go", `exclude.(X)`))
                            })
                            }
                            +
                            +// Confirm that a fix for a tidy module will correct all modules in the
                            +// workspace.
                            +func TestMultiModule_OneBrokenModule(t *testing.T) {
                            + testenv.NeedsGo1Point(t, 15)
                            +
                            + const mod = `
                            +-- a/go.mod --
                            +module a.com
                            +
                            +go 1.12
                            +-- a/main.go --
                            +package main
                            +-- b/go.mod --
                            +module b.com
                            +
                            +go 1.12
                            +
                            +require (
                            + example.com v1.2.3
                            +)
                            +-- b/go.sum --
                            +-- b/main.go --
                            +package b
                            +
                            +import "example.com/blah"
                            +
                            +func main() {
                            + blah.Hello()
                            +}
                            +`
                            + WithOptions(
                            + ProxyFiles(workspaceProxy),
                            + Modes(Experimental),
                            + ).Run(t, mod, func(t *testing.T, env *Env) {
                            + params := &protocol.PublishDiagnosticsParams{}
                            + env.OpenFile("a/go.mod")
                            + env.Await(
                            + ReadDiagnostics("a/go.mod", params),
                            + )
                            + for _, d := range params.Diagnostics {
                            + if d.Message != `go.sum is out of sync with go.mod. Please update it by applying the quick fix.` {
                            + continue
                            + }
                            + actions, err := env.GetQuickFixes("a/go.mod", []protocol.Diagnostic{d})
                            + if err != nil {
                            + t.Fatal(err)
                            + }
                            + if len(actions) != 2 {
                            + t.Fatalf("expected 2 code actions, got %v", len(actions))
                            + }
                            + env.ApplyQuickFixes("a/go.mod", []protocol.Diagnostic{d})
                            + }
                            + env.Await(
                            + EmptyDiagnostics("a/go.mod"),
                            + )
                            + })
                            +}
                            diff --git a/gopls/internal/regtest/wrappers.go b/gopls/internal/regtest/wrappers.go
                            index fa9367e..12ac7f9 100644
                            --- a/gopls/internal/regtest/wrappers.go
                            +++ b/gopls/internal/regtest/wrappers.go
                            @@ -200,6 +200,12 @@
                            }
                            }

                            +// GetQuickFixes returns the available quick fix code actions.
                            +func (e *Env) GetQuickFixes(path string, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
                            + e.T.Helper()
                            + return e.Editor.GetQuickFixes(e.Ctx, path, nil, diagnostics)
                            +}
                            +
                            // Hover in the editor, calling t.Fatal on any error.
                            func (e *Env) Hover(name string, pos fake.Pos) (*protocol.MarkupContent, fake.Pos) {
                            e.T.Helper()
                            diff --git a/internal/lsp/cache/mod.go b/internal/lsp/cache/mod.go
                            index 99f9a22..9112bfd 100644
                            --- a/internal/lsp/cache/mod.go
                            +++ b/internal/lsp/cache/mod.go
                            @@ -214,17 +214,23 @@

                            // extractGoCommandError tries to parse errors that come from the go command
                            // and shape them into go.mod diagnostics.
                            -func (s *snapshot) extractGoCommandErrors(ctx context.Context, snapshot source.Snapshot, fh source.FileHandle, goCmdError string) []*source.Diagnostic {
                            +func (s *snapshot) extractGoCommandErrors(ctx context.Context, snapshot source.Snapshot, goCmdError string) []*source.Diagnostic {
                            var srcErrs []*source.Diagnostic
                            - if srcErr := s.parseModError(ctx, fh, goCmdError); srcErr != nil {
                            - srcErrs = append(srcErrs, srcErr)
                            + if srcErr := s.parseModError(ctx, goCmdError); srcErr != nil {
                            + srcErrs = append(srcErrs, srcErr...)
                            }
                            - // If the error message contains a position, use that. Don't pass a file
                            - // handle in, as it might not be the file associated with the error.
                            if srcErr := extractErrorWithPosition(ctx, goCmdError, s); srcErr != nil {
                            srcErrs = append(srcErrs, srcErr)
                            - } else if srcErr := s.matchErrorToModule(ctx, fh, goCmdError); srcErr != nil {
                            - srcErrs = append(srcErrs, srcErr)
                            + } else {
                            + for _, uri := range s.ModFiles() {
                            + fh, err := s.GetFile(ctx, uri)
                            + if err != nil {
                            + continue
                            + }
                            + if srcErr := s.matchErrorToModule(ctx, fh, goCmdError); srcErr != nil {
                            + srcErrs = append(srcErrs, srcErr)
                            + }
                            + }
                            }
                            return srcErrs
                            }
                            diff --git a/internal/lsp/cache/mod_tidy.go b/internal/lsp/cache/mod_tidy.go
                            index e8a8547..1b7ef52 100644
                            --- a/internal/lsp/cache/mod_tidy.go
                            +++ b/internal/lsp/cache/mod_tidy.go
                            @@ -151,8 +151,7 @@

                            return mth.tidy(ctx, s)
                            }
                            -
                            -func (s *snapshot) parseModError(ctx context.Context, fh source.FileHandle, errText string) *source.Diagnostic {
                            +func (s *snapshot) parseModError(ctx context.Context, errText string) []*source.Diagnostic {
                            // Match on common error messages. This is really hacky, but I'm not sure
                            // of any better way. This can be removed when golang/go#39164 is resolved.
                            isInconsistentVendor := strings.Contains(errText, "inconsistent vendoring")
                            @@ -162,58 +161,78 @@
                            return nil
                            }

                            - pmf, err := s.ParseMod(ctx, fh)
                            - if err != nil {
                            - return nil
                            - }
                            - if pmf.File.Module == nil || pmf.File.Module.Syntax == nil {
                            - return nil
                            - }
                            - rng, err := rangeFromPositions(pmf.Mapper, pmf.File.Module.Syntax.Start, pmf.File.Module.Syntax.End)
                            - if err != nil {
                            - return nil
                            - }
                            - // TODO(rFindley): we shouldn't really need to call three constructors here.
                            - // Reconsider this.
                            - args := command.URIArg{protocol.URIFromSpanURI(fh.URI())}
                            switch {
                            case isInconsistentVendor:
                            + uri := s.ModFiles()[0]
                            + args := command.URIArg{URI: protocol.URIFromSpanURI(uri)}
                            + rng, err := s.uriToModDecl(ctx, uri)
                            + if err != nil {
                            + return nil
                            + }
                            cmd, err := command.NewVendorCommand("Run go mod vendor", args)
                            if err != nil {
                            return nil
                            }
                            - return &source.Diagnostic{
                            - URI: fh.URI(),
                            + return []*source.Diagnostic{{
                            + URI: uri,
                            Range: rng,
                            Severity: protocol.SeverityError,
                            Source: source.ListError,
                            Message: `Inconsistent vendoring detected. Please re-run "go mod vendor".
                            See https://github.com/golang/go/issues/39164 for more detail on this issue.`,
                            SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)},
                            - }
                            + }}

                            case isGoSumUpdates:
                            - tidyCmd, err := command.NewTidyCommand("Run go mod tidy", args)
                            - if err != nil {
                            - return nil
                            + var args []protocol.DocumentURI
                            + for _, uri := range s.ModFiles() {
                            + args = append(args, protocol.URIFromSpanURI(uri))
                            }
                            - updateCmd, err := command.NewUpdateGoSumCommand("Update go.sum", args)
                            - if err != nil {
                            - return nil
                            + var diagnostics []*source.Diagnostic
                            + for _, uri := range s.ModFiles() {
                            + rng, err := s.uriToModDecl(ctx, uri)
                            + if err != nil {
                            + return nil
                            + }
                            + tidyCmd, err := command.NewTidyCommand("Run go mod tidy", command.URIArgs{URIs: args})
                            + if err != nil {
                            + return nil
                            + }
                            + updateCmd, err := command.NewUpdateGoSumCommand("Update go.sum", command.URIArgs{URIs: args})
                            + if err != nil {
                            + return nil
                            + }
                            + diagnostics = append(diagnostics, &source.Diagnostic{
                            + URI: uri,
                            + Range: rng,
                            + Severity: protocol.SeverityError,
                            + Source: source.ListError,
                            + Message: `go.sum is out of sync with go.mod. Please update it by applying the quick fix.`,
                            + SuggestedFixes: []source.SuggestedFix{
                            + source.SuggestedFixFromCommand(tidyCmd),
                            + source.SuggestedFixFromCommand(updateCmd),
                            + },
                            + })
                            }
                            - return &source.Diagnostic{
                            - URI: fh.URI(),
                            - Range: rng,
                            - Severity: protocol.SeverityError,
                            - Source: source.ListError,
                            - Message: `go.sum is out of sync with go.mod. Please update it or run "go mod tidy".`,
                            - SuggestedFixes: []source.SuggestedFix{
                            - source.SuggestedFixFromCommand(tidyCmd),
                            - source.SuggestedFixFromCommand(updateCmd),
                            - },
                            - }
                            + return diagnostics
                            + default:
                            + return nil
                            }
                            - return nil
                            +}
                            +
                            +func (s *snapshot) uriToModDecl(ctx context.Context, uri span.URI) (protocol.Range, error) {
                            + fh, err := s.GetFile(ctx, uri)
                            + if err != nil {
                            + return protocol.Range{}, nil
                            + }
                            + pmf, err := s.ParseMod(ctx, fh)
                            + if err != nil {
                            + return protocol.Range{}, nil
                            + }
                            + if pmf.File.Module == nil || pmf.File.Module.Syntax == nil {
                            + return protocol.Range{}, nil
                            + }
                            + return rangeFromPositions(pmf.Mapper, pmf.File.Module.Syntax.Start, pmf.File.Module.Syntax.End)
                            }

                            func hashImports(ctx context.Context, wsPackages []source.Package) (string, error) {
                            diff --git a/internal/lsp/cache/snapshot.go b/internal/lsp/cache/snapshot.go
                            index 019a7e6..2c90492 100644
                            --- a/internal/lsp/cache/snapshot.go
                            +++ b/internal/lsp/cache/snapshot.go
                            @@ -1032,14 +1032,7 @@
                            }
                            criticalErr := &source.CriticalError{
                            MainError: loadErr,
                            - }
                            - // Attempt to place diagnostics in the relevant go.mod files, if any.
                            - for _, uri := range s.ModFiles() {
                            - fh, err := s.GetFile(ctx, uri)
                            - if err != nil {
                            - continue
                            - }
                            - criticalErr.DiagList = append(criticalErr.DiagList, s.extractGoCommandErrors(ctx, s, fh, loadErr.Error())...)
                            + DiagList: s.extractGoCommandErrors(ctx, s, loadErr.Error()),
                            }
                            return criticalErr
                            }
                            diff --git a/internal/lsp/code_action.go b/internal/lsp/code_action.go
                            index 1ab91fb..6c41dc3 100644
                            --- a/internal/lsp/code_action.go
                            +++ b/internal/lsp/code_action.go
                            @@ -553,6 +553,7 @@
                            }
                            return quickFixes, nil
                            }
                            +
                            func sameDiagnostic(pd protocol.Diagnostic, sd *source.Diagnostic) bool {
                            return pd.Message == sd.Message && protocol.CompareRange(pd.Range, sd.Range) == 0 && pd.Source == string(sd.Source)
                            }
                            diff --git a/internal/lsp/command.go b/internal/lsp/command.go
                            index 487e182..a959d1c 100644
                            --- a/internal/lsp/command.go
                            +++ b/internal/lsp/command.go
                            @@ -184,23 +184,41 @@

                            // TODO(rFindley): UpdateGoSum, Tidy, and Vendor could probably all be one command.

                            -func (c *commandHandler) UpdateGoSum(ctx context.Context, args command.URIArg) error {
                            +func (c *commandHandler) UpdateGoSum(ctx context.Context, args command.URIArgs) error {
                            return c.run(ctx, commandConfig{
                            requireSave: true,
                            progress: "Updating go.sum",
                            - forURI: args.URI,
                            }, func(ctx context.Context, deps commandDeps) error {
                            - return runSimpleGoCommand(ctx, deps.snapshot, source.UpdateUserModFile|source.AllowNetwork, args.URI.SpanURI(), "list", []string{"all"})
                            + for _, uri := range args.URIs {
                            + snapshot, fh, ok, release, err := c.s.beginFileRequest(ctx, uri, source.UnknownKind)
                            + defer release()
                            + if !ok {
                            + return err
                            + }
                            + if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, fh.URI(), "list", []string{"all"}); err != nil {
                            + return err
                            + }
                            + }
                            + return nil
                            })
                            }

                            -func (c *commandHandler) Tidy(ctx context.Context, args command.URIArg) error {
                            +func (c *commandHandler) Tidy(ctx context.Context, args command.URIArgs) error {
                            return c.run(ctx, commandConfig{
                            requireSave: true,
                            progress: "Running go mod tidy",
                            - forURI: args.URI,
                            }, func(ctx context.Context, deps commandDeps) error {
                            - return runSimpleGoCommand(ctx, deps.snapshot, source.UpdateUserModFile|source.AllowNetwork, args.URI.SpanURI(), "mod", []string{"tidy"})
                            + for _, uri := range args.URIs {
                            + snapshot, fh, ok, release, err := c.s.beginFileRequest(ctx, uri, source.UnknownKind)
                            + defer release()
                            + if !ok {
                            + return err
                            + }
                            + if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, fh.URI(), "mod", []string{"tidy"}); err != nil {
                            + return err
                            + }
                            + }
                            + return nil
                            })
                            }

                            diff --git a/internal/lsp/command/command_gen.go b/internal/lsp/command/command_gen.go
                            index 7fda594..3e7280c 100644
                            --- a/internal/lsp/command/command_gen.go
                            +++ b/internal/lsp/command/command_gen.go
                            @@ -137,7 +137,7 @@
                            err := s.Test(ctx, a0, a1, a2)
                            return nil, err
                            case "gopls.tidy":
                            - var a0 URIArg
                            + var a0 URIArgs
                            if err := UnmarshalArgs(params.Arguments, &a0); err != nil {
                            return nil, err
                            }
                            @@ -151,7 +151,7 @@
                            err := s.ToggleGCDetails(ctx, a0)
                            return nil, err
                            case "gopls.update_go_sum":
                            - var a0 URIArg
                            + var a0 URIArgs
                            if err := UnmarshalArgs(params.Arguments, &a0); err != nil {
                            return nil, err
                            }
                            @@ -307,7 +307,7 @@
                            }, nil
                            }

                            -func NewTidyCommand(title string, a0 URIArg) (protocol.Command, error) {
                            +func NewTidyCommand(title string, a0 URIArgs) (protocol.Command, error) {
                            args, err := MarshalArgs(a0)
                            if err != nil {
                            return protocol.Command{}, err
                            @@ -331,7 +331,7 @@
                            }, nil
                            }

                            -func NewUpdateGoSumCommand(title string, a0 URIArg) (protocol.Command, error) {
                            +func NewUpdateGoSumCommand(title string, a0 URIArgs) (protocol.Command, error) {
                            args, err := MarshalArgs(a0)
                            if err != nil {
                            return protocol.Command{}, err
                            diff --git a/internal/lsp/command/interface.go b/internal/lsp/command/interface.go
                            index 9de4b32..3d258a8 100644
                            --- a/internal/lsp/command/interface.go
                            +++ b/internal/lsp/command/interface.go
                            @@ -61,7 +61,7 @@
                            // Tidy: Run go mod tidy
                            //
                            // Runs `go mod tidy` for a module.
                            - Tidy(context.Context, URIArg) error
                            + Tidy(context.Context, URIArgs) error

                            // Vendor: Run go mod vendor
                            //
                            @@ -71,7 +71,7 @@
                            // UpdateGoSum: Update go.sum
                            //
                            // Updates the go.sum file for a module.
                            - UpdateGoSum(context.Context, URIArg) error
                            + UpdateGoSum(context.Context, URIArgs) error

                            // CheckUpgrades: Check for upgrades
                            //
                            @@ -151,6 +151,11 @@
                            URI protocol.DocumentURI
                            }

                            +type URIArgs struct {
                            + // The file URI.
                            + URIs []protocol.DocumentURI
                            +}
                            +
                            type CheckUpgradesArgs struct {
                            // The go.mod file URI.
                            URI protocol.DocumentURI
                            diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go
                            index ea77ffa..0764e6e 100644
                            --- a/internal/lsp/fake/editor.go
                            +++ b/internal/lsp/fake/editor.go
                            @@ -754,22 +754,15 @@
                            return e.codeAction(ctx, path, rng, diagnostics, protocol.QuickFix, protocol.SourceFixAll)
                            }

                            +// GetQuickFixes returns the available quick fix code actions.
                            +func (e *Editor) GetQuickFixes(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) {
                            + return e.getCodeActions(ctx, path, rng, diagnostics, protocol.QuickFix, protocol.SourceFixAll)
                            +}
                            +
                            func (e *Editor) codeAction(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) error {
                            - if e.Server == nil {
                            - return nil
                            - }
                            - params := &protocol.CodeActionParams{}
                            - params.TextDocument.URI = e.sandbox.Workdir.URI(path)
                            - params.Context.Only = only
                            - if diagnostics != nil {
                            - params.Context.Diagnostics = diagnostics
                            - }
                            - if rng != nil {
                            - params.Range = *rng
                            - }
                            - actions, err := e.Server.CodeAction(ctx, params)
                            + actions, err := e.getCodeActions(ctx, path, rng, diagnostics, only...)
                            if err != nil {
                            - return errors.Errorf("textDocument/codeAction: %w", err)
                            + return err
                            }
                            for _, action := range actions {
                            if action.Title == "" {
                            @@ -814,6 +807,22 @@
                            return nil
                            }

                            +func (e *Editor) getCodeActions(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) ([]protocol.CodeAction, error) {
                            + if e.Server == nil {
                            + return nil, nil
                            + }
                            + params := &protocol.CodeActionParams{}
                            + params.TextDocument.URI = e.sandbox.Workdir.URI(path)
                            + params.Context.Only = only
                            + if diagnostics != nil {
                            + params.Context.Diagnostics = diagnostics
                            + }
                            + if rng != nil {
                            + params.Range = *rng
                            + }
                            + return e.Server.CodeAction(ctx, params)
                            +}
                            +
                            func (e *Editor) ExecuteCommand(ctx context.Context, params *protocol.ExecuteCommandParams) (interface{}, error) {
                            if e.Server == nil {
                            return nil, nil
                            diff --git a/internal/lsp/mod/code_lens.go b/internal/lsp/mod/code_lens.go
                            index f66a3e1..1598ed5 100644
                            --- a/internal/lsp/mod/code_lens.go
                            +++ b/internal/lsp/mod/code_lens.go
                            @@ -86,7 +86,7 @@
                            return nil, nil
                            }
                            uri := protocol.URIFromSpanURI(fh.URI())
                            - cmd, err := command.NewTidyCommand("Run go mod tidy", command.URIArg{URI: uri})
                            + cmd, err := command.NewTidyCommand("Run go mod tidy", command.URIArgs{URIs: []protocol.DocumentURI{uri}})
                            if err != nil {
                            return nil, err
                            }
                            diff --git a/internal/lsp/mod/diagnostics.go b/internal/lsp/mod/diagnostics.go
                            index 041bf72..e515ada 100644
                            --- a/internal/lsp/mod/diagnostics.go
                            +++ b/internal/lsp/mod/diagnostics.go
                            @@ -105,7 +105,12 @@
                            event.Error(ctx, "diagnosing go.mod", err)
                            }
                            if err == nil {
                            - diagnostics = append(diagnostics, tidied.Diagnostics...)
                            + for _, d := range tidied.Diagnostics {
                            + if d.URI != fh.URI() {
                            + continue
                            + }
                            + diagnostics = append(diagnostics, d)
                            + }
                            }
                            return diagnostics, nil
                            }
                            diff --git a/internal/lsp/source/api_json.go b/internal/lsp/source/api_json.go
                            index dc9ce6f..1942cf3 100755
                            --- a/internal/lsp/source/api_json.go
                            +++ b/internal/lsp/source/api_json.go
                            @@ -742,7 +742,7 @@
                            Command: "gopls.tidy",
                            Title: "Run go mod tidy",
                            Doc: "Runs `go mod tidy` for a module.",
                            - ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}",
                            + ArgDoc: "{\n\t// The file URI.\n\t\"URIs\": []string,\n}",
                            },
                            {
                            Command: "gopls.toggle_gc_details",
                            @@ -754,7 +754,7 @@
                            Command: "gopls.update_go_sum",
                            Title: "Update go.sum",
                            Doc: "Updates the go.sum file for a module.",
                            - ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}",
                            + ArgDoc: "{\n\t// The file URI.\n\t\"URIs\": []string,\n}",
                            },
                            {
                            Command: "gopls.upgrade_dependency",

                            The change was submitted with unreviewed changes in the following files: The name of the file: gopls/doc/commands.md Insertions: 161, Deletions: 0. @@ -5:7, +5:7 @@ - ### **Run go generate** - Identifier: `gopls.generate` + ### **Add dependency** + Identifier: `gopls.add_dependency` @@ -8:9, +8:9 @@ - generate runs `go generate` for a given directory. + Adds a dependency to the go.mod file for a module. @@ +10:11 @@ + Args: @@ -11:13, +12:22 @@ - ### **Fill struct** - Identifier: `gopls.fill_struct` + ``` + { + // The go.mod file URI. + "URI": string, + // Additional args to pass to the go command. + "GoCmdArgs": []string, + // Whether to add a require directive. + "AddRequire": bool, + } + ``` @@ -14:16, +23:25 @@ - fill_struct is a gopls command to fill a struct with default - values. + ### **Apply a fix** + Identifier: `gopls.apply_fix` @@ +26:27 @@ + Applies a fix to a region of source code. @@ -18:20, +28:29 @@ - ### **Regenerate cgo** - Identifier: `gopls.regenerate_cgo` + Args: @@ -21:54, +30:49 @@ - regenerate_cgo regenerates cgo definitions. - - - ### **Run test(s)** - Identifier: `gopls.test` - - test runs `go test` for a specific test function. - - - ### **Run go mod tidy** - Identifier: `gopls.tidy` - - tidy runs `go mod tidy` for a module. - - - ### **Update go.sum** - Identifier: `gopls.update_go_sum` - - update_go_sum updates the go.sum file for a module. - - - ### **Undeclared name** - Identifier: `gopls.undeclared_name` - - undeclared_name adds a variable declaration for an undeclared - name. - - - ### **go get package** - Identifier: `gopls.go_get_package` - - go_get_package runs `go get` to fetch a package. - + ``` + { + // The fix to apply. + "Fix": string, + // The file URI for the document to fix. + "URI": string, + // The document range to scan for fixes. + "Range": { + "start": { + "line": uint32, + "character": uint32, + }, + "end": { + "line": uint32, + "character": uint32, + }, + }, + } + ``` @@ -58:59, +53:54 @@ - check_upgrades checks for module upgrades. + Checks for module upgrades. @@ +55:56 @@ + Args: @@ -61:96, +57:65 @@ - ### **Add dependency** - Identifier: `gopls.add_dependency` - - add_dependency adds a dependency. - - - ### **Upgrade dependency** - Identifier: `gopls.upgrade_dependency` - - upgrade_dependency upgrades a dependency. - - - ### **Remove dependency** - Identifier: `gopls.remove_dependency` - - remove_dependency removes a dependency. - - - ### **Run go mod vendor** - Identifier: `gopls.vendor` - - vendor runs `go mod vendor` for a module. - - - ### **Extract to variable** - Identifier: `gopls.extract_variable` - - extract_variable extracts an expression to a variable. - - - ### **Extract to function** - Identifier: `gopls.extract_function` - - extract_function extracts statements to a function. - + ``` + { + // The go.mod file URI. + "URI": string, + // The modules to check. + "Modules": []string, + } + ``` @@ -100:101, +69:70 @@ - gc_details controls calculation of gc annotations. + Toggle the calculation of gc annotations. @@ +71:92 @@ + Args: + + ``` + string + ``` + + ### **Run go generate** + Identifier: `gopls.generate` + + Runs `go generate` for a given directory. + + Args: + + ``` + { + // URI for the directory to generate. + "Dir": string, + // Whether to generate recursively (go generate ./...) + "Recursive": bool, + } + ``` @@ -106:107, +96:97 @@ - generate_gopls_mod (re)generates the gopls.mod file. + (Re)generate the gopls.mod file for a workspace. @@ +98:259 @@ + Args: + + ``` + { + // The file URI. + "URI": string, + } + ``` + + ### **go get package** + Identifier: `gopls.go_get_package` + + Runs `go get` to fetch a package. + + Args: + + ``` + { + // Any document URI within the relevant module. + "URI": string, + // The package to go get. + "Pkg": string, + "AddRequire": bool, + } + ``` + + ### **Regenerate cgo** + Identifier: `gopls.regenerate_cgo` + + Regenerates cgo definitions. + + Args: + + ``` + { + // The file URI. + "URI": string, + } + ``` + + ### **Remove dependency** + Identifier: `gopls.remove_dependency` + + Removes a dependency from the go.mod file of a module. + + Args: + + ``` + { + // The go.mod file URI. + "URI": string, + // The module path to remove. + "ModulePath": string, + "OnlyDiagnostic": bool, + } + ``` + + ### **Run test(s)** + Identifier: `gopls.run_tests` + + Runs `go test` for a specific set of test or benchmark functions. + + Args: + + ``` + { + // The test file containing the tests to run. + "URI": string, + // Specific test names to run, e.g. TestFoo. + "Tests": []string, + // Specific benchmarks to run, e.g. BenchmarkFoo. + "Benchmarks": []string, + } + ``` + + ### **Run test(s) (legacy)** + Identifier: `gopls.test` + + Runs `go test` for a specific set of test or benchmark functions. + + Args: + + ``` + string, + []string, + []string + ``` + + ### **Run go mod tidy** + Identifier: `gopls.tidy` + + Runs `go mod tidy` for a module. + + Args: + + ``` + { + // The file URI. + "URIs": []string, + } + ``` + + ### **Toggle gc_details** + Identifier: `gopls.toggle_gc_details` + + Toggle the calculation of gc annotations. + + Args: + + ``` + { + // The file URI. + "URI": string, + } + ``` + + ### **Update go.sum** + Identifier: `gopls.update_go_sum` + + Updates the go.sum file for a module. + + Args: + + ``` + { + // The file URI. + "URIs": []string, + } + ``` + + ### **Upgrade dependency** + Identifier: `gopls.upgrade_dependency` + + Upgrades a dependency in the go.mod file for a module. + + Args: + + ``` + { + // The go.mod file URI. + "URI": string, + // Additional args to pass to the go command. + "GoCmdArgs": []string, + // Whether to add a require directive. + "AddRequire": bool, + } + ``` + + ### **Run go mod vendor** + Identifier: `gopls.vendor` + + Runs `go mod vendor` for a module. + + Args: + + ``` + { + // The file URI. + "URI": string, + } + ``` The name of the file: gopls/doc/generate.go Insertions: 49, Deletions: 0. @@ +31:33 @@ + "golang.org/x/tools/internal/lsp/command" + "golang.org/x/tools/internal/lsp/command/commandmeta" @@ -89:90, +91:92 @@ - c.Command = source.CommandPrefix + c.Command + c.Command = command.ID(c.Command) @@ -370:390 @@ - // The code that defines commands is much more complicated than the - // code that defines options, so reading comments for the Doc is very - // fragile. If this causes problems, we should switch to a dynamic - // approach and put the doc in the Commands struct rather than reading - // from the source code. - - // Find the Commands slice. - typesSlice := pkg.Types.Scope().Lookup("Commands") - f, err := fileForPos(pkg, typesSlice.Pos()) - if err != nil { - return nil, err - } - path, _ := astutil.PathEnclosingInterval(f, typesSlice.Pos(), typesSlice.Pos()) - vspec := path[1].(*ast.ValueSpec) - var astSlice *ast.CompositeLit - for i, name := range vspec.Names { - if name.Name == "Commands" { - astSlice = vspec.Values[i].(*ast.CompositeLit) - } - } @@ +375:379 @@ + _, cmds, err := commandmeta.Load() + if err != nil { + return nil, err + } @@ -394:432, +380:381 @@ - for _, elt := range astSlice.Elts { - // Find the composite literal of the Command. - typesCommand := pkg.TypesInfo.ObjectOf(elt.(*ast.Ident)) - path, _ := astutil.PathEnclosingInterval(f, typesCommand.Pos(), typesCommand.Pos()) - vspec := path[1].(*ast.ValueSpec) - - var astCommand ast.Expr - for i, name := range vspec.Names { - if name.Name == typesCommand.Name() { - astCommand = vspec.Values[i] - } - } - - // Read the Name and Title fields of the literal. - var name, title string - ast.Inspect(astCommand, func(n ast.Node) bool { - kv, ok := n.(*ast.KeyValueExpr) - if ok { - k := kv.Key.(*ast.Ident).Name - switch k { - case "Name": - name = strings.Trim(kv.Value.(*ast.BasicLit).Value, `"`) - case "Title": - title = strings.Trim(kv.Value.(*ast.BasicLit).Value, `"`) - } - } - return true - }) - - if title == "" { - title = name - } - - // Conventionally, the doc starts with the name of the variable. - // Replace it with the name of the command. - doc := vspec.Doc.Text() - doc = strings.Replace(doc, typesCommand.Name(), name, 1) - + for _, cmd := range cmds { @@ -433:436, +382:386 @@ - Command: name, - Title: title, - Doc: doc, + Command: cmd.Name, + Title: cmd.Title, + Doc: cmd.Doc, + ArgDoc: argsDoc(cmd.Args), @@ +391:440 @@ + func argsDoc(args []*commandmeta.Field) string { + var b strings.Builder + for i, arg := range args { + b.WriteString(argDoc(arg, 0)) + if i != len(args)-1 { + b.WriteString(",\n") + } + } + return b.String() + } + + func argDoc(arg *commandmeta.Field, level int) string { + // Max level to expand struct fields. + const maxLevel = 3 + if len(arg.Fields) > 0 { + if level < maxLevel { + return structDoc(arg.Fields, level) + } + return "{ ... }" + } + under := arg.Type.Underlying() + switch u := under.(type) { + case *types.Slice: + return fmt.Sprintf("[]%s", u.Elem().Underlying().String()) + } + return types.TypeString(under, nil) + } + + func structDoc(fields []*commandmeta.Field, level int) string { + var b strings.Builder + b.WriteString("{\n") + indent := strings.Repeat("\t", level) + for _, fld := range fields { + if fld.Doc != "" && level == 0 { + doclines := strings.Split(fld.Doc, "\n") + for _, line := range doclines { + fmt.Fprintf(&b, "%s\t// %s\n", indent, line) + } + } + tag := fld.JSONTag + if tag == "" { + tag = fld.Name + } + fmt.Fprintf(&b, "%s\t%q: %s,\n", indent, tag, argDoc(fld, level+1)) + } + fmt.Fprintf(&b, "%s}", indent) + return b.String() + } + @@ -442:443, +441:442 @@ - lensNames := map[string]struct{}{} + all := map[command.Command]struct{}{} @@ -444:445, +443:444 @@ - lensNames[k] = struct{}{} + all[k] = struct{}{} @@ -447:448, +446:450 @@ - lensNames[k] = struct{}{} + if _, ok := all[k]; ok { + panic(fmt.Sprintf("duplicate lens %q", string(k))) + } + all[k] = struct{}{} @@ -453:454, +455:456 @@ - if _, ok := lensNames[cmd.Command]; ok { + if _, ok := all[command.Command(cmd.Command)]; ok { @@ +738:741 @@ + if command.ArgDoc != "" { + fmt.Fprintf(section, "Args:\n\n```\n%s\n```\n\n", command.ArgDoc) + } The name of the file: gopls/internal/regtest/codelens/codelens_test.go Insertions: 1, Deletions: 1. @@ +10:11 @@ + "time" @@ +14:15 @@ + "golang.org/x/tools/internal/lsp/command" @@ -15:16 @@ - "golang.org/x/tools/internal/lsp/source" @@ -54:55, +55:56 @@ - enabled: map[string]bool{source.CommandGenerate.Name: false}, + enabled: map[string]bool{string(command.Generate): false}, @@ -162:163, +163:164 @@ - env.ExecuteCodeLensCommand("go.mod", source.CommandCheckUpgrades) + env.ExecuteCodeLensCommand("go.mod", command.CheckUpgrades) @@ -166:167, +167:168 @@ - env.ApplyQuickFixes("go.mod", d.Diagnostics...) + env.ApplyQuickFixes("go.mod", d.Diagnostics) @@ -220:221, +221:222 @@ - env.ExecuteCodeLensCommand("go.mod", source.CommandTidy) + env.ExecuteCodeLensCommand("go.mod", command.Tidy) @@ -267:268, +268:269 @@ - env.ExecuteCodeLensCommand("cgo.go", source.CommandRegenerateCgo) + env.ExecuteCodeLensCommand("cgo.go", command.RegenerateCgo) @@ +299:301 @@ + // TestGCDetails seems to suffer from poor performance on certain builders. Give it some more time to complete. + Timeout(60*time.Second), @@ -300:301, +303:304 @@ - env.ExecuteCodeLensCommand("main.go", source.CommandToggleDetails) + env.ExecuteCodeLensCommand("main.go", command.GCDetails) @@ -333:334, +336:337 @@ - env.ExecuteCodeLensCommand("main.go", source.CommandToggleDetails) + env.ExecuteCodeLensCommand("main.go", command.GCDetails) The name of the file: gopls/internal/regtest/diagnostics/diagnostics_test.go Insertions: 4, Deletions: 4. @@ -537:538, +537:538 @@ - env.ApplyQuickFixes("main.go", d.Diagnostics...) + env.ApplyQuickFixes("main.go", d.Diagnostics) @@ -678:679, +678:679 @@ - env.ApplyQuickFixes("main.go", d.Diagnostics...) + env.ApplyQuickFixes("main.go", d.Diagnostics) @@ -698:699, +698:699 @@ - env.ApplyQuickFixes("go.mod", d.Diagnostics...) + env.ApplyQuickFixes("go.mod", d.Diagnostics) @@ -738:739, +738:739 @@ - env.DiagnosticAtRegexpWithMessage("main.go", `"github.com/ardanlabs/conf"`, "your go.mod file"), + env.DiagnosticAtRegexpWithMessage("main.go", `"github.com/ardanlabs/conf"`, "no required module"), @@ -742:743, +742:743 @@ - env.ApplyQuickFixes("main.go", d.Diagnostics...) + env.ApplyQuickFixes("main.go", d.Diagnostics) The name of the file: gopls/internal/regtest/misc/imports_test.go Insertions: 1, Deletions: 1. @@ -210:211, +210:211 @@ - env.ApplyQuickFixes("a/a.go", d.Diagnostics...) + env.ApplyQuickFixes("a/a.go", d.Diagnostics) The name of the file: gopls/internal/regtest/misc/vendor_test.go Insertions: 1, Deletions: 5. @@ -12:13 @@ - "golang.org/x/tools/internal/lsp/source" @@ -71:76, +70:71 @@ - env.ApplyQuickFixes("go.mod", d.Diagnostics...) - - // Check for file changes when the command completes. - env.Await(CompletedWork(source.CommandVendor.Title, 1)) - env.CheckForFileChanges() + env.ApplyQuickFixes("go.mod", d.Diagnostics) The name of the file: gopls/internal/regtest/modfile/modfile_test.go Insertions: 11, Deletions: 11. @@ -182:183, +182:183 @@ - env.ApplyQuickFixes("a/main.go", goGetDiag) + env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{goGetDiag}) @@ -232:233, +232:233 @@ - env.ApplyQuickFixes("a/main.go", randomDiag) + env.ApplyQuickFixes("a/main.go", []protocol.Diagnostic{randomDiag}) @@ -279:280, +279:280 @@ - env.ApplyQuickFixes("a/go.mod", d.Diagnostics...) + env.ApplyQuickFixes("a/go.mod", d.Diagnostics) @@ -324:325, +324:325 @@ - env.ApplyQuickFixes("a/go.mod", d.Diagnostics...) + env.ApplyQuickFixes("a/go.mod", d.Diagnostics) @@ -387:388, +387:388 @@ - env.ApplyQuickFixes("a/main.go", d.Diagnostics...) + env.ApplyQuickFixes("a/main.go", d.Diagnostics) @@ -460:461, +460:461 @@ - var _ = blah.Name + var V1Name = blah.Name @@ -473:474, +473:474 @@ - example.com/blah/v2 v2.0.0 h1:w5baE9JuuU11s3de3yWx2sU05AhNkgLYdZ4qukv+V0k= + example.com/blah/v2 v2.0.0 h1:DNPsFPkKtTdxclRheaMCiYAoYizp6PuBzO0OmLOO0pY= @@ -488:489 @@ - var d protocol.PublishDiagnosticsParams @@ -490:494, +489:493 @@ - OnceMet( - DiagnosticAt("a/go.mod", 0, 0), - ReadDiagnostics("a/go.mod", &d), - ), + // We would like for the error to appear in the v2 module, but + // as of writing non-workspace packages are not diagnosed. + env.DiagnosticAtRegexpWithMessage("a/main.go", `"example.com/blah/v2"`, "cannot find module providing"), + env.DiagnosticAtRegexpWithMessage("a/go.mod", `require example.com/blah/v2`, "cannot find module providing"), @@ -495:496, +494:495 @@ - env.ApplyQuickFixes("a/main.go", d.Diagnostics...) + env.ApplyQuickFixes("a/go.mod", env.DiagnosticsFor("a/go.mod").Diagnostics) @@ -505:506, +504:505 @@ - env.Await(EmptyDiagnostics("a/go.mod")) + env.Await(EmptyDiagnostics("a/main.go")) @@ -554:555, +553:554 @@ - env.ApplyQuickFixes("a/go.mod", d.Diagnostics...) + env.ApplyQuickFixes("a/go.mod", d.Diagnostics) @@ +719:721 @@ + require example.com v1.2.3 + @@ -736:737 @@ - env.DiagnosticAtRegexpWithMessage("b/go.mod", "module modb.com", "not in your go.mod file"), @@ -817:818 @@ - Modes(Singleton), // workspace modules don't use -mod=readonly (golang/go#43346) @@ -828:829, +827:828 @@ - env.ApplyQuickFixes("go.mod", d.Diagnostics...) + env.ApplyQuickFixes("go.mod", d.Diagnostics) @@ -939:940, +938:939 @@ - env.ApplyQuickFixes("go.mod", d.Diagnostics...) + env.ApplyQuickFixes("go.mod", d.Diagnostics) @@ -992:993, +991:992 @@ - env.ApplyQuickFixes("go.mod", diagnostics...) + env.ApplyQuickFixes("go.mod", diagnostics) @@ -1045:1046, +1044:1045 @@ - env.ApplyQuickFixes("go.mod", diagnostic) + env.ApplyQuickFixes("go.mod", []protocol.Diagnostic{diagnostic}) The name of the file: gopls/internal/regtest/workspace/workspace_test.go Insertions: 24, Deletions: 21. @@ -290:302, +290:299 @@ - if testenv.Go1Point() < 14 { - // On 1.14 and above, the go mod tidy diagnostics accidentally - // download for us. This is the behavior we actually want. - d := protocol.PublishDiagnosticsParams{} - env.Await( - OnceMet( - env.DiagnosticAtRegexpWithMessage("moda/a/go.mod", "require b.com v1.2.3", "b....@v1.2.3"), - ReadDiagnostics("moda/a/go.mod", &d), - ), - ) - env.ApplyQuickFixes("moda/a/go.mod", d.Diagnostics...) - } + + d := protocol.PublishDiagnosticsParams{} + env.Await( + OnceMet( + env.DiagnosticAtRegexpWithMessage("moda/a/go.mod", "require b.com v1.2.3", "b....@v1.2.3 has not been downloaded"), + ReadDiagnostics("moda/a/go.mod", &d), + ), + ) + env.ApplyQuickFixes("moda/a/go.mod", d.Diagnostics) @@ -510:511, +507:508 @@ - env.ApplyQuickFixes("modb/go.mod", d.Diagnostics...) + env.ApplyQuickFixes("modb/go.mod", d.Diagnostics) @@ -790:791, +787:788 @@ - func TestOneUntidyModule(t *testing.T) { + func TestMultiModule_OneBrokenModule(t *testing.T) { @@ +820:821 @@ + env.OpenFile("a/go.mod") @@ -827:829, +825:826 @@ - // TODO(rstambler): The "add dependency" diagnostic is also broken. - if d.Message != `go.sum is out of sync with go.mod. Please update it or run "go list -mod=mod ./...".` { + if d.Message != `go.sum is out of sync with go.mod. Please update it by applying the quick fix.` { @@ -831:837, +828:840 @@ - env.ApplyQuickFixes("a/go.mod", d) - env.Await( - EmptyDiagnostics("a/go.mod"), - ) - } - + actions, err := env.GetQuickFixes("a/go.mod", []protocol.Diagnostic{d}) + if err != nil { + t.Fatal(err) + } + if len(actions) != 2 { + t.Fatalf("expected 2 code actions, got %v", len(actions)) + } + env.ApplyQuickFixes("a/go.mod", []protocol.Diagnostic{d}) + } + env.Await( + EmptyDiagnostics("a/go.mod"), + ) The name of the file: gopls/internal/regtest/wrappers.go Insertions: 7, Deletions: 1. @@ +11:12 @@ + "golang.org/x/tools/internal/lsp/command" @@ -13:14 @@ - "golang.org/x/tools/internal/lsp/source" @@ -195:196, +195:196 @@ - func (e *Env) ApplyQuickFixes(path string, diagnostics ...protocol.Diagnostic) { + func (e *Env) ApplyQuickFixes(path string, diagnostics []protocol.Diagnostic) { @@ +202:208 @@ + // GetQuickFixes returns the available quick fix code actions. + func (e *Env) GetQuickFixes(path string, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) { + e.T.Helper() + return e.Editor.GetQuickFixes(e.Ctx, path, nil, diagnostics) + } + @@ -301:302, +307:308 @@ - func (e *Env) ExecuteCodeLensCommand(path string, cmd *source.Command) { + func (e *Env) ExecuteCodeLensCommand(path string, cmd command.Command) { The name of the file: internal/lsp/cache/mod.go Insertions: 0, Deletions: 2. @@ +17:18 @@ + "golang.org/x/tools/internal/lsp/command" @@ -220:222 @@ - // If the error message contains a position, use that. Don't pass a file - // handle in, as it might not be the file associated with the error. @@ -260:261 @@ - outer: @@ -274:292, +272:275 @@ - - for _, req := range pm.File.Require { - if req.Mod == ver { - reference = req.Syntax - break outer - } - } - for _, ex := range pm.File.Exclude { - if ex.Mod == ver { - reference = ex.Syntax - break outer - } - } - for _, rep := range pm.File.Replace { - if rep.New == ver || rep.Old == ver { - reference = rep.Syntax - break outer - } + reference = findModuleReference(pm.File, ver) + if reference != nil { + break @@ -311:312, +294:300 @@ - args, err := source.MarshalArgs(fh.URI(), false, []string{fmt.Sprintf("%v@%v", innermost.Path, innermost.Version)}) + title := fmt.Sprintf("Download %v@%v", innermost.Path, innermost.Version) + cmd, err := command.NewAddDependencyCommand(title, command.DependencyArgs{ + URI: protocol.URIFromSpanURI(fh.URI()), + AddRequire: false, + GoCmdArgs: []string{fmt.Sprintf("%v@%v", innermost.Path, innermost.Version)}, + }) @@ -320:333, +308:314 @@ - URI: fh.URI(), - Range: rng, - Severity: protocol.SeverityError, - Message: msg, - Source: source.ListError, - SuggestedFixes: []source.SuggestedFix{{ - Title: fmt.Sprintf("Download %v@%v", innermost.Path, innermost.Version), - Command: &protocol.Command{ - Title: source.CommandAddDependency.Title, - Command: source.CommandAddDependency.ID(), - Arguments: args, - }, - }}, + URI: fh.URI(), + Range: rng, + Severity: protocol.SeverityError, + Message: msg, + Source: source.ListError, + SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, @@ +329:348 @@ + func findModuleReference(mf *modfile.File, ver module.Version) *modfile.Line { + for _, req := range mf.Require { + if req.Mod == ver { + return req.Syntax + } + } + for _, ex := range mf.Exclude { + if ex.Mod == ver { + return ex.Syntax + } + } + for _, rep := range mf.Replace { + if rep.New == ver || rep.Old == ver { + return rep.Syntax + } + } + return nil + } + The name of the file: internal/lsp/cache/mod_tidy.go Insertions: 23, Deletions: 42. @@ -8:9 @@ - "encoding/json" @@ +20:21 @@ + "golang.org/x/tools/internal/lsp/command" @@ -110:111, +110:111 @@ - tmpURI, inv, cleanup, err := snapshot.goCommandInvocation(ctx, source.WriteTemporaryModFile|source.AllowNetwork, inv) + tmpURI, inv, cleanup, err := snapshot.goCommandInvocation(ctx, source.WriteTemporaryModFile, inv) @@ -153:154 @@ - @@ -164:178 @@ - // Don't show inconsistent vendoring errors for multi-module workspaces - // because the workspace module doesn't support vendoring, and we don't - // want to accidentally create new vendor directories. - if isInconsistentVendor && len(s.ModFiles()) > 1 { - return nil - } - var args []json.RawMessage - for _, uri := range s.ModFiles() { - arg, err := source.MarshalArgs(uri) - if err != nil { - return nil - } - args = append(args, arg...) - } @@ +166:167 @@ + args := command.URIArg{URI: protocol.URIFromSpanURI(uri)} @@ +171:175 @@ + cmd, err := command.NewVendorCommand("Run go mod vendor", args) + if err != nil { + return nil + } @@ -192:202, +182:190 @@ - SuggestedFixes: []source.SuggestedFix{{ - Title: source.CommandVendor.Title, - Command: &protocol.Command{ - Command: source.CommandVendor.ID(), - Title: source.CommandVendor.Title, - Arguments: args, - }, - }}}, - } - case isGoSumUpdates: + SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, + }} + + case isGoSumUpdates: + var args []protocol.DocumentURI + for _, uri := range s.ModFiles() { + args = append(args, protocol.URIFromSpanURI(uri)) + } @@ +196:204 @@ + tidyCmd, err := command.NewTidyCommand("Run go mod tidy", command.URIArgs{URIs: args}) + if err != nil { + return nil + } + updateCmd, err := command.NewUpdateGoSumCommand("Update go.sum", command.URIArgs{URIs: args}) + if err != nil { + return nil + } @@ -213:231, +209:213 @@ - Message: `go.sum is out of sync with go.mod. Please update it or run "go list -mod=mod ./...".`, - SuggestedFixes: []source.SuggestedFix{ - { - Title: source.CommandTidy.Title, - Command: &protocol.Command{ - Command: source.CommandTidy.ID(), - Title: source.CommandTidy.Title, - Arguments: args, - }, - }, - { - Title: source.CommandUpdateGoSum.Title, - Command: &protocol.Command{ - Command: source.CommandUpdateGoSum.ID(), - Title: source.CommandUpdateGoSum.Title, - Arguments: args, - }, - }, + Message: `go.sum is out of sync with go.mod. Please update it by applying the quick fix.`, + SuggestedFixes: []source.SuggestedFix{ + source.SuggestedFixFromCommand(tidyCmd), + source.SuggestedFixFromCommand(updateCmd), @@ -414:415, +396:402 @@ - args, err := source.MarshalArgs(m.URI, onlyDiagnostic, req.Mod.Path) + title := fmt.Sprintf("Remove dependency: %s", req.Mod.Path) + cmd, err := command.NewRemoveDependencyCommand(title, command.RemoveDependencyArgs{ + URI: protocol.URIFromSpanURI(m.URI), + OnlyDiagnostic: onlyDiagnostic, + ModulePath: req.Mod.Path, + }) @@ -419:432, +406:412 @@ - URI: m.URI, - Range: rng, - Severity: protocol.SeverityWarning, - Source: source.ModTidyError, - Message: fmt.Sprintf("%s is not used in this module", req.Mod.Path), - SuggestedFixes: []source.SuggestedFix{{ - Title: fmt.Sprintf("Remove dependency: %s", req.Mod.Path), - Command: &protocol.Command{ - Title: source.CommandRemoveDependency.Title, - Command: source.CommandRemoveDependency.ID(), - Arguments: args, - }, - }}, + URI: m.URI, + Range: rng, + Severity: protocol.SeverityWarning, + Source: source.ModTidyError, + Message: fmt.Sprintf("%s is not used in this module", req.Mod.Path), + SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, @@ -488:489, +468:474 @@ - args, err := source.MarshalArgs(pm.Mapper.URI, !req.Indirect, []string{req.Mod.Path + "@" + req.Mod.Version}) + title := fmt.Sprintf("Add %s to your go.mod file", req.Mod.Path) + cmd, err := command.NewAddDependencyCommand(title, command.DependencyArgs{ + URI: protocol.URIFromSpanURI(pm.Mapper.URI), + AddRequire: !req.Indirect, + GoCmdArgs: []string{req.Mod.Path + "@" + req.Mod.Version}, + }) @@ -493:506, +478:484 @@ - URI: pm.Mapper.URI, - Range: rng, - Severity: protocol.SeverityError, - Source: source.ModTidyError, - Message: fmt.Sprintf("%s is not in your go.mod file", req.Mod.Path), - SuggestedFixes: []source.SuggestedFix{{ - Title: fmt.Sprintf("Add %s to your go.mod file", req.Mod.Path), - Command: &protocol.Command{ - Title: source.CommandAddDependency.Title, - Command: source.CommandAddDependency.ID(), - Arguments: args, - }, - }}, + URI: pm.Mapper.URI, + Range: rng, + Severity: protocol.SeverityError, + Source: source.ModTidyError, + Message: fmt.Sprintf("%s is not in your go.mod file", req.Mod.Path), + SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, The name of the file: internal/lsp/code_action.go Insertions: 1, Deletions: 5. @@ -9:10 @@ - "regexp" @@ +15:16 @@ + "golang.org/x/tools/internal/lsp/command" @@ +21:22 @@ + errors "golang.org/x/xerrors" @@ -107:116 @@ - // Fix unresolved imports with "go get". This is separate from the - // goimports fixes because goimports will not remove an import - // that appears to be used, even if currently unresolved. - actions, err := goGetFixes(ctx, snapshot, fh.URI(), diagnostics) - if err != nil { - return nil, err - } - codeActions = append(codeActions, actions...) - @@ +128:133 @@ + pkgQuickFixes, err := quickFixesForDiagnostics(ctx, snapshot, diagnostics, pkg.GetDiagnostics()) + if err != nil { + return nil, err + } + codeActions = append(codeActions, pkgQuickFixes...) @@ -270:271, +267:268 @@ - if analyzer.Command != nil { + if analyzer.Fix != "" { @@ -362:394 @@ - var importErrorRe = regexp.MustCompile(`could not import ([^\s]+)`) - - func goGetFixes(ctx context.Context, snapshot source.Snapshot, uri span.URI, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) { - if snapshot.GoModForFile(uri) == "" { - // Go get only supports module mode for now. - return nil, nil - } - - var actions []protocol.CodeAction - for _, diag := range diagnostics { - matches := importErrorRe.FindStringSubmatch(diag.Message) - if len(matches) == 0 { - return nil, nil - } - args, err := source.MarshalArgs(uri, matches[1]) - if err != nil { - return nil, err - } - actions = append(actions, protocol.CodeAction{ - Title: fmt.Sprintf("go get package %v", matches[1]), - Diagnostics: []protocol.Diagnostic{diag}, - Kind: protocol.QuickFix, - Command: &protocol.Command{ - Title: source.CommandGoGetPackage.Title, - Command: source.CommandGoGetPackage.ID(), - Arguments: args, - }, - }) - } - return actions, nil - } - @@ -400:401, +365:366 @@ - if a.Command == nil { + if a.Fix == "" { @@ -437:439, +402:404 @@ - if analyzer.Command == nil { - return nil, fmt.Errorf("no command for convenience analyzer %s", analyzer.Analyzer.Name) + if analyzer.Fix == "" { + return nil, fmt.Errorf("no fix for convenience analyzer %s", analyzer.Analyzer.Name) @@ -440:441, +405:410 @@ - jsonArgs, err := source.MarshalArgs(sd.URI, sd.Range) + cmd, err := command.NewApplyFixCommand(sd.Message, command.ApplyFixArgs{ + URI: protocol.URIFromSpanURI(sd.URI), + Range: sd.Range, + Fix: analyzer.Fix, + }) @@ -452:457, +421:422 @@ - Command: &protocol.Command{ - Command: analyzer.Command.ID(), - Title: sd.Message, - Arguments: jsonArgs, - }, + Command: &cmd, @@ -468:469, +433:438 @@ - jsonArgs, err := source.MarshalArgs(uri, rng) + _, pgf, err := source.GetParsedFile(ctx, snapshot, fh, source.NarrowestPackage) + if err != nil { + return nil, errors.Errorf("getting file for Identifier: %w", err) + } + srng, err := pgf.Mapper.RangeToSpanRange(rng) @@ -472:479, +441:451 @@ - var actions []protocol.CodeAction - for _, command := range []*source.Command{ - source.CommandExtractFunction, - source.CommandExtractVariable, - } { - if !command.Applies(ctx, snapshot, fh, rng) { - continue + puri := protocol.URIFromSpanURI(uri) + var commands []protocol.Command + if _, ok, _ := source.CanExtractFunction(snapshot.FileSet(), srng, pgf.Src, pgf.File); ok { + cmd, err := command.NewApplyFixCommand("Extract to function", command.ApplyFixArgs{ + URI: puri, + Fix: source.ExtractFunction, + Range: rng, + }) + if err != nil { + return nil, err @@ +452:467 @@ + commands = append(commands, cmd) + } + if _, _, ok, _ := source.CanExtractVariable(srng, pgf.File); ok { + cmd, err := command.NewApplyFixCommand("Extract variable", command.ApplyFixArgs{ + URI: puri, + Fix: source.ExtractVariable, + Range: rng, + }) + if err != nil { + return nil, err + } + commands = append(commands, cmd) + } + var actions []protocol.CodeAction + for _, cmd := range commands { @@ -481:487, +468:471 @@ - Title: command.Title, - Kind: protocol.RefactorExtract, - Command: &protocol.Command{ - Command: command.ID(), - Arguments: jsonArgs, - }, + Title: cmd.Title, + Kind: protocol.RefactorExtract, + Command: &cmd, @@ -506:507, +490:491 @@ - func moduleQuickFixes(ctx context.Context, snapshot source.Snapshot, fh source.VersionedFileHandle, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) { + func moduleQuickFixes(ctx context.Context, snapshot source.Snapshot, fh source.VersionedFileHandle, pdiags []protocol.Diagnostic) ([]protocol.CodeAction, error) { @@ -522:523, +506:507 @@ - errors, err := mod.DiagnosticsForMod(ctx, snapshot, modFH) + diags, err := mod.DiagnosticsForMod(ctx, snapshot, modFH) @@ +510:514 @@ + return quickFixesForDiagnostics(ctx, snapshot, pdiags, diags) + } + + func quickFixesForDiagnostics(ctx context.Context, snapshot source.Snapshot, pdiags []protocol.Diagnostic, sdiags []*source.Diagnostic) ([]protocol.CodeAction, error) { @@ -527:532, +515:516 @@ - for _, e := range errors { - // Don't offer fixes for diagnostics in other go.mod files. - if fh.Kind() == source.Mod && e.URI != modFH.URI() { - continue - } + for _, e := range sdiags { @@ -533:534, +517:518 @@ - for _, d := range diagnostics { + for _, d := range pdiags { @@ +534:535 @@ + @@ -551:553, +536:539 @@ - if uri != modFH.URI() { - continue + fh, err := snapshot.GetVersionedFile(ctx, uri) + if err != nil { + return nil, err @@ -556:557, +542:543 @@ - Version: modFH.Version(), + Version: fh.Version(), @@ -558:559, +544:545 @@ - URI: protocol.URIFromSpanURI(modFH.URI()), + URI: protocol.URIFromSpanURI(uri), @@ -602:603, +588:589 @@ - jsonArgs, err := source.MarshalArgs(uri, tests, benchmarks) + cmd, err := command.NewTestCommand("Run tests and benchmarks", protocol.URIFromSpanURI(uri), tests, benchmarks) @@ -607:614, +593:596 @@ - Title: source.CommandTest.Name, - Kind: protocol.GoTest, - Command: &protocol.Command{ - Title: source.CommandTest.Title, - Command: source.CommandTest.ID(), - Arguments: jsonArgs, - }, + Title: cmd.Title, + Kind: protocol.GoTest, + Command: &cmd, The name of the file: internal/lsp/command.go Insertions: 85, Deletions: 145. @@ +20:21 @@ + "golang.org/x/tools/internal/lsp/command" @@ -28:39, +29:30 @@ - var command *source.Command - for _, c := range source.Commands { - if c.ID() == params.Command { - command = c - break - } - } - if command == nil { - return nil, fmt.Errorf("no known command") - } - var match bool + var found bool @@ -40:42, +31:33 @@ - if command.ID() == name { - match = true + if name == params.Command { + found = true @@ -45:47, +36:38 @@ - if !match { - return nil, fmt.Errorf("%s is not a supported command", command.ID()) + if !found { + return nil, fmt.Errorf("%s is not a supported command", params.Command) @@ -48:55, +39:77 @@ - // Some commands require that all files are saved to disk. If we detect - // unsaved files, warn the user instead of running the commands. - unsaved := false - for _, overlay := range s.session.Overlays() { - if !overlay.Saved() { - unsaved = true - break + + handler := &commandHandler{ + s: s, + params: params, + } + return command.Dispatch(ctx, params, handler) + } + + type commandHandler struct { + s *Server + params *protocol.ExecuteCommandParams + } + + // commandConfig configures common command set-up and execution. + type commandConfig struct { + async bool + requireSave bool // whether all files must be saved for the command to work + progress string // title to use for progress reporting. If empty, no progress will be reported. + forURI protocol.DocumentURI // URI to resolve to a snapshot. If unset, snapshot will be nil. + } + + // commandDeps is evaluated from a commandConfig. Note that not all fields may + // be populated, depending on which configuration is set. See comments in-line + // for details. + type commandDeps struct { + snapshot source.Snapshot // present if cfg.forURI was set + fh source.VersionedFileHandle // present if cfg.forURI was set + work *workDone // present cfg.progress was set + } + + type commandFunc func(context.Context, commandDeps) error + + func (c *commandHandler) run(ctx context.Context, cfg commandConfig, run commandFunc) (err error) { + if cfg.requireSave { + for _, overlay := range c.s.session.Overlays() { + if !overlay.Saved() { + return errors.New("All files must be saved first") + } @@ -57:70, +79:87 @@ - if unsaved { - switch params.Command { - case source.CommandTest.ID(), - source.CommandGenerate.ID(), - source.CommandToggleDetails.ID(), - source.CommandAddDependency.ID(), - source.CommandUpgradeDependency.ID(), - source.CommandRemoveDependency.ID(), - source.CommandVendor.ID(): - // TODO(PJW): for Toggle, not an error if it is being disabled - err := errors.New("All files must be saved first") - s.showCommandError(ctx, command.Title, err) - return nil, nil + var deps commandDeps + if cfg.forURI != "" { + var ok bool + var release func() + deps.snapshot, deps.fh, ok, release, err = c.s.beginFileRequest(ctx, cfg.forURI, source.UnknownKind) + defer release() + if !ok { + return err @@ -73:82, +90:92 @@ - - var work *workDone - // Don't show progress for suggested fixes. They should be quick. - if !command.IsSuggestedFix() { - // Start progress prior to spinning off a goroutine specifically so that - // clients are aware of the work item before the command completes. This - // matters for regtests, where having a continuous thread of work is - // convenient for assertions. - work = s.progress.start(ctx, command.Title, "Running...", params.WorkDoneToken, cancel) + if cfg.progress != "" { + deps.work = c.s.progress.start(ctx, cfg.progress, "Running...", c.params.WorkDoneToken, cancel) @@ -83:85, +93:94 @@ - - run := func() { + runcmd := func() error { @@ -86:87, +95:96 @@ - err := s.runCommand(ctx, work, command, params.Arguments) + err := run(ctx, deps) @@ -89:90, +98:99 @@ - work.end(command.Title + ": canceled") + deps.work.end("canceled") @@ -91:96, +100:102 @@ - event.Error(ctx, fmt.Sprintf("%s: command error", command.Title), err) - work.end(command.Title + ": failed") - // Show a message when work completes with error, because the progress end - // message is typically dismissed immediately by LSP clients. - s.showCommandError(ctx, command.Title, err) + event.Error(ctx, "command error", err) + deps.work.end("failed") @@ -97:98, +103:104 @@ - work.end(command.ID() + ": completed") + deps.work.end("completed") @@ +105:106 @@ + return err @@ -100:104, +107:110 @@ - if command.Async { - go run() - } else { - run() + if cfg.async { + go runcmd() + return nil @@ -105:108, +111:112 @@ - // Errors running the command are displayed to the user above, so don't - // return them. - return nil, nil + return runcmd() @@ -110:239, +114:120 @@ - func (s *Server) runSuggestedFixCommand(ctx context.Context, command *source.Command, args []json.RawMessage) error { - var uri protocol.DocumentURI - var rng protocol.Range - if err := source.UnmarshalArgs(args, &uri, &rng); err != nil { - return err - } - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, uri, source.Go) - defer release() - if !ok { - return err - } - edits, err := command.SuggestedFix(ctx, snapshot, fh, rng) - if err != nil { - return err - } - r, err := s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ - Edit: protocol.WorkspaceEdit{ - DocumentChanges: edits, - }, - }) - if err != nil { - return err - } - if !r.Applied { - return errors.New(r.FailureReason) - } - return nil - } - - func (s *Server) showCommandError(ctx context.Context, title string, err error) { - // Command error messages should not be cancelable. - ctx = xcontext.Detach(ctx) - if err := s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ - Type: protocol.Error, - Message: fmt.Sprintf("%s failed: %v", title, err), - }); err != nil { - event.Error(ctx, title+": failed to show message", err) - } - } - - func (s *Server) runCommand(ctx context.Context, work *workDone, command *source.Command, args []json.RawMessage) (err error) { - // If the command has a suggested fix function available, use it and apply - // the edits to the workspace. - if command.IsSuggestedFix() { - return s.runSuggestedFixCommand(ctx, command, args) - } - switch command { - case source.CommandTest: - var uri protocol.DocumentURI - var tests, benchmarks []string - if err := source.UnmarshalArgs(args, &uri, &tests, &benchmarks); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - return s.runTests(ctx, snapshot, uri, work, tests, benchmarks) - case source.CommandGenerate: - var uri protocol.DocumentURI - var recursive bool - if err := source.UnmarshalArgs(args, &uri, &recursive); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - return s.runGoGenerate(ctx, snapshot, uri.SpanURI(), recursive, work) - case source.CommandRegenerateCgo: - var uri protocol.DocumentURI - if err := source.UnmarshalArgs(args, &uri); err != nil { - return err - } - mod := source.FileModification{ - URI: uri.SpanURI(), - Action: source.InvalidateMetadata, - } - return s.didModifyFiles(ctx, []source.FileModification{mod}, FromRegenerateCgo) - case source.CommandTidy, source.CommandVendor: - for _, arg := range args { - var uri protocol.DocumentURI - if err := json.Unmarshal(arg, &uri); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - // The flow for `go mod tidy` and `go mod vendor` is almost identical, - // so we combine them into one case for convenience. - action := "tidy" - if command == source.CommandVendor { - action = "vendor" - } - if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, uri.SpanURI(), "mod", []string{action}); err != nil { - return err - } - } - case source.CommandUpdateGoSum: - for _, arg := range args { - var uri protocol.DocumentURI - if err := json.Unmarshal(arg, &uri); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, uri.SpanURI(), "list", []string{"all"}); err != nil { - return err - } - } - case source.CommandCheckUpgrades: - var uri protocol.DocumentURI - var modules []string - if err := source.UnmarshalArgs(args, &uri, &modules); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - upgrades, err := s.getUpgrades(ctx, snapshot, uri.SpanURI(), modules) + func (c *commandHandler) ApplyFix(ctx context.Context, args command.ApplyFixArgs) error { + return c.run(ctx, commandConfig{ + // Note: no progress here. Applying fixes should be quick. + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { + edits, err := source.ApplyFix(ctx, args.Fix, deps.snapshot, deps.fh, args.Range) @@ -242:245, +123:134 @@ - snapshot.View().RegisterModuleUpgrades(upgrades) - // Re-diagnose the snapshot to publish the new module diagnostics. - s.diagnoseSnapshot(snapshot, nil, false) + r, err := c.s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ + Edit: protocol.WorkspaceEdit{ + DocumentChanges: edits, + }, + }) + if err != nil { + return err + } + if !r.Applied { + return errors.New(r.FailureReason) + } @@ -246:251, +135:157 @@ - case source.CommandAddDependency, source.CommandUpgradeDependency: - var uri protocol.DocumentURI - var goCmdArgs []string - var addRequire bool - if err := source.UnmarshalArgs(args, &uri, &addRequire, &goCmdArgs); err != nil { + }) + } + + func (c *commandHandler) RegenerateCgo(ctx context.Context, args command.URIArg) error { + return c.run(ctx, commandConfig{ + progress: "Regenerating Cgo", + }, func(ctx context.Context, deps commandDeps) error { + mod := source.FileModification{ + URI: args.URI.SpanURI(), + Action: source.InvalidateMetadata, + } + return c.s.didModifyFiles(ctx, []source.FileModification{mod}, FromRegenerateCgo) + }) + } + + func (c *commandHandler) CheckUpgrades(ctx context.Context, args command.CheckUpgradesArgs) error { + return c.run(ctx, commandConfig{ + forURI: args.URI, + progress: "Checking for upgrades", + }, func(ctx context.Context, deps commandDeps) error { + upgrades, err := c.s.getUpgrades(ctx, deps.snapshot, args.URI.SpanURI(), args.Modules) + if err != nil { @@ -253:271, +159:240 @@ - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - return s.runGoGetModule(ctx, snapshot, uri.SpanURI(), addRequire, goCmdArgs) - case source.CommandRemoveDependency: - var uri protocol.DocumentURI - var modulePath string - var onlyDiagnostic bool - if err := source.UnmarshalArgs(args, &uri, &onlyDiagnostic, &modulePath); err != nil { - return err - } - snapshot, fh, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } + deps.snapshot.View().RegisterModuleUpgrades(upgrades) + // Re-diagnose the snapshot to publish the new module diagnostics. + c.s.diagnoseSnapshot(deps.snapshot, nil, false) + return nil + }) + } + + func (c *commandHandler) AddDependency(ctx context.Context, args command.DependencyArgs) error { + return c.GoGetModule(ctx, args) + } + + func (c *commandHandler) UpgradeDependency(ctx context.Context, args command.DependencyArgs) error { + return c.GoGetModule(ctx, args) + } + + func (c *commandHandler) GoGetModule(ctx context.Context, args command.DependencyArgs) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Running go get", + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { + return runGoGetModule(ctx, deps.snapshot, args.URI.SpanURI(), args.AddRequire, args.GoCmdArgs) + }) + } + + // TODO(rFindley): UpdateGoSum, Tidy, and Vendor could probably all be one command. + + func (c *commandHandler) UpdateGoSum(ctx context.Context, args command.URIArgs) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Updating go.sum", + }, func(ctx context.Context, deps commandDeps) error { + for _, uri := range args.URIs { + snapshot, fh, ok, release, err := c.s.beginFileRequest(ctx, uri, source.UnknownKind) + defer release() + if !ok { + return err + } + if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, fh.URI(), "list", []string{"all"}); err != nil { + return err + } + } + return nil + }) + } + + func (c *commandHandler) Tidy(ctx context.Context, args command.URIArgs) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Running go mod tidy", + }, func(ctx context.Context, deps commandDeps) error { + for _, uri := range args.URIs { + snapshot, fh, ok, release, err := c.s.beginFileRequest(ctx, uri, source.UnknownKind) + defer release() + if !ok { + return err + } + if err := runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, fh.URI(), "mod", []string{"tidy"}); err != nil { + return err + } + } + return nil + }) + } + + func (c *commandHandler) Vendor(ctx context.Context, args command.URIArg) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Running go mod vendor", + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { + return runSimpleGoCommand(ctx, deps.snapshot, source.UpdateUserModFile|source.AllowNetwork, args.URI.SpanURI(), "mod", []string{"vendor"}) + }) + } + + func (c *commandHandler) RemoveDependency(ctx context.Context, args command.RemoveDependencyArgs) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Removing dependency", + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { @@ -276:278, +245:247 @@ - if onlyDiagnostic { - if err := s.runGoGetModule(ctx, snapshot, uri.SpanURI(), false, []string{modulePath + "@none"}); err != nil { + if args.OnlyDiagnostic { + if err := runGoGetModule(ctx, deps.snapshot, args.URI.SpanURI(), false, []string{args.ModulePath + "@none"}); err != nil { @@ -280:281, +249:250 @@ - return runSimpleGoCommand(ctx, snapshot, source.UpdateUserModFile|source.AllowNetwork, uri.SpanURI(), "mod", []string{"tidy"}) + return runSimpleGoCommand(ctx, deps.snapshot, source.UpdateUserModFile|source.AllowNetwork, args.URI.SpanURI(), "mod", []string{"tidy"}) @@ -282:283, +251:252 @@ - pm, err := snapshot.ParseMod(ctx, fh) + pm, err := deps.snapshot.ParseMod(ctx, deps.fh) @@ -286:287, +255:256 @@ - edits, err := dropDependency(snapshot, pm, modulePath) + edits, err := dropDependency(deps.snapshot, pm, args.ModulePath) @@ -290:291, +259:260 @@ - response, err := s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ + response, err := c.s.client.ApplyEdit(ctx, &protocol.ApplyWorkspaceEditParams{ @@ -294:295, +263:264 @@ - Version: fh.Version(), + Version: deps.fh.Version(), @@ -296:297, +265:266 @@ - URI: protocol.URIFromSpanURI(fh.URI()), + URI: protocol.URIFromSpanURI(deps.fh.URI()), @@ -309:381, +278:280 @@ - case source.CommandGoGetPackage: - var uri protocol.DocumentURI - var pkg string - if err := source.UnmarshalArgs(args, &uri, &pkg); err != nil { - return err - } - snapshot, _, ok, release, err := s.beginFileRequest(ctx, uri, source.UnknownKind) - defer release() - if !ok { - return err - } - return s.runGoGetPackage(ctx, snapshot, uri.SpanURI(), pkg) - - case source.CommandToggleDetails: - var fileURI protocol.DocumentURI - if err := source.UnmarshalArgs(args, &fileURI); err != nil { - return err - } - pkgDir := span.URIFromPath(filepath.Dir(fileURI.SpanURI().Filename())) - s.gcOptimizationDetailsMu.Lock() - if _, ok := s.gcOptimizationDetails[pkgDir]; ok { - delete(s.gcOptimizationDetails, pkgDir) - s.clearDiagnosticSource(gcDetailsSource) - } else { - s.gcOptimizationDetails[pkgDir] = struct{}{} - } - s.gcOptimizationDetailsMu.Unlock() - // need to recompute diagnostics. - // so find the snapshot - snapshot, _, ok, release, err := s.beginFileRequest(ctx, fileURI, source.UnknownKind) - defer release() - if !ok { - return err - } - s.diagnoseSnapshot(snapshot, nil, false) - case source.CommandGenerateGoplsMod: - var v source.View - if len(args) == 0 { - views := s.session.Views() - if len(views) != 1 { - return fmt.Errorf("cannot resolve view: have %d views", len(views)) - } - v = views[0] - } else { - var uri protocol.DocumentURI - if err := source.UnmarshalArgs(args, &uri); err != nil { - return err - } - var err error - v, err = s.session.ViewOf(uri.SpanURI()) - if err != nil { - return err - } - } - snapshot, release := v.Snapshot(ctx) - defer release() - modFile, err := cache.BuildGoplsMod(ctx, v.Folder(), snapshot) - if err != nil { - return errors.Errorf("getting workspace mod file: %w", err) - } - content, err := modFile.Format() - if err != nil { - return errors.Errorf("formatting mod file: %w", err) - } - filename := filepath.Join(v.Folder().Filename(), "gopls.mod") - if err := ioutil.WriteFile(filename, content, 0644); err != nil { - return errors.Errorf("writing mod file: %w", err) - } - default: - return fmt.Errorf("unsupported command: %s", command.ID()) - } - return nil + return nil + }) @@ -408:409, +307:338 @@ - func (s *Server) runTests(ctx context.Context, snapshot source.Snapshot, uri protocol.DocumentURI, work *workDone, tests, benchmarks []string) error { + func (c *commandHandler) Test(ctx context.Context, uri protocol.DocumentURI, tests, benchmarks []string) error { + return c.RunTests(ctx, command.RunTestsArgs{ + URI: uri, + Tests: tests, + Benchmarks: benchmarks, + }) + } + + func (c *commandHandler) RunTests(ctx context.Context, args command.RunTestsArgs) error { + return c.run(ctx, commandConfig{ + async: true, + progress: "Running go test", + requireSave: true, + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { + if err := c.runTests(ctx, deps.snapshot, deps.work, args.URI, args.Tests, args.Benchmarks); err != nil { + if err := c.s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ + Type: protocol.Error, + Message: fmt.Sprintf("Running tests failed: %v", err), + }); err != nil { + event.Error(ctx, "running tests: failed to show message", err) + } + } + // Since we're running asynchronously, any error returned here would be + // ignored. + return nil + }) + } + + func (c *commandHandler) runTests(ctx context.Context, snapshot source.Snapshot, work *workDone, uri protocol.DocumentURI, tests, benchmarks []string) error { + // TODO: fix the error reporting when this runs async. @@ -477:478, +406:407 @@ - return s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ + return c.s.client.ShowMessage(ctx, &protocol.ShowMessageParams{ @@ -483:492, +412:416 @@ - func (s *Server) runGoGenerate(ctx context.Context, snapshot source.Snapshot, dir span.URI, recursive bool, work *workDone) error { - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - er := &eventWriter{ctx: ctx, operation: "generate"} - - pattern := "." - if recursive { - pattern = "./..." + func (c *commandHandler) Generate(ctx context.Context, args command.GenerateArgs) error { + title := "Running go generate ." + if args.Recursive { + title = "Running go generate ./..." @@ +417:423 @@ + return c.run(ctx, commandConfig{ + requireSave: true, + progress: title, + forURI: args.Dir, + }, func(ctx context.Context, deps commandDeps) error { + er := &eventWriter{ctx: ctx, operation: "generate"} @@ -494:511, +424:438 @@ - inv := &gocommand.Invocation{ - Verb: "generate", - Args: []string{"-x", pattern}, - WorkingDir: dir.Filename(), - } - stderr := io.MultiWriter(er, workDoneWriter{work}) - if err := snapshot.RunGoCommandPiped(ctx, source.Normal, inv, er, stderr); err != nil { - return err - } - return nil - } - - func (s *Server) runGoGetPackage(ctx context.Context, snapshot source.Snapshot, uri span.URI, pkg string) error { - stdout, err := snapshot.RunGoCommandDirect(ctx, source.WriteTemporaryModFile|source.AllowNetwork, &gocommand.Invocation{ - Verb: "list", - Args: []string{"-f", "{{.Module.Path}}@{{.Module.Version}}", pkg}, - WorkingDir: filepath.Dir(uri.Filename()), + pattern := "." + if args.Recursive { + pattern = "./..." + } + inv := &gocommand.Invocation{ + Verb: "generate", + Args: []string{"-x", pattern}, + WorkingDir: args.Dir.SpanURI().Filename(), + } + stderr := io.MultiWriter(er, workDoneWriter{deps.work}) + if err := deps.snapshot.RunGoCommandPiped(ctx, source.Normal, inv, er, stderr); err != nil { + return err + } + return nil @@ -512:517 @@ - if err != nil { - return err - } - ver := strings.TrimSpace(stdout.String()) - return s.runGoGetModule(ctx, snapshot, uri, true, []string{ver}) @@ -519:520, +441:461 @@ - func (s *Server) runGoGetModule(ctx context.Context, snapshot source.Snapshot, uri span.URI, addRequire bool, args []string) error { + func (c *commandHandler) GoGetPackage(ctx context.Context, args command.GoGetPackageArgs) error { + return c.run(ctx, commandConfig{ + forURI: args.URI, + progress: "Running go get", + }, func(ctx context.Context, deps commandDeps) error { + uri := args.URI.SpanURI() + stdout, err := deps.snapshot.RunGoCommandDirect(ctx, source.WriteTemporaryModFile|source.AllowNetwork, &gocommand.Invocation{ + Verb: "list", + Args: []string{"-f", "{{.Module.Path}}@{{.Module.Version}}", args.Pkg}, + WorkingDir: filepath.Dir(uri.Filename()), + }) + if err != nil { + return err + } + ver := strings.TrimSpace(stdout.String()) + return runGoGetModule(ctx, deps.snapshot, uri, args.AddRequire, []string{ver}) + }) + } + + func runGoGetModule(ctx context.Context, snapshot source.Snapshot, uri span.URI, addRequire bool, args []string) error { @@ +505:558 @@ + + func (c *commandHandler) GCDetails(ctx context.Context, uri protocol.DocumentURI) error { + return c.ToggleGCDetails(ctx, command.URIArg{URI: uri}) + } + + func (c *commandHandler) ToggleGCDetails(ctx context.Context, args command.URIArg) error { + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Toggling GC Details", + forURI: args.URI, + }, func(ctx context.Context, deps commandDeps) error { + pkgDir := span.URIFromPath(filepath.Dir(args.URI.SpanURI().Filename())) + c.s.gcOptimizationDetailsMu.Lock() + if _, ok := c.s.gcOptimizationDetails[pkgDir]; ok { + delete(c.s.gcOptimizationDetails, pkgDir) + c.s.clearDiagnosticSource(gcDetailsSource) + } else { + c.s.gcOptimizationDetails[pkgDir] = struct{}{} + } + c.s.gcOptimizationDetailsMu.Unlock() + c.s.diagnoseSnapshot(deps.snapshot, nil, false) + return nil + }) + } + + func (c *commandHandler) GenerateGoplsMod(ctx context.Context, args command.URIArg) error { + // TODO: go back to using URI + return c.run(ctx, commandConfig{ + requireSave: true, + progress: "Generating gopls.mod", + }, func(ctx context.Context, deps commandDeps) error { + views := c.s.session.Views() + if len(views) != 1 { + return fmt.Errorf("cannot resolve view: have %d views", len(views)) + } + v := views[0] + snapshot, release := v.Snapshot(ctx) + defer release() + modFile, err := cache.BuildGoplsMod(ctx, snapshot.View().Folder(), snapshot) + if err != nil { + return errors.Errorf("getting workspace mod file: %w", err) + } + content, err := modFile.Format() + if err != nil { + return errors.Errorf("formatting mod file: %w", err) + } + filename := filepath.Join(snapshot.View().Folder().Filename(), "gopls.mod") + if err := ioutil.WriteFile(filename, content, 0644); err != nil { + return errors.Errorf("writing mod file: %w", err) + } + return nil + }) + } The name of the file: internal/lsp/command/command_gen.go Insertions: 368, Deletions: 0. @@ +0:369 @@ + // Copyright 2021 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + + // Don't include this file during code generation, or it will break the build + // if existing interface methods have been modified. + // +build !generate + + package command + + // Code generated by generate.go. DO NOT EDIT. + + import ( + "context" + "fmt" + + "golang.org/x/tools/internal/lsp/protocol" + ) + + const ( + AddDependency Command = "add_dependency" + ApplyFix Command = "apply_fix" + CheckUpgrades Command = "check_upgrades" + GCDetails Command = "gc_details" + Generate Command = "generate" + GenerateGoplsMod Command = "generate_gopls_mod" + GoGetPackage Command = "go_get_package" + RegenerateCgo Command = "regenerate_cgo" + RemoveDependency Command = "remove_dependency" + RunTests Command = "run_tests" + Test Command = "test" + Tidy Command = "tidy" + ToggleGCDetails Command = "toggle_gc_details" + UpdateGoSum Command = "update_go_sum" + UpgradeDependency Command = "upgrade_dependency" + Vendor Command = "vendor" + ) + + var Commands = []Command{ + AddDependency, + ApplyFix, + CheckUpgrades, + GCDetails, + Generate, + GenerateGoplsMod, + GoGetPackage, + RegenerateCgo, + RemoveDependency, + RunTests, + Test, + Tidy, + ToggleGCDetails, + UpdateGoSum, + UpgradeDependency, + Vendor, + } + + func Dispatch(ctx context.Context, params *protocol.ExecuteCommandParams, s Interface) (interface{}, error) { + switch params.Command { + case "gopls.add_dependency": + var a0 DependencyArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.AddDependency(ctx, a0) + return nil, err + case "gopls.apply_fix": + var a0 ApplyFixArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.ApplyFix(ctx, a0) + return nil, err + case "gopls.check_upgrades": + var a0 CheckUpgradesArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.CheckUpgrades(ctx, a0) + return nil, err + case "gopls.gc_details": + var a0 protocol.DocumentURI + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.GCDetails(ctx, a0) + return nil, err + case "gopls.generate": + var a0 GenerateArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.Generate(ctx, a0) + return nil, err + case "gopls.generate_gopls_mod": + var a0 URIArg + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.GenerateGoplsMod(ctx, a0) + return nil, err + case "gopls.go_get_package": + var a0 GoGetPackageArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.GoGetPackage(ctx, a0) + return nil, err + case "gopls.regenerate_cgo": + var a0 URIArg + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.RegenerateCgo(ctx, a0) + return nil, err + case "gopls.remove_dependency": + var a0 RemoveDependencyArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.RemoveDependency(ctx, a0) + return nil, err + case "gopls.run_tests": + var a0 RunTestsArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.RunTests(ctx, a0) + return nil, err + case "gopls.test": + var a0 protocol.DocumentURI + var a1 []string + var a2 []string + if err := UnmarshalArgs(params.Arguments, &a0, &a1, &a2); err != nil { + return nil, err + } + err := s.Test(ctx, a0, a1, a2) + return nil, err + case "gopls.tidy": + var a0 URIArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.Tidy(ctx, a0) + return nil, err + case "gopls.toggle_gc_details": + var a0 URIArg + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.ToggleGCDetails(ctx, a0) + return nil, err + case "gopls.update_go_sum": + var a0 URIArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.UpdateGoSum(ctx, a0) + return nil, err + case "gopls.upgrade_dependency": + var a0 DependencyArgs + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.UpgradeDependency(ctx, a0) + return nil, err + case "gopls.vendor": + var a0 URIArg + if err := UnmarshalArgs(params.Arguments, &a0); err != nil { + return nil, err + } + err := s.Vendor(ctx, a0) + return nil, err + } + return nil, fmt.Errorf("unsupported command %q", params.Command) + } + + func NewAddDependencyCommand(title string, a0 DependencyArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.add_dependency", + Arguments: args, + }, nil + } + + func NewApplyFixCommand(title string, a0 ApplyFixArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.apply_fix", + Arguments: args, + }, nil + } + + func NewCheckUpgradesCommand(title string, a0 CheckUpgradesArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.check_upgrades", + Arguments: args, + }, nil + } + + func NewGCDetailsCommand(title string, a0 protocol.DocumentURI) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.gc_details", + Arguments: args, + }, nil + } + + func NewGenerateCommand(title string, a0 GenerateArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.generate", + Arguments: args, + }, nil + } + + func NewGenerateGoplsModCommand(title string, a0 URIArg) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.generate_gopls_mod", + Arguments: args, + }, nil + } + + func NewGoGetPackageCommand(title string, a0 GoGetPackageArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.go_get_package", + Arguments: args, + }, nil + } + + func NewRegenerateCgoCommand(title string, a0 URIArg) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.regenerate_cgo", + Arguments: args, + }, nil + } + + func NewRemoveDependencyCommand(title string, a0 RemoveDependencyArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.remove_dependency", + Arguments: args, + }, nil + } + + func NewRunTestsCommand(title string, a0 RunTestsArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.run_tests", + Arguments: args, + }, nil + } + + func NewTestCommand(title string, a0 protocol.DocumentURI, a1 []string, a2 []string) (protocol.Command, error) { + args, err := MarshalArgs(a0, a1, a2) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.test", + Arguments: args, + }, nil + } + + func NewTidyCommand(title string, a0 URIArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.tidy", + Arguments: args, + }, nil + } + + func NewToggleGCDetailsCommand(title string, a0 URIArg) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.toggle_gc_details", + Arguments: args, + }, nil + } + + func NewUpdateGoSumCommand(title string, a0 URIArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.update_go_sum", + Arguments: args, + }, nil + } + + func NewUpgradeDependencyCommand(title string, a0 DependencyArgs) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.upgrade_dependency", + Arguments: args, + }, nil + } + + func NewVendorCommand(title string, a0 URIArg) (protocol.Command, error) { + args, err := MarshalArgs(a0) + if err != nil { + return protocol.Command{}, err + } + return protocol.Command{ + Title: title, + Command: "gopls.vendor", + Arguments: args, + }, nil + } + The name of the file: internal/lsp/command/interface.go Insertions: 189, Deletions: 0. @@ +0:190 @@ + // Copyright 2021 The Go Authors. All rights reserved. + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + + // Package command defines the interface provided by gopls for the + // workspace/executeCommand LSP request. + // + // This interface is fully specified by the Interface type, provided it + // conforms to the restrictions outlined in its doc string. + // + // Bindings for server-side command dispatch and client-side serialization are + // also provided by this package, via code generation. + package command + + //go:generate go run -tags=generate generate.go + + import ( + "context" + + "golang.org/x/tools/internal/lsp/protocol" + ) + + // Interface defines the interface gopls exposes for the + // workspace/executeCommand request. + // + // This interface is used to generate marshaling/unmarshaling code, dispatch, + // and documentation, and so has some additional restrictions: + // 1. All method arguments must be JSON serializable. + // 2. Methods must return either error or (T, error), where T is a + // JSON serializable type. + // 3. The first line of the doc string is special. Everything after the colon + // is considered the command 'Title'. + // TODO(rFindley): reconsider this -- Title may be unnecessary. + type Interface interface { + // ApplyFix: Apply a fix + // + // Applies a fix to a region of source code. + ApplyFix(context.Context, ApplyFixArgs) error + // Test: Run test(s) (legacy) + // + // Runs `go test` for a specific set of test or benchmark functions. + Test(context.Context, protocol.DocumentURI, []string, []string) error + + // TODO: deprecate Test in favor of RunTests below. + + // Test: Run test(s) + // + // Runs `go test` for a specific set of test or benchmark functions. + RunTests(context.Context, RunTestsArgs) error + + // Generate: Run go generate + // + // Runs `go generate` for a given directory. + Generate(context.Context, GenerateArgs) error + + // RegenerateCgo: Regenerate cgo + // + // Regenerates cgo definitions. + RegenerateCgo(context.Context, URIArg) error + + // Tidy: Run go mod tidy + // + // Runs `go mod tidy` for a module. + Tidy(context.Context, URIArgs) error + + // Vendor: Run go mod vendor + // + // Runs `go mod vendor` for a module. + Vendor(context.Context, URIArg) error + + // UpdateGoSum: Update go.sum + // + // Updates the go.sum file for a module. + UpdateGoSum(context.Context, URIArgs) error + + // CheckUpgrades: Check for upgrades + // + // Checks for module upgrades. + CheckUpgrades(context.Context, CheckUpgradesArgs) error + + // AddDependency: Add dependency + // + // Adds a dependency to the go.mod file for a module. + AddDependency(context.Context, DependencyArgs) error + + // UpgradeDependency: Upgrade dependency + // + // Upgrades a dependency in the go.mod file for a module. + UpgradeDependency(context.Context, DependencyArgs) error + + // RemoveDependency: Remove dependency + // + // Removes a dependency from the go.mod file of a module. + RemoveDependency(context.Context, RemoveDependencyArgs) error + + // GoGetPackage: go get package + // + // Runs `go get` to fetch a package. + GoGetPackage(context.Context, GoGetPackageArgs) error + + // GCDetails: Toggle gc_details + // + // Toggle the calculation of gc annotations. + GCDetails(context.Context, protocol.DocumentURI) error + + // TODO: deprecate GCDetails in favor of ToggleGCDetails below. + + // ToggleGCDetails: Toggle gc_details + // + // Toggle the calculation of gc annotations. + ToggleGCDetails(context.Context, URIArg) error + + // GenerateGoplsMod: Generate gopls.mod + // + // (Re)generate the gopls.mod file for a workspace. + GenerateGoplsMod(context.Context, URIArg) error + } + + type RunTestsArgs struct { + // The test file containing the tests to run. + URI protocol.DocumentURI + + // Specific test names to run, e.g. TestFoo. + Tests []string + + // Specific benchmarks to run, e.g. BenchmarkFoo. + Benchmarks []string + } + + type GenerateArgs struct { + // URI for the directory to generate. + Dir protocol.DocumentURI + + // Whether to generate recursively (go generate ./...) + Recursive bool + } + + // TODO(rFindley): document the rest of these once the docgen is fleshed out. + + type ApplyFixArgs struct { + // The fix to apply. + Fix string + // The file URI for the document to fix. + URI protocol.DocumentURI + // The document range to scan for fixes. + Range protocol.Range + } + + type URIArg struct { + // The file URI. + URI protocol.DocumentURI + } + + type URIArgs struct { + // The file URI. + URIs []protocol.DocumentURI + } + + type CheckUpgradesArgs struct { + // The go.mod file URI. + URI protocol.DocumentURI + // The modules to check. + Modules []string + } + + type DependencyArgs struct { + // The go.mod file URI. + URI protocol.DocumentURI + // Additional args to pass to the go command. + GoCmdArgs []string + // Whether to add a require directive. + AddRequire bool + } + + type RemoveDependencyArgs struct { + // The go.mod file URI. + URI protocol.DocumentURI + // The module path to remove. + ModulePath string + OnlyDiagnostic bool + } + + type GoGetPackageArgs struct { + // Any document URI within the relevant module. + URI protocol.DocumentURI + // The package to go get. + Pkg string + AddRequire bool + } + The name of the file: internal/lsp/fake/editor.go Insertions: 23, Deletions: 14. @@ +17:18 @@ + "golang.org/x/tools/internal/lsp/command" @@ -18:19 @@ - "golang.org/x/tools/internal/lsp/source" @@ -756:772, +756:765 @@ - func (e *Editor) codeAction(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) error { - if e.Server == nil { - return nil - } - params := &protocol.CodeActionParams{} - params.TextDocument.URI = e.sandbox.Workdir.URI(path) - params.Context.Only = only - if diagnostics != nil { - params.Context.Diagnostics = diagnostics - } - if rng != nil { - params.Range = *rng - } - actions, err := e.Server.CodeAction(ctx, params) - if err != nil { - return errors.Errorf("textDocument/codeAction: %w", err) + // GetQuickFixes returns the available quick fix code actions. + func (e *Editor) GetQuickFixes(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic) ([]protocol.CodeAction, error) { + return e.getCodeActions(ctx, path, rng, diagnostics, protocol.QuickFix, protocol.SourceFixAll) + } + + func (e *Editor) codeAction(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) error { + actions, err := e.getCodeActions(ctx, path, rng, diagnostics, only...) + if err != nil { + return err @@ +809:825 @@ + func (e *Editor) getCodeActions(ctx context.Context, path string, rng *protocol.Range, diagnostics []protocol.Diagnostic, only ...protocol.CodeActionKind) ([]protocol.CodeAction, error) { + if e.Server == nil { + return nil, nil + } + params := &protocol.CodeActionParams{} + params.TextDocument.URI = e.sandbox.Workdir.URI(path) + params.Context.Only = only + if diagnostics != nil { + params.Context.Diagnostics = diagnostics + } + if rng != nil { + params.Range = *rng + } + return e.Server.CodeAction(ctx, params) + } + @@ +903:904 @@ + // TODO(rFindley): this shouldn't be necessary anymore. Delete it. @@ -899:900, +909:913 @@ - jsonArgs, err := source.MarshalArgs(span.URIFromPath(absDir), false) + cmd, err := command.NewGenerateCommand("", command.GenerateArgs{ + Dir: protocol.URIFromSpanURI(span.URIFromPath(absDir)), + Recursive: false, + }) @@ -904:906, +917:919 @@ - Command: source.CommandGenerate.ID(), - Arguments: jsonArgs, + Command: cmd.Command, + Arguments: cmd.Arguments, The name of the file: internal/lsp/mod/code_lens.go Insertions: 2, Deletions: 1. @@ +13:14 @@ + "golang.org/x/tools/internal/lsp/command" @@ -19:24, +20:25 @@ - func LensFuncs() map[string]source.LensFunc { - return map[string]source.LensFunc{ - source.CommandUpgradeDependency.Name: upgradeLenses, - source.CommandTidy.Name: tidyLens, - source.CommandVendor.Name: vendorLens, + func LensFuncs() map[command.Command]source.LensFunc { + return map[command.Command]source.LensFunc{ + command.UpgradeDependency: upgradeLenses, + command.Tidy: tidyLens, + command.Vendor: vendorLens, @@ -36:40 @@ - upgradeTransitiveArgs, err := source.MarshalArgs(fh.URI(), false, []string{"-u", "all"}) - if err != nil { - return nil, err - } @@ -44:45, +41:46 @@ - checkUpgradeArgs, err := source.MarshalArgs(fh.URI(), requires) + uri := protocol.URIFromSpanURI(fh.URI()) + checkUpgrade, err := command.NewCheckUpgradesCommand("Check for upgrades", command.CheckUpgradesArgs{ + URI: uri, + Modules: requires, + }) @@ -48:49, +49:62 @@ - upgradeDirectArgs, err := source.MarshalArgs(fh.URI(), false, requires) + upgradeTransitive, err := command.NewUpgradeDependencyCommand("Upgrade transitive dependencies", command.DependencyArgs{ + URI: uri, + AddRequire: false, + GoCmdArgs: []string{"-u", "all"}, + }) + if err != nil { + return nil, err + } + upgradeDirect, err := command.NewUpgradeDependencyCommand("Upgrade direct dependencies", command.DependencyArgs{ + URI: uri, + AddRequire: false, + GoCmdArgs: requires, + }) @@ -59:83, +72:75 @@ - { - Range: rng, - Command: protocol.Command{ - Title: "Check for upgrades", - Command: source.CommandCheckUpgrades.ID(), - Arguments: checkUpgradeArgs, - }, - }, - { - Range: rng, - Command: protocol.Command{ - Title: "Upgrade transitive dependencies", - Command: source.CommandUpgradeDependency.ID(), - Arguments: upgradeTransitiveArgs, - }, - }, - { - Range: rng, - Command: protocol.Command{ - Title: "Upgrade direct dependencies", - Command: source.CommandUpgradeDependency.ID(), - Arguments: upgradeDirectArgs, - }, - }, + {Range: rng, Command: checkUpgrade}, + {Range: rng, Command: upgradeTransitive}, + {Range: rng, Command: upgradeDirect}, @@ -95:96, +87:89 @@ - goModArgs, err := source.MarshalArgs(fh.URI()) + uri := protocol.URIFromSpanURI(fh.URI()) + cmd, err := command.NewTidyCommand("Run go mod tidy", command.URIArgs{URIs: []protocol.DocumentURI{uri}}) @@ -104:110, +97:99 @@ - Range: rng, - Command: protocol.Command{ - Title: source.CommandTidy.Title, - Command: source.CommandTidy.ID(), - Arguments: goModArgs, - }, + Range: rng, + Command: cmd, @@ -122:123, +111:114 @@ - goModArgs, err := source.MarshalArgs(fh.URI()) + title := "Create vendor directory" + uri := protocol.URIFromSpanURI(fh.URI()) + cmd, err := command.NewVendorCommand(title, command.URIArg{URI: uri}) @@ -128:129 @@ - title := "Create vendor directory" @@ -133:141, +123:124 @@ - return []protocol.CodeLens{{ - Range: rng, - Command: protocol.Command{ - Title: title, - Command: source.CommandVendor.ID(), - Arguments: goModArgs, - }, - }}, nil + return []protocol.CodeLens{{Range: rng, Command: cmd}}, nil The name of the file: internal/lsp/mod/diagnostics.go Insertions: 7, Deletions: 2. @@ +13:14 @@ + "golang.org/x/tools/internal/lsp/command" @@ -67:68, +68:74 @@ - args, err := source.MarshalArgs(fh.URI(), false, []string{req.Mod.Path + "@" + ver}) + title := fmt.Sprintf("Upgrade to %v", ver) + cmd, err := command.NewUpgradeDependencyCommand(title, command.DependencyArgs{ + URI: protocol.URIFromSpanURI(fh.URI()), + AddRequire: false, + GoCmdArgs: []string{req.Mod.Path + "@" + ver}, + }) @@ -72:85, +78:84 @@ - URI: fh.URI(), - Range: rng, - Severity: protocol.SeverityInformation, - Source: source.UpgradeNotification, - Message: fmt.Sprintf("%v can be upgraded", req.Mod.Path), - SuggestedFixes: []source.SuggestedFix{{ - Title: fmt.Sprintf("Upgrade to %v", ver), - Command: &protocol.Command{ - Title: fmt.Sprintf("Upgrade to %v", ver), - Command: source.CommandUpgradeDependency.ID(), - Arguments: args, - }, - }}, + URI: fh.URI(), + Range: rng, + Severity: protocol.SeverityInformation, + Source: source.UpgradeNotification, + Message: fmt.Sprintf("%v can be upgraded", req.Mod.Path), + SuggestedFixes: []source.SuggestedFix{source.SuggestedFixFromCommand(cmd)}, @@ -88:89, +87:101 @@ - tidied, err := snapshot.ModTidy(ctx, pm) + // Packages in the workspace can contribute diagnostics to go.mod files. + wspkgs, err := snapshot.WorkspacePackages(ctx) + if err != nil && !source.IsNonFatalGoModError(err) { + event.Error(ctx, "diagnosing go.mod", err) + } + if err == nil { + for _, pkg := range wspkgs { + for _, diag := range pkg.GetDiagnostics() { + if diag.URI == fh.URI() { + diagnostics = append(diagnostics, diag) + } + } + } + } @@ -90:92, +102:105 @@ - if source.IsNonFatalGoModError(err) { - return diagnostics, nil + tidied, err := snapshot.ModTidy(ctx, pm) + if err != nil && !source.IsNonFatalGoModError(err) { + event.Error(ctx, "diagnosing go.mod", err) @@ -93:95, +106:113 @@ - if err != nil { - return nil, err + if err == nil { + for _, d := range tidied.Diagnostics { + if d.URI != fh.URI() { + continue + } + diagnostics = append(diagnostics, d) + } @@ -96:97 @@ - diagnostics = append(diagnostics, tidied.Diagnostics...) The name of the file: internal/lsp/source/api_json.go Insertions: 62, Deletions: 1. @@ +578:583 @@ + Name: "\"gc_details\"", + Doc: "Toggle the calculation of gc annotations.", + Default: "false", + }, + { @@ -579:580, +584:585 @@ - Doc: "generate runs `go generate` for a given directory.\n", + Doc: "Runs `go generate` for a given directory.", @@ -584:585, +589:590 @@ - Doc: "regenerate_cgo regenerates cgo definitions.\n", + Doc: "Regenerates cgo definitions.", @@ -589:590, +594:595 @@ - Doc: "test runs `go test` for a specific test function.\n", + Doc: "Runs `go test` for a specific set of test or benchmark functions.", @@ -594:595, +599:600 @@ - Doc: "tidy runs `go mod tidy` for a module.\n", + Doc: "Runs `go mod tidy` for a module.", @@ -599:600, +604:605 @@ - Doc: "upgrade_dependency upgrades a dependency.\n", + Doc: "Upgrades a dependency in the go.mod file for a module.", @@ -604:605, +609:610 @@ - Doc: "vendor runs `go mod vendor` for a module.\n", + Doc: "Runs `go mod vendor` for a module.", @@ -607:612 @@ - { - Name: "\"gc_details\"", - Doc: "gc_details controls calculation of gc annotations.\n", - Default: "false", - }, @@ -675:678, +675:679 @@ - Command: "gopls.generate", - Title: "Run go generate", - Doc: "generate runs `go generate` for a given directory.\n", + Command: "gopls.add_dependency", + Title: "Add dependency", + Doc: "Adds a dependency to the go.mod file for a module.", + ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// Additional args to pass to the go command.\n\t\"GoCmdArgs\": []string,\n\t// Whether to add a require directive.\n\t\"AddRequire\": bool,\n}", @@ -680:713, +681:685 @@ - Command: "gopls.fill_struct", - Title: "Fill struct", - Doc: "fill_struct is a gopls command to fill a struct with default\nvalues.\n", - }, - { - Command: "gopls.regenerate_cgo", - Title: "Regenerate cgo", - Doc: "regenerate_cgo regenerates cgo definitions.\n", - }, - { - Command: "gopls.test", - Title: "Run test(s)", - Doc: "test runs `go test` for a specific test function.\n", - }, - { - Command: "gopls.tidy", - Title: "Run go mod tidy", - Doc: "tidy runs `go mod tidy` for a module.\n", - }, - { - Command: "gopls.update_go_sum", - Title: "Update go.sum", - Doc: "update_go_sum updates the go.sum file for a module.\n", - }, - { - Command: "gopls.undeclared_name", - Title: "Undeclared name", - Doc: "undeclared_name adds a variable declaration for an undeclared\nname.\n", - }, - { - Command: "gopls.go_get_package", - Title: "go get package", - Doc: "go_get_package runs `go get` to fetch a package.\n", + Command: "gopls.apply_fix", + Title: "Apply a fix", + Doc: "Applies a fix to a region of source code.", + ArgDoc: "{\n\t// The fix to apply.\n\t\"Fix\": string,\n\t// The file URI for the document to fix.\n\t\"URI\": string,\n\t// The document range to scan for fixes.\n\t\"Range\": {\n\t\t\"start\": {\n\t\t\t\"line\": uint32,\n\t\t\t\"character\": uint32,\n\t\t},\n\t\t\"end\": {\n\t\t\t\"line\": uint32,\n\t\t\t\"character\": uint32,\n\t\t},\n\t},\n}", @@ -717:748, +689:691 @@ - Doc: "check_upgrades checks for module upgrades.\n", - }, - { - Command: "gopls.add_dependency", - Title: "Add dependency", - Doc: "add_dependency adds a dependency.\n", - }, - { - Command: "gopls.upgrade_dependency", - Title: "Upgrade dependency", - Doc: "upgrade_dependency upgrades a dependency.\n", - }, - { - Command: "gopls.remove_dependency", - Title: "Remove dependency", - Doc: "remove_dependency removes a dependency.\n", - }, - { - Command: "gopls.vendor", - Title: "Run go mod vendor", - Doc: "vendor runs `go mod vendor` for a module.\n", - }, - { - Command: "gopls.extract_variable", - Title: "Extract to variable", - Doc: "extract_variable extracts an expression to a variable.\n", - }, - { - Command: "gopls.extract_function", - Title: "Extract to function", - Doc: "extract_function extracts statements to a function.\n", + Doc: "Checks for module upgrades.", + ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// The modules to check.\n\t\"Modules\": []string,\n}", @@ -752:753, +695:703 @@ - Doc: "gc_details controls calculation of gc annotations.\n", + Doc: "Toggle the calculation of gc annotations.", + ArgDoc: "string", + }, + { + Command: "gopls.generate", + Title: "Run go generate", + Doc: "Runs `go generate` for a given directory.", + ArgDoc: "{\n\t// URI for the directory to generate.\n\t\"Dir\": string,\n\t// Whether to generate recursively (go generate ./...)\n\t\"Recursive\": bool,\n}", @@ -757:758, +707:769 @@ - Doc: "generate_gopls_mod (re)generates the gopls.mod file.\n", + Doc: "(Re)generate the gopls.mod file for a workspace.", + ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}", + }, + { + Command: "gopls.go_get_package", + Title: "go get package", + Doc: "Runs `go get` to fetch a package.", + ArgDoc: "{\n\t// Any document URI within the relevant module.\n\t\"URI\": string,\n\t// The package to go get.\n\t\"Pkg\": string,\n\t\"AddRequire\": bool,\n}", + }, + { + Command: "gopls.regenerate_cgo", + Title: "Regenerate cgo", + Doc: "Regenerates cgo definitions.", + ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}", + }, + { + Command: "gopls.remove_dependency", + Title: "Remove dependency", + Doc: "Removes a dependency from the go.mod file of a module.", + ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// The module path to remove.\n\t\"ModulePath\": string,\n\t\"OnlyDiagnostic\": bool,\n}", + }, + { + Command: "gopls.run_tests", + Title: "Run test(s)", + Doc: "Runs `go test` for a specific set of test or benchmark functions.", + ArgDoc: "{\n\t// The test file containing the tests to run.\n\t\"URI\": string,\n\t// Specific test names to run, e.g. TestFoo.\n\t\"Tests\": []string,\n\t// Specific benchmarks to run, e.g. BenchmarkFoo.\n\t\"Benchmarks\": []string,\n}", + }, + { + Command: "gopls.test", + Title: "Run test(s) (legacy)", + Doc: "Runs `go test` for a specific set of test or benchmark functions.", + ArgDoc: "string,\n[]string,\n[]string", + }, + { + Command: "gopls.tidy", + Title: "Run go mod tidy", + Doc: "Runs `go mod tidy` for a module.", + ArgDoc: "{\n\t// The file URI.\n\t\"URIs\": []string,\n}", + }, + { + Command: "gopls.toggle_gc_details", + Title: "Toggle gc_details", + Doc: "Toggle the calculation of gc annotations.", + ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}", + }, + { + Command: "gopls.update_go_sum", + Title: "Update go.sum", + Doc: "Updates the go.sum file for a module.", + ArgDoc: "{\n\t// The file URI.\n\t\"URIs\": []string,\n}", + }, + { + Command: "gopls.upgrade_dependency", + Title: "Upgrade dependency", + Doc: "Upgrades a dependency in the go.mod file for a module.", + ArgDoc: "{\n\t// The go.mod file URI.\n\t\"URI\": string,\n\t// Additional args to pass to the go command.\n\t\"GoCmdArgs\": []string,\n\t// Whether to add a require directive.\n\t\"AddRequire\": bool,\n}", + }, + { + Command: "gopls.vendor", + Title: "Run go mod vendor", + Doc: "Runs `go mod vendor` for a module.", + ArgDoc: "{\n\t// The file URI.\n\t\"URI\": string,\n}", @@ +773:778 @@ + Lens: "gc_details", + Title: "Toggle gc_details", + Doc: "Toggle the calculation of gc annotations.", + }, + { @@ -764:765, +780:781 @@ - Doc: "generate runs `go generate` for a given directory.\n", + Doc: "Runs `go generate` for a given directory.", @@ -769:770, +785:786 @@ - Doc: "regenerate_cgo regenerates cgo definitions.\n", + Doc: "Regenerates cgo definitions.", @@ -773:775, +789:791 @@ - Title: "Run test(s)", - Doc: "test runs `go test` for a specific test function.\n", + Title: "Run test(s) (legacy)", + Doc: "Runs `go test` for a specific set of test or benchmark functions.", @@ -779:780, +795:796 @@ - Doc: "tidy runs `go mod tidy` for a module.\n", + Doc: "Runs `go mod tidy` for a module.", @@ -784:785, +800:801 @@ - Doc: "upgrade_dependency upgrades a dependency.\n", + Doc: "Upgrades a dependency in the go.mod file for a module.", @@ -789:795, +805:806 @@ - Doc: "vendor runs `go mod vendor` for a module.\n", - }, - { - Lens: "gc_details", - Title: "Toggle gc_details", - Doc: "gc_details controls calculation of gc annotations.\n", + Doc: "Runs `go mod vendor` for a module.",

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-MessageType: merged

                            Robert Findley (Gerrit)

                            unread,
                            Feb 9, 2021, 8:53:24 PM2/9/21
                            to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                            Attention is currently required from: Rebecca Stambler.

                            View Change

                            1 comment:

                            • File gopls/internal/regtest/workspace/workspace_test.go:

                              • Patch Set #17, Line 822:

                                env.Await(
                                ReadDiagnostics("a/go.mod", params),

                                This is going to read the diagnostics immediately. You should probably do OnceMet(..., ReadDiagnostics), to ensure that they're present.

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-CC: Robert Findley <rfin...@google.com>
                            Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Comment-Date: Wed, 10 Feb 2021 01:53:19 +0000
                            Gerrit-HasComments: Yes
                            Gerrit-Has-Labels: No
                            Gerrit-MessageType: comment

                            Robert Findley (Gerrit)

                            unread,
                            Feb 9, 2021, 9:12:04 PM2/9/21
                            to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                            Attention is currently required from: Rebecca Stambler.

                            View Change

                            3 comments:

                            • Patchset:

                              • Patch Set #17:

                                (just noticed a few things while skimming this CL -- none are a big deal)

                            • File gopls/internal/regtest/wrappers.go:

                              • Patch Set #17, Line 206: return e.Editor.GetQuickFixes(e.Ctx, path, nil, diagnostics)

                                BTW, the point of wrapping is to turn errors into test failure. In this case, you could just call e.Editor.GetQuickFixes directly.

                            • File internal/lsp/command/interface.go:

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-CC: Robert Findley <rfin...@google.com>
                            Gerrit-Attention: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Comment-Date: Wed, 10 Feb 2021 02:12:00 +0000

                            Rebecca Stambler (Gerrit)

                            unread,
                            Feb 9, 2021, 10:54:46 PM2/9/21
                            to goph...@pubsubhelper.golang.org, Robert Findley, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                            Patch set 17:Run-TryBot +1Trust +1

                            View Change

                            3 comments:

                            • Patchset:

                              • Patch Set #17:

                                (just noticed a few things while skimming this CL -- none are a big deal)

                              • Mailed CL 290829.

                            • File gopls/internal/regtest/workspace/workspace_test.go:

                              • This is going to read the diagnostics immediately. You should probably do OnceMet(... […]

                                Regtests always wait for the IWL right? So I think this should be fine.

                            • File internal/lsp/command/interface.go:

                              • Done

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-CC: Robert Findley <rfin...@google.com>
                            Gerrit-Comment-Date: Wed, 10 Feb 2021 03:54:43 +0000
                            Gerrit-HasComments: Yes
                            Gerrit-Has-Labels: Yes
                            Comment-In-Reply-To: Robert Findley <rfin...@google.com>
                            Gerrit-MessageType: comment

                            Robert Findley (Gerrit)

                            unread,
                            Feb 10, 2021, 8:50:23 AM2/10/21
                            to Rebecca Stambler, goph...@pubsubhelper.golang.org, Go Bot, kokoro, Heschi Kreinick, golang-co...@googlegroups.com

                            View Change

                            1 comment:

                            • File gopls/internal/regtest/workspace/workspace_test.go:

                              • Regtests always wait for the IWL right? So I think this should be fine.

                                Ah, yup.

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-CC: Robert Findley <rfin...@google.com>
                            Gerrit-Comment-Date: Wed, 10 Feb 2021 13:50:18 +0000
                            Gerrit-HasComments: Yes
                            Gerrit-Has-Labels: No
                            Comment-In-Reply-To: Rebecca Stambler <rsta...@golang.org>

                            Heschi Kreinick (Gerrit)

                            unread,
                            Feb 10, 2021, 8:51:34 PM2/10/21
                            to Rebecca Stambler, goph...@pubsubhelper.golang.org, Robert Findley, Go Bot, kokoro, golang-co...@googlegroups.com

                            Patch set 17:Code-Review +2

                            View Change

                            1 comment:

                            • File gopls/internal/regtest/workspace/workspace_test.go:

                              • Ah, yup.

                                But, as I just learned, the loop below will silently do nothing if no diagnostics are found, or they don't have exactly the right text.

                            To view, visit change 289772. To unsubscribe, or for help writing mail filters, visit settings.

                            Gerrit-Project: tools
                            Gerrit-Branch: master
                            Gerrit-Change-Id: Id4a6013f2aceb6b902dff3118b027f6cb99eb3c1
                            Gerrit-Change-Number: 289772
                            Gerrit-PatchSet: 17
                            Gerrit-Owner: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: Go Bot <go...@golang.org>
                            Gerrit-Reviewer: Heschi Kreinick <hes...@google.com>
                            Gerrit-Reviewer: Rebecca Stambler <rsta...@golang.org>
                            Gerrit-Reviewer: kokoro <noreply...@google.com>
                            Gerrit-CC: Robert Findley <rfin...@google.com>
                            Gerrit-Comment-Date: Thu, 11 Feb 2021 01:51:29 +0000
                            Gerrit-HasComments: Yes
                            Gerrit-Has-Labels: Yes
                            Reply all
                            Reply to author
                            Forward
                            0 new messages