mirror of
https://github.com/golang/go
synced 2024-11-18 13:24:39 -07:00
internal/lsp: check for file URIs on LSP requests
In general, we expect all URIs to be file:// scheme. Silently ignore requests that come in for other schemes. (In the command-line client we panic since we should never see anything else.) The calling convention for beginFileRequest is odd; see the function comment. Fixes golang/go#33699. Change-Id: Ie721e9a85478f3a12975f6528cfbd28cc7910be8 Reviewed-on: https://go-review.googlesource.com/c/tools/+/219483 Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
f7b8cc7bd0
commit
5916a50871
@ -293,6 +293,15 @@ func newConnection(app *Application) *connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fileURI converts a DocumentURI to a file:// span.URI, panicking if it's not a file.
|
||||||
|
func fileURI(uri protocol.DocumentURI) span.URI {
|
||||||
|
sURI := uri.SpanURI()
|
||||||
|
if !sURI.IsFile() {
|
||||||
|
panic(fmt.Sprintf("%q is not a file URI", uri))
|
||||||
|
}
|
||||||
|
return sURI
|
||||||
|
}
|
||||||
|
|
||||||
func (c *cmdClient) ShowMessage(ctx context.Context, p *protocol.ShowMessageParams) error { return nil }
|
func (c *cmdClient) ShowMessage(ctx context.Context, p *protocol.ShowMessageParams) error { return nil }
|
||||||
|
|
||||||
func (c *cmdClient) ShowMessageRequest(ctx context.Context, p *protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error) {
|
func (c *cmdClient) ShowMessageRequest(ctx context.Context, p *protocol.ShowMessageRequestParams) (*protocol.MessageActionItem, error) {
|
||||||
@ -373,7 +382,7 @@ func (c *cmdClient) PublishDiagnostics(ctx context.Context, p *protocol.PublishD
|
|||||||
c.filesMu.Lock()
|
c.filesMu.Lock()
|
||||||
defer c.filesMu.Unlock()
|
defer c.filesMu.Unlock()
|
||||||
|
|
||||||
file := c.getFile(ctx, p.URI.SpanURI())
|
file := c.getFile(ctx, fileURI(p.URI))
|
||||||
file.diagnostics = p.Diagnostics
|
file.diagnostics = p.Diagnostics
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func (d *definition) Run(ctx context.Context, args ...string) error {
|
|||||||
if hover == nil {
|
if hover == nil {
|
||||||
return errors.Errorf("%v: not an identifier", from)
|
return errors.Errorf("%v: not an identifier", from)
|
||||||
}
|
}
|
||||||
file = conn.AddFile(ctx, locs[0].URI.SpanURI())
|
file = conn.AddFile(ctx, fileURI(locs[0].URI))
|
||||||
if file.err != nil {
|
if file.err != nil {
|
||||||
return errors.Errorf("%v: %v", from, file.err)
|
return errors.Errorf("%v: %v", from, file.err)
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ func (i *implementation) Run(ctx context.Context, args ...string) error {
|
|||||||
|
|
||||||
var spans []string
|
var spans []string
|
||||||
for _, impl := range implementations {
|
for _, impl := range implementations {
|
||||||
f := conn.AddFile(ctx, impl.URI.SpanURI())
|
f := conn.AddFile(ctx, fileURI(impl.URI))
|
||||||
span, err := f.mapper.Span(impl)
|
span, err := f.mapper.Span(impl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -74,7 +74,7 @@ func (t *imports) Run(ctx context.Context, args ...string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, c := range a.Edit.DocumentChanges {
|
for _, c := range a.Edit.DocumentChanges {
|
||||||
if c.TextDocument.URI.SpanURI() == uri {
|
if fileURI(c.TextDocument.URI) == uri {
|
||||||
edits = append(edits, c.Edits...)
|
edits = append(edits, c.Edits...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ func (r *references) Run(ctx context.Context, args ...string) error {
|
|||||||
}
|
}
|
||||||
var spans []string
|
var spans []string
|
||||||
for _, l := range locations {
|
for _, l := range locations {
|
||||||
f := conn.AddFile(ctx, l.URI.SpanURI())
|
f := conn.AddFile(ctx, fileURI(l.URI))
|
||||||
// convert location to span for user-friendly 1-indexed line
|
// convert location to span for user-friendly 1-indexed line
|
||||||
// and column numbers
|
// and column numbers
|
||||||
span, err := f.mapper.Span(l)
|
span, err := f.mapper.Span(l)
|
||||||
|
@ -81,7 +81,7 @@ func (r *rename) Run(ctx context.Context, args ...string) error {
|
|||||||
var orderedURIs []string
|
var orderedURIs []string
|
||||||
edits := map[span.URI][]protocol.TextEdit{}
|
edits := map[span.URI][]protocol.TextEdit{}
|
||||||
for _, c := range edit.DocumentChanges {
|
for _, c := range edit.DocumentChanges {
|
||||||
uri := c.TextDocument.URI.SpanURI()
|
uri := fileURI(c.TextDocument.URI)
|
||||||
edits[uri] = append(edits[uri], c.Edits...)
|
edits[uri] = append(edits[uri], c.Edits...)
|
||||||
orderedURIs = append(orderedURIs, string(uri))
|
orderedURIs = append(orderedURIs, string(uri))
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ func (s *suggestedfix) Run(ctx context.Context, args ...string) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for _, c := range a.Edit.DocumentChanges {
|
for _, c := range a.Edit.DocumentChanges {
|
||||||
if c.TextDocument.URI.SpanURI() == uri {
|
if fileURI(c.TextDocument.URI) == uri {
|
||||||
edits = append(edits, c.Edits...)
|
edits = append(edits, c.Edits...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
|
func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.UnknownKind)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
uri := fh.Identity().URI
|
||||||
|
|
||||||
// Determine the supported actions for this file kind.
|
// Determine the supported actions for this file kind.
|
||||||
supportedCodeActions, ok := view.Options().SupportedCodeActions[fh.Identity().Kind]
|
supportedCodeActions, ok := snapshot.View().Options().SupportedCodeActions[fh.Identity().Kind]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("no supported code actions for %v file kind", fh.Identity().Kind)
|
return nil, fmt.Errorf("no supported code actions for %v file kind", fh.Identity().Kind)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/tools/internal/lsp/protocol"
|
"golang.org/x/tools/internal/lsp/protocol"
|
||||||
"golang.org/x/tools/internal/lsp/source"
|
"golang.org/x/tools/internal/lsp/source"
|
||||||
"golang.org/x/tools/internal/span"
|
|
||||||
errors "golang.org/x/xerrors"
|
errors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,36 +14,27 @@ func (s *Server) executeCommand(ctx context.Context, params *protocol.ExecuteCom
|
|||||||
if len(params.Arguments) == 0 || len(params.Arguments) > 1 {
|
if len(params.Arguments) == 0 || len(params.Arguments) > 1 {
|
||||||
return nil, errors.Errorf("expected one file URI for call to `go mod tidy`, got %v", params.Arguments)
|
return nil, errors.Errorf("expected one file URI for call to `go mod tidy`, got %v", params.Arguments)
|
||||||
}
|
}
|
||||||
// Confirm that this action is being taken on a go.mod file.
|
uri := protocol.DocumentURI(params.Arguments[0].(string))
|
||||||
uri := span.URIFromURI(params.Arguments[0].(string))
|
snapshot, _, ok, err := s.beginFileRequest(uri, source.Mod)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Mod {
|
|
||||||
return nil, errors.Errorf("%s is not a mod file", uri)
|
|
||||||
}
|
|
||||||
// Run go.mod tidy on the view.
|
// Run go.mod tidy on the view.
|
||||||
if _, err := source.InvokeGo(ctx, view.Folder().Filename(), snapshot.Config(ctx).Env, "mod", "tidy"); err != nil {
|
if _, err := source.InvokeGo(ctx, snapshot.View().Folder().Filename(), snapshot.Config(ctx).Env, "mod", "tidy"); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case "upgrade.dependency":
|
case "upgrade.dependency":
|
||||||
if len(params.Arguments) < 2 {
|
if len(params.Arguments) < 2 {
|
||||||
return nil, errors.Errorf("expected one file URI and one dependency for call to `go get`, got %v", params.Arguments)
|
return nil, errors.Errorf("expected one file URI and one dependency for call to `go get`, got %v", params.Arguments)
|
||||||
}
|
}
|
||||||
uri := span.URIFromURI(params.Arguments[0].(string))
|
uri := protocol.DocumentURI(params.Arguments[0].(string))
|
||||||
view, err := s.session.ViewOf(uri)
|
snapshot, _, ok, err := s.beginFileRequest(uri, source.UnknownKind)
|
||||||
if err != nil {
|
if !ok {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dep := params.Arguments[1].(string)
|
dep := params.Arguments[1].(string)
|
||||||
// Run "go get" on the dependency to upgrade it to the latest version.
|
// Run "go get" on the dependency to upgrade it to the latest version.
|
||||||
if _, err := source.InvokeGo(ctx, view.Folder().Filename(), view.Snapshot().Config(ctx).Env, "get", dep); err != nil {
|
if _, err := source.InvokeGo(ctx, snapshot.View().Folder().Filename(), snapshot.Config(ctx).Env, "get", dep); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
|
func (s *Server) completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.UnknownKind)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var candidates []source.CompletionItem
|
var candidates []source.CompletionItem
|
||||||
@ -51,7 +45,7 @@ func (s *Server) completion(ctx context.Context, params *protocol.CompletionPara
|
|||||||
|
|
||||||
// When using deep completions/fuzzy matching, report results as incomplete so
|
// When using deep completions/fuzzy matching, report results as incomplete so
|
||||||
// client fetches updated completions after every key stroke.
|
// client fetches updated completions after every key stroke.
|
||||||
options := view.Options()
|
options := snapshot.View().Options()
|
||||||
incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy
|
incompleteResults := options.DeepCompletion || options.Matcher == source.Fuzzy
|
||||||
|
|
||||||
items := toProtocolCompletionItems(candidates, rng, options)
|
items := toProtocolCompletionItems(candidates, rng, options)
|
||||||
|
@ -12,19 +12,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) definition(ctx context.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) {
|
func (s *Server) definition(ctx context.Context, params *protocol.DefinitionParams) ([]protocol.Location, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -42,19 +33,10 @@ func (s *Server) definition(ctx context.Context, params *protocol.DefinitionPara
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefinitionParams) ([]protocol.Location, error) {
|
func (s *Server) typeDefinition(ctx context.Context, params *protocol.TypeDefinitionParams) ([]protocol.Location, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -8,24 +8,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRangeParams) ([]protocol.FoldingRange, error) {
|
func (s *Server) foldingRange(ctx context.Context, params *protocol.FoldingRangeParams) ([]protocol.FoldingRange, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var ranges []*source.FoldingRangeInfo
|
|
||||||
switch fh.Identity().Kind {
|
|
||||||
case source.Go:
|
|
||||||
ranges, err = source.FoldingRange(ctx, snapshot, fh, view.Options().LineFoldingOnly)
|
|
||||||
case source.Mod:
|
|
||||||
ranges = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
|
ranges, err := source.FoldingRange(ctx, snapshot, fh, snapshot.View().Options().LineFoldingOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) {
|
func (s *Server) formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
edits, err := source.Format(ctx, snapshot, fh)
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var edits []protocol.TextEdit
|
|
||||||
switch fh.Identity().Kind {
|
|
||||||
case source.Go:
|
|
||||||
edits, err = source.Format(ctx, snapshot, fh)
|
|
||||||
case source.Mod:
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -234,6 +234,32 @@ func (s *Server) fetchConfig(ctx context.Context, name string, folder span.URI,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// beginFileRequest checks preconditions for a file-oriented request and routes
|
||||||
|
// it to a snapshot.
|
||||||
|
// We don't want to return errors for benign conditions like wrong file type,
|
||||||
|
// so callers should do if !ok { return err } rather than if err != nil.
|
||||||
|
func (s *Server) beginFileRequest(pURI protocol.DocumentURI, expectKind source.FileKind) (source.Snapshot, source.FileHandle, bool, error) {
|
||||||
|
uri := pURI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
// Not a file URI. Stop processing the request, but don't return an error.
|
||||||
|
return nil, nil, false, nil
|
||||||
|
}
|
||||||
|
view, err := s.session.ViewOf(uri)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, false, err
|
||||||
|
}
|
||||||
|
snapshot := view.Snapshot()
|
||||||
|
fh, err := snapshot.GetFile(uri)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, false, err
|
||||||
|
}
|
||||||
|
if expectKind != source.UnknownKind && fh.Identity().Kind != expectKind {
|
||||||
|
// Wrong kind of file. Nothing to do.
|
||||||
|
return nil, nil, false, nil
|
||||||
|
}
|
||||||
|
return snapshot, fh, true, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) shutdown(ctx context.Context) error {
|
func (s *Server) shutdown(ctx context.Context) error {
|
||||||
s.stateMu.Lock()
|
s.stateMu.Lock()
|
||||||
defer s.stateMu.Unlock()
|
defer s.stateMu.Unlock()
|
||||||
|
@ -14,26 +14,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) documentHighlight(ctx context.Context, params *protocol.DocumentHighlightParams) ([]protocol.DocumentHighlight, error) {
|
func (s *Server) documentHighlight(ctx context.Context, params *protocol.DocumentHighlightParams) ([]protocol.DocumentHighlight, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
rngs, err := source.Highlight(ctx, snapshot, fh, params.Position)
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Error(ctx, "no highlight", err, telemetry.URI.Of(params.TextDocument.URI))
|
||||||
}
|
|
||||||
var rngs []protocol.Range
|
|
||||||
switch fh.Identity().Kind {
|
|
||||||
case source.Go:
|
|
||||||
rngs, err = source.Highlight(ctx, snapshot, fh, params.Position)
|
|
||||||
case source.Mod:
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error(ctx, "no highlight", err, telemetry.URI.Of(uri))
|
|
||||||
}
|
}
|
||||||
return toProtocolHighlight(rngs), nil
|
return toProtocolHighlight(rngs), nil
|
||||||
}
|
}
|
||||||
|
@ -12,19 +12,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
|
func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*protocol.Hover, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
ident, err := source.Identifier(ctx, snapshot, fh, params.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -37,13 +28,13 @@ func (s *Server) hover(ctx context.Context, params *protocol.HoverParams) (*prot
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
hover, err := source.FormatHover(h, view.Options())
|
hover, err := source.FormatHover(h, snapshot.View().Options())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &protocol.Hover{
|
return &protocol.Hover{
|
||||||
Contents: protocol.MarkupContent{
|
Contents: protocol.MarkupContent{
|
||||||
Kind: view.Options().PreferredContentFormat,
|
Kind: snapshot.View().Options().PreferredContentFormat,
|
||||||
Value: hover,
|
Value: hover,
|
||||||
},
|
},
|
||||||
Range: rng,
|
Range: rng,
|
||||||
|
@ -12,18 +12,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) implementation(ctx context.Context, params *protocol.ImplementationParams) ([]protocol.Location, error) {
|
func (s *Server) implementation(ctx context.Context, params *protocol.ImplementationParams) ([]protocol.Location, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
return source.Implementation(ctx, snapshot, fh, params.Position)
|
return source.Implementation(ctx, snapshot, fh, params.Position)
|
||||||
}
|
}
|
||||||
|
@ -21,19 +21,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLinkParams) ([]protocol.DocumentLink, error) {
|
func (s *Server) documentLink(ctx context.Context, params *protocol.DocumentLinkParams) ([]protocol.DocumentLink, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
|
||||||
view, err := s.session.ViewOf(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fh, err := view.Snapshot().GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// TODO(golang/go#36501): Support document links for go.mod files.
|
// TODO(golang/go#36501): Support document links for go.mod files.
|
||||||
if fh.Identity().Kind == source.Mod {
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
return nil, nil
|
if !ok {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
view := snapshot.View()
|
||||||
file, _, m, _, err := view.Session().Cache().ParseGoHandle(fh, source.ParseFull).Parse(ctx)
|
file, _, m, _, err := view.Session().Cache().ParseGoHandle(fh, source.ParseFull).Parse(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -12,22 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) references(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) {
|
func (s *Server) references(ctx context.Context, params *protocol.ReferenceParams) ([]protocol.Location, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
references, err := source.References(ctx, snapshot, fh, params.Position, params.Context.IncludeDeclaration)
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Find all references to the identifier at the position.
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
references, err := source.References(ctx, view.Snapshot(), fh, params.Position, params.Context.IncludeDeclaration)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -12,20 +12,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, error) {
|
func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*protocol.WorkspaceEdit, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
edits, err := source.Rename(ctx, snapshot, fh, params.Position, params.NewName)
|
edits, err := source.Rename(ctx, snapshot, fh, params.Position, params.NewName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -45,20 +35,10 @@ func (s *Server) rename(ctx context.Context, params *protocol.RenameParams) (*pr
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) prepareRename(ctx context.Context, params *protocol.PrepareRenameParams) (*protocol.Range, error) {
|
func (s *Server) prepareRename(ctx context.Context, params *protocol.PrepareRenameParams) (*protocol.Range, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do not return errors here, as it adds clutter.
|
// Do not return errors here, as it adds clutter.
|
||||||
// Returning a nil result means there is not a valid rename.
|
// Returning a nil result means there is not a valid rename.
|
||||||
item, err := source.PrepareRename(ctx, snapshot, fh, params.Position)
|
item, err := source.PrepareRename(ctx, snapshot, fh, params.Position)
|
||||||
|
@ -95,17 +95,17 @@ func (s *Server) nonstandardRequest(ctx context.Context, method string, params i
|
|||||||
paramMap := params.(map[string]interface{})
|
paramMap := params.(map[string]interface{})
|
||||||
if method == "gopls/diagnoseFiles" {
|
if method == "gopls/diagnoseFiles" {
|
||||||
for _, file := range paramMap["files"].([]interface{}) {
|
for _, file := range paramMap["files"].([]interface{}) {
|
||||||
uri := span.URIFromURI(file.(string))
|
snapshot, fh, ok, err := s.beginFileRequest(protocol.DocumentURI(file.(string)), source.UnknownKind)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
fileID, diagnostics, err := source.FileDiagnostics(ctx, view.Snapshot(), uri)
|
|
||||||
|
fileID, diagnostics, err := source.FileDiagnostics(ctx, snapshot, fh.Identity().URI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{
|
if err := s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{
|
||||||
URI: protocol.URIFromSpanURI(uri),
|
URI: protocol.URIFromSpanURI(fh.Identity().URI),
|
||||||
Diagnostics: toProtocolDiagnostics(diagnostics),
|
Diagnostics: toProtocolDiagnostics(diagnostics),
|
||||||
Version: fileID.Version,
|
Version: fileID.Version,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
|
@ -14,19 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) signatureHelp(ctx context.Context, params *protocol.SignatureHelpParams) (*protocol.SignatureHelp, error) {
|
func (s *Server) signatureHelp(ctx context.Context, params *protocol.SignatureHelpParams) (*protocol.SignatureHelp, error) {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if fh.Identity().Kind != source.Go {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
info, activeParameter, err := source.SignatureHelp(ctx, snapshot, fh, params.Position)
|
info, activeParameter, err := source.SignatureHelp(ctx, snapshot, fh, params.Position)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Print(ctx, "no signature help", tag.Of("At", params.Position), tag.Of("Failure", err))
|
log.Print(ctx, "no signature help", tag.Of("At", params.Position), tag.Of("Failure", err))
|
||||||
|
@ -18,26 +18,13 @@ func (s *Server) documentSymbol(ctx context.Context, params *protocol.DocumentSy
|
|||||||
ctx, done := trace.StartSpan(ctx, "lsp.Server.documentSymbol")
|
ctx, done := trace.StartSpan(ctx, "lsp.Server.documentSymbol")
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
snapshot, fh, ok, err := s.beginFileRequest(params.TextDocument.URI, source.Go)
|
||||||
view, err := s.session.ViewOf(uri)
|
if !ok {
|
||||||
if err != nil {
|
return []protocol.DocumentSymbol{}, err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
snapshot := view.Snapshot()
|
symbols, err := source.DocumentSymbols(ctx, snapshot, fh)
|
||||||
fh, err := snapshot.GetFile(uri)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
log.Error(ctx, "DocumentSymbols failed", err, telemetry.URI.Of(fh.Identity().URI))
|
||||||
}
|
|
||||||
var symbols []protocol.DocumentSymbol
|
|
||||||
switch fh.Identity().Kind {
|
|
||||||
case source.Go:
|
|
||||||
symbols, err = source.DocumentSymbols(ctx, snapshot, fh)
|
|
||||||
case source.Mod:
|
|
||||||
return []protocol.DocumentSymbol{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Error(ctx, "DocumentSymbols failed", err, telemetry.URI.Of(uri))
|
|
||||||
return []protocol.DocumentSymbol{}, nil
|
return []protocol.DocumentSymbol{}, nil
|
||||||
}
|
}
|
||||||
return symbols, nil
|
return symbols, nil
|
||||||
|
@ -17,9 +17,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
|
func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
|
||||||
|
uri := params.TextDocument.URI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
_, err := s.didModifyFiles(ctx, []source.FileModification{
|
_, err := s.didModifyFiles(ctx, []source.FileModification{
|
||||||
{
|
{
|
||||||
URI: params.TextDocument.URI.SpanURI(),
|
URI: uri,
|
||||||
Action: source.Open,
|
Action: source.Open,
|
||||||
Version: params.TextDocument.Version,
|
Version: params.TextDocument.Version,
|
||||||
Text: []byte(params.TextDocument.Text),
|
Text: []byte(params.TextDocument.Text),
|
||||||
@ -31,6 +36,10 @@ func (s *Server) didOpen(ctx context.Context, params *protocol.DidOpenTextDocume
|
|||||||
|
|
||||||
func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error {
|
func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error {
|
||||||
uri := params.TextDocument.URI.SpanURI()
|
uri := params.TextDocument.URI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
text, err := s.changedText(ctx, uri, params.ContentChanges)
|
text, err := s.changedText(ctx, uri, params.ContentChanges)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -65,8 +74,12 @@ func (s *Server) didChange(ctx context.Context, params *protocol.DidChangeTextDo
|
|||||||
func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error {
|
func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.DidChangeWatchedFilesParams) error {
|
||||||
var modifications []source.FileModification
|
var modifications []source.FileModification
|
||||||
for _, change := range params.Changes {
|
for _, change := range params.Changes {
|
||||||
|
uri := change.URI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
modifications = append(modifications, source.FileModification{
|
modifications = append(modifications, source.FileModification{
|
||||||
URI: change.URI.SpanURI(),
|
URI: uri,
|
||||||
Action: changeTypeToFileAction(change.Type),
|
Action: changeTypeToFileAction(change.Type),
|
||||||
OnDisk: true,
|
OnDisk: true,
|
||||||
})
|
})
|
||||||
@ -76,8 +89,13 @@ func (s *Server) didChangeWatchedFiles(ctx context.Context, params *protocol.Did
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error {
|
func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocumentParams) error {
|
||||||
|
uri := params.TextDocument.URI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
c := source.FileModification{
|
c := source.FileModification{
|
||||||
URI: params.TextDocument.URI.SpanURI(),
|
URI: uri,
|
||||||
Action: source.Save,
|
Action: source.Save,
|
||||||
Version: params.TextDocument.Version,
|
Version: params.TextDocument.Version,
|
||||||
}
|
}
|
||||||
@ -89,9 +107,14 @@ func (s *Server) didSave(ctx context.Context, params *protocol.DidSaveTextDocume
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error {
|
func (s *Server) didClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error {
|
||||||
|
uri := params.TextDocument.URI.SpanURI()
|
||||||
|
if !uri.IsFile() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
_, err := s.didModifyFiles(ctx, []source.FileModification{
|
_, err := s.didModifyFiles(ctx, []source.FileModification{
|
||||||
{
|
{
|
||||||
URI: params.TextDocument.URI.SpanURI(),
|
URI: uri,
|
||||||
Action: source.Close,
|
Action: source.Close,
|
||||||
Version: -1,
|
Version: -1,
|
||||||
Text: nil,
|
Text: nil,
|
||||||
|
@ -20,6 +20,10 @@ const fileScheme = "file"
|
|||||||
// URI represents the full URI for a file.
|
// URI represents the full URI for a file.
|
||||||
type URI string
|
type URI string
|
||||||
|
|
||||||
|
func (uri URI) IsFile() bool {
|
||||||
|
return strings.HasPrefix(string(uri), "file://")
|
||||||
|
}
|
||||||
|
|
||||||
// Filename returns the file path for the given URI.
|
// Filename returns the file path for the given URI.
|
||||||
// It is an error to call this on a URI that is not a valid filename.
|
// It is an error to call this on a URI that is not a valid filename.
|
||||||
func (uri URI) Filename() string {
|
func (uri URI) Filename() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user