1
0
mirror of https://github.com/golang/go synced 2024-11-18 20:14:43 -07:00
go/internal/lsp/cmd/imports.go
Peter Weinberger 11e13f1c3f internal/lsp: fix the return type of CodeAction()
Paul Jolly observes that returning interface{} is not helpful.
Now CodeAction() returns []CodeAction.

The type in typescript is (Command | CodeAction)[] | null
but the choice is up to gopls, which returns []CodeAction.

Fixes golang/go#35688, golang/go#35679

Change-Id: I91c22bb0752431954ae2f993cb7b44726cf60e5c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/207898
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
2019-11-19 17:57:05 +00:00

102 lines
2.6 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2019 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 cmd
import (
"context"
"flag"
"fmt"
"io/ioutil"
"golang.org/x/tools/internal/lsp/diff"
"golang.org/x/tools/internal/lsp/protocol"
"golang.org/x/tools/internal/lsp/source"
"golang.org/x/tools/internal/span"
"golang.org/x/tools/internal/tool"
errors "golang.org/x/xerrors"
)
// imports implements the import verb for gopls.
type imports struct {
Diff bool `flag:"d" help:"display diffs instead of rewriting files"`
Write bool `flag:"w" help:"write result to (source) file instead of stdout"`
app *Application
}
func (t *imports) Name() string { return "imports" }
func (t *imports) Usage() string { return "<filename>" }
func (t *imports) ShortHelp() string { return "updates import statements" }
func (t *imports) DetailedHelp(f *flag.FlagSet) {
fmt.Fprintf(f.Output(), `
Example: update imports statements in a file:
  $ gopls imports -w internal/lsp/cmd/check.go
gopls imports flags are:
`)
f.PrintDefaults()
}
// Run performs diagnostic checks on the file specified and either;
// - if -w is specified, updates the file in place;
// - if -d is specified, prints out unified diffs of the changes; or
// - otherwise, prints the new versions to stdout.
func (t *imports) Run(ctx context.Context, args ...string) error {
if len(args) != 1 {
return tool.CommandLineErrorf("imports expects 1 argument")
}
conn, err := t.app.connect(ctx)
if err != nil {
return err
}
defer conn.terminate(ctx)
from := span.Parse(args[0])
uri := from.URI()
file := conn.AddFile(ctx, uri)
if file.err != nil {
return file.err
}
actions, err := conn.CodeAction(ctx, &protocol.CodeActionParams{
TextDocument: protocol.TextDocumentIdentifier{
URI: protocol.NewURI(uri),
},
})
if err != nil {
return errors.Errorf("%v: %v", from, err)
}
var edits []protocol.TextEdit
for _, a := range actions {
if a.Title != "Organize Imports" {
continue
}
for _, c := range a.Edit.DocumentChanges {
if c.TextDocument.URI == string(uri) {
edits = append(edits, c.Edits...)
}
}
}
sedits, err := source.FromProtocolEdits(file.mapper, edits)
if err != nil {
return errors.Errorf("%v: %v", edits, err)
}
newContent := diff.ApplyEdits(string(file.mapper.Content), sedits)
filename := file.uri.Filename()
switch {
case t.Write:
if len(edits) > 0 {
ioutil.WriteFile(filename, []byte(newContent), 0644)
}
case t.Diff:
diffs := diff.ToUnified(filename+".orig", filename, string(file.mapper.Content), sedits)
fmt.Print(diffs)
default:
fmt.Print(string(newContent))
}
return nil
}