Bumping k8s dependencies to 1.13
This commit is contained in:
53
vendor/golang.org/x/tools/internal/lsp/completion.go
generated
vendored
Normal file
53
vendor/golang.org/x/tools/internal/lsp/completion.go
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
func toProtocolCompletionItems(items []source.CompletionItem) []protocol.CompletionItem {
|
||||
var results []protocol.CompletionItem
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return items[i].Score > items[j].Score
|
||||
})
|
||||
for _, item := range items {
|
||||
results = append(results, protocol.CompletionItem{
|
||||
Label: item.Label,
|
||||
Detail: item.Detail,
|
||||
Kind: float64(toProtocolCompletionItemKind(item.Kind)),
|
||||
})
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func toProtocolCompletionItemKind(kind source.CompletionItemKind) protocol.CompletionItemKind {
|
||||
switch kind {
|
||||
case source.InterfaceCompletionItem:
|
||||
return protocol.InterfaceCompletion
|
||||
case source.StructCompletionItem:
|
||||
return protocol.StructCompletion
|
||||
case source.TypeCompletionItem:
|
||||
return protocol.TypeParameterCompletion // ??
|
||||
case source.ConstantCompletionItem:
|
||||
return protocol.ConstantCompletion
|
||||
case source.FieldCompletionItem:
|
||||
return protocol.FieldCompletion
|
||||
case source.ParameterCompletionItem, source.VariableCompletionItem:
|
||||
return protocol.VariableCompletion
|
||||
case source.FunctionCompletionItem:
|
||||
return protocol.FunctionCompletion
|
||||
case source.MethodCompletionItem:
|
||||
return protocol.MethodCompletion
|
||||
case source.PackageCompletionItem:
|
||||
return protocol.ModuleCompletion // ??
|
||||
default:
|
||||
return protocol.TextCompletion
|
||||
}
|
||||
|
||||
}
|
38
vendor/golang.org/x/tools/internal/lsp/diagnostics.go
generated
vendored
Normal file
38
vendor/golang.org/x/tools/internal/lsp/diagnostics.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
func toProtocolDiagnostics(v *source.View, diagnostics []source.Diagnostic) []protocol.Diagnostic {
|
||||
reports := []protocol.Diagnostic{}
|
||||
for _, diag := range diagnostics {
|
||||
tok := v.Config.Fset.File(diag.Range.Start)
|
||||
reports = append(reports, protocol.Diagnostic{
|
||||
Message: diag.Message,
|
||||
Range: toProtocolRange(tok, diag.Range),
|
||||
Severity: toProtocolSeverity(diag.Severity),
|
||||
Source: "LSP",
|
||||
})
|
||||
}
|
||||
return reports
|
||||
}
|
||||
|
||||
func toProtocolSeverity(severity source.DiagnosticSeverity) protocol.DiagnosticSeverity {
|
||||
switch severity {
|
||||
case source.SeverityError:
|
||||
return protocol.SeverityError
|
||||
case source.SeverityWarning:
|
||||
return protocol.SeverityWarning
|
||||
case source.SeverityHint:
|
||||
return protocol.SeverityHint
|
||||
case source.SeverityInformation:
|
||||
return protocol.SeverityInformation
|
||||
}
|
||||
return protocol.SeverityError // default
|
||||
}
|
244
vendor/golang.org/x/tools/internal/lsp/lsp_test.go
generated
vendored
Normal file
244
vendor/golang.org/x/tools/internal/lsp/lsp_test.go
generated
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"go/token"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
"golang.org/x/tools/go/packages/packagestest"
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
func TestLSP(t *testing.T) {
|
||||
packagestest.TestAll(t, testLSP)
|
||||
}
|
||||
|
||||
func testLSP(t *testing.T, exporter packagestest.Exporter) {
|
||||
const dir = "testdata"
|
||||
|
||||
files := packagestest.MustCopyFileTree(dir)
|
||||
for fragment, operation := range files {
|
||||
if trimmed := strings.TrimSuffix(fragment, ".in"); trimmed != fragment {
|
||||
delete(files, fragment)
|
||||
files[trimmed] = operation
|
||||
}
|
||||
}
|
||||
modules := []packagestest.Module{
|
||||
{
|
||||
Name: "golang.org/x/tools/internal/lsp",
|
||||
Files: files,
|
||||
},
|
||||
}
|
||||
exported := packagestest.Export(t, exporter, modules)
|
||||
defer exported.Cleanup()
|
||||
|
||||
dirs := make(map[string]bool)
|
||||
|
||||
// collect results for certain tests
|
||||
expectedDiagnostics := make(map[string][]protocol.Diagnostic)
|
||||
expectedCompletions := make(map[token.Position]*protocol.CompletionItem)
|
||||
expectedFormat := make(map[string]string)
|
||||
|
||||
s := &server{
|
||||
view: source.NewView(),
|
||||
}
|
||||
// merge the config objects
|
||||
cfg := *exported.Config
|
||||
cfg.Fset = s.view.Config.Fset
|
||||
cfg.Mode = packages.LoadSyntax
|
||||
s.view.Config = &cfg
|
||||
|
||||
for _, module := range modules {
|
||||
for fragment := range module.Files {
|
||||
if !strings.HasSuffix(fragment, ".go") {
|
||||
continue
|
||||
}
|
||||
filename := exporter.Filename(exported, module.Name, fragment)
|
||||
expectedDiagnostics[filename] = []protocol.Diagnostic{}
|
||||
dirs[filepath.Dir(filename)] = true
|
||||
}
|
||||
}
|
||||
// Do a first pass to collect special markers
|
||||
if err := exported.Expect(map[string]interface{}{
|
||||
"item": func(name string, r packagestest.Range, _, _ string) {
|
||||
exported.Mark(name, r)
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Collect any data that needs to be used by subsequent tests.
|
||||
if err := exported.Expect(map[string]interface{}{
|
||||
"diag": func(pos token.Position, msg string) {
|
||||
collectDiagnostics(t, expectedDiagnostics, pos, msg)
|
||||
},
|
||||
"item": func(pos token.Position, label, detail, kind string) {
|
||||
collectCompletionItems(expectedCompletions, pos, label, detail, kind)
|
||||
},
|
||||
"format": func(pos token.Position) {
|
||||
collectFormat(expectedFormat, pos)
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// test completion
|
||||
testCompletion(t, exported, s, expectedCompletions)
|
||||
|
||||
// test diagnostics
|
||||
var dirList []string
|
||||
for dir := range dirs {
|
||||
dirList = append(dirList, dir)
|
||||
}
|
||||
exported.Config.Mode = packages.LoadFiles
|
||||
pkgs, err := packages.Load(exported.Config, dirList...)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testDiagnostics(t, s.view, pkgs, expectedDiagnostics)
|
||||
|
||||
// test format
|
||||
testFormat(t, s, expectedFormat)
|
||||
}
|
||||
|
||||
func testCompletion(t *testing.T, exported *packagestest.Exported, s *server, wants map[token.Position]*protocol.CompletionItem) {
|
||||
if err := exported.Expect(map[string]interface{}{
|
||||
"complete": func(src token.Position, expected []token.Position) {
|
||||
var want []protocol.CompletionItem
|
||||
for _, pos := range expected {
|
||||
want = append(want, *wants[pos])
|
||||
}
|
||||
list, err := s.Completion(context.Background(), &protocol.CompletionParams{
|
||||
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
|
||||
TextDocument: protocol.TextDocumentIdentifier{
|
||||
URI: protocol.DocumentURI(source.ToURI(src.Filename)),
|
||||
},
|
||||
Position: protocol.Position{
|
||||
Line: float64(src.Line - 1),
|
||||
Character: float64(src.Column - 1),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := list.Items
|
||||
if equal := reflect.DeepEqual(want, got); !equal {
|
||||
t.Errorf("completion failed for %s:%v:%v: (expected: %v), (got: %v)", filepath.Base(src.Filename), src.Line, src.Column, want, got)
|
||||
}
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func collectCompletionItems(expectedCompletions map[token.Position]*protocol.CompletionItem, pos token.Position, label, detail, kind string) {
|
||||
var k protocol.CompletionItemKind
|
||||
switch kind {
|
||||
case "struct":
|
||||
k = protocol.StructCompletion
|
||||
case "func":
|
||||
k = protocol.FunctionCompletion
|
||||
case "var":
|
||||
k = protocol.VariableCompletion
|
||||
case "type":
|
||||
k = protocol.TypeParameterCompletion
|
||||
case "field":
|
||||
k = protocol.FieldCompletion
|
||||
case "interface":
|
||||
k = protocol.InterfaceCompletion
|
||||
case "const":
|
||||
k = protocol.ConstantCompletion
|
||||
case "method":
|
||||
k = protocol.MethodCompletion
|
||||
}
|
||||
expectedCompletions[pos] = &protocol.CompletionItem{
|
||||
Label: label,
|
||||
Detail: detail,
|
||||
Kind: float64(k),
|
||||
}
|
||||
}
|
||||
|
||||
func testDiagnostics(t *testing.T, v *source.View, pkgs []*packages.Package, wants map[string][]protocol.Diagnostic) {
|
||||
for _, pkg := range pkgs {
|
||||
for _, filename := range pkg.GoFiles {
|
||||
f := v.GetFile(source.ToURI(filename))
|
||||
diagnostics, err := source.Diagnostics(context.Background(), v, f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
got := toProtocolDiagnostics(v, diagnostics[filename])
|
||||
sort.Slice(got, func(i int, j int) bool {
|
||||
return got[i].Range.Start.Line < got[j].Range.Start.Line
|
||||
})
|
||||
want := wants[filename]
|
||||
if equal := reflect.DeepEqual(want, got); !equal {
|
||||
t.Errorf("diagnostics failed for %s: (expected: %v), (got: %v)", filepath.Base(filename), want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func collectDiagnostics(t *testing.T, expectedDiagnostics map[string][]protocol.Diagnostic, pos token.Position, msg string) {
|
||||
line := float64(pos.Line - 1)
|
||||
col := float64(pos.Column - 1)
|
||||
want := protocol.Diagnostic{
|
||||
Range: protocol.Range{
|
||||
Start: protocol.Position{
|
||||
Line: line,
|
||||
Character: col,
|
||||
},
|
||||
End: protocol.Position{
|
||||
Line: line,
|
||||
Character: col,
|
||||
},
|
||||
},
|
||||
Severity: protocol.SeverityError,
|
||||
Source: "LSP",
|
||||
Message: msg,
|
||||
}
|
||||
if _, ok := expectedDiagnostics[pos.Filename]; ok {
|
||||
expectedDiagnostics[pos.Filename] = append(expectedDiagnostics[pos.Filename], want)
|
||||
} else {
|
||||
t.Errorf("unexpected filename: %v", pos.Filename)
|
||||
}
|
||||
}
|
||||
|
||||
func testFormat(t *testing.T, s *server, expectedFormat map[string]string) {
|
||||
for filename, gofmted := range expectedFormat {
|
||||
edits, err := s.Formatting(context.Background(), &protocol.DocumentFormattingParams{
|
||||
TextDocument: protocol.TextDocumentIdentifier{
|
||||
URI: protocol.DocumentURI(source.ToURI(filename)),
|
||||
},
|
||||
})
|
||||
if err != nil || len(edits) == 0 {
|
||||
if gofmted != "" {
|
||||
t.Error(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
edit := edits[0]
|
||||
if edit.NewText != gofmted {
|
||||
t.Errorf("formatting failed: (got: %s), (expected: %s)", edit.NewText, gofmted)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func collectFormat(expectedFormat map[string]string, pos token.Position) {
|
||||
cmd := exec.Command("gofmt", pos.Filename)
|
||||
stdout := bytes.NewBuffer(nil)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Run() // ignore error, sometimes we have intentionally ungofmt-able files
|
||||
expectedFormat[pos.Filename] = stdout.String()
|
||||
}
|
114
vendor/golang.org/x/tools/internal/lsp/position.go
generated
vendored
Normal file
114
vendor/golang.org/x/tools/internal/lsp/position.go
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"go/token"
|
||||
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
// fromProtocolLocation converts from a protocol location to a source range.
|
||||
// It will return an error if the file of the location was not valid.
|
||||
// It uses fromProtocolRange to convert the start and end positions.
|
||||
func fromProtocolLocation(v *source.View, loc protocol.Location) (source.Range, error) {
|
||||
f := v.GetFile(source.URI(loc.URI))
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return source.Range{}, err
|
||||
}
|
||||
return fromProtocolRange(tok, loc.Range), nil
|
||||
}
|
||||
|
||||
// toProtocolLocation converts from a source range back to a protocol location.
|
||||
func toProtocolLocation(v *source.View, r source.Range) protocol.Location {
|
||||
tokFile := v.Config.Fset.File(r.Start)
|
||||
file := v.GetFile(source.ToURI(tokFile.Name()))
|
||||
return protocol.Location{
|
||||
URI: protocol.DocumentURI(file.URI),
|
||||
Range: toProtocolRange(tokFile, r),
|
||||
}
|
||||
}
|
||||
|
||||
// fromProtocolRange converts a protocol range to a source range.
|
||||
// It uses fromProtocolPosition to convert the start and end positions, which
|
||||
// requires the token file the positions belongs to.
|
||||
func fromProtocolRange(f *token.File, r protocol.Range) source.Range {
|
||||
start := fromProtocolPosition(f, r.Start)
|
||||
var end token.Pos
|
||||
switch {
|
||||
case r.End == r.Start:
|
||||
end = start
|
||||
case r.End.Line < 0:
|
||||
end = token.NoPos
|
||||
default:
|
||||
end = fromProtocolPosition(f, r.End)
|
||||
}
|
||||
return source.Range{
|
||||
Start: start,
|
||||
End: end,
|
||||
}
|
||||
}
|
||||
|
||||
// toProtocolRange converts from a source range back to a protocol range.
|
||||
func toProtocolRange(f *token.File, r source.Range) protocol.Range {
|
||||
return protocol.Range{
|
||||
Start: toProtocolPosition(f, r.Start),
|
||||
End: toProtocolPosition(f, r.End),
|
||||
}
|
||||
}
|
||||
|
||||
// fromProtocolPosition converts a protocol position (0-based line and column
|
||||
// number) to a token.Pos (byte offset value).
|
||||
// It requires the token file the pos belongs to in order to do this.
|
||||
func fromProtocolPosition(f *token.File, pos protocol.Position) token.Pos {
|
||||
line := lineStart(f, int(pos.Line)+1)
|
||||
return line + token.Pos(pos.Character) // TODO: this is wrong, bytes not characters
|
||||
}
|
||||
|
||||
// toProtocolPosition converts from a token pos (byte offset) to a protocol
|
||||
// position (0-based line and column number)
|
||||
// It requires the token file the pos belongs to in order to do this.
|
||||
func toProtocolPosition(f *token.File, pos token.Pos) protocol.Position {
|
||||
if !pos.IsValid() {
|
||||
return protocol.Position{Line: -1.0, Character: -1.0}
|
||||
}
|
||||
p := f.Position(pos)
|
||||
return protocol.Position{
|
||||
Line: float64(p.Line - 1),
|
||||
Character: float64(p.Column - 1),
|
||||
}
|
||||
}
|
||||
|
||||
// this functionality was borrowed from the analysisutil package
|
||||
func lineStart(f *token.File, line int) token.Pos {
|
||||
// Use binary search to find the start offset of this line.
|
||||
//
|
||||
// TODO(adonovan): eventually replace this function with the
|
||||
// simpler and more efficient (*go/token.File).LineStart, added
|
||||
// in go1.12.
|
||||
|
||||
min := 0 // inclusive
|
||||
max := f.Size() // exclusive
|
||||
for {
|
||||
offset := (min + max) / 2
|
||||
pos := f.Pos(offset)
|
||||
posn := f.Position(pos)
|
||||
if posn.Line == line {
|
||||
return pos - (token.Pos(posn.Column) - 1)
|
||||
}
|
||||
|
||||
if min+1 >= max {
|
||||
return token.NoPos
|
||||
}
|
||||
|
||||
if posn.Line < line {
|
||||
min = offset
|
||||
} else {
|
||||
max = offset
|
||||
}
|
||||
}
|
||||
}
|
362
vendor/golang.org/x/tools/internal/lsp/protocol/basic.go
generated
vendored
Normal file
362
vendor/golang.org/x/tools/internal/lsp/protocol/basic.go
generated
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Basic JSON Structures" part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
const (
|
||||
// CodeRequestCancelled is the error code that is returned when a request is
|
||||
// cancelled early.
|
||||
CodeRequestCancelled = -32800
|
||||
)
|
||||
|
||||
// DocumentURI represents the URI of a document.
|
||||
// Many of the interfaces contain fields that correspond to the URI of a document.
|
||||
// For clarity, the type of such a field is declared as a DocumentURI.
|
||||
// Over the wire, it will still be transferred as a string, but this guarantees
|
||||
// that the contents of that string can be parsed as a valid URI.
|
||||
type DocumentURI string
|
||||
|
||||
// Position in a text document expressed as zero-based line and zero-based character offset.
|
||||
// A position is between two characters like an ‘insert’ cursor in a editor.
|
||||
type Position struct {
|
||||
/**
|
||||
* Line position in a document (zero-based).
|
||||
*/
|
||||
Line float64 `json:"line"`
|
||||
|
||||
/**
|
||||
* Character offset on a line in a document (zero-based). Assuming that the line is
|
||||
* represented as a string, the `character` value represents the gap between the
|
||||
* `character` and `character + 1`.
|
||||
*
|
||||
* If the character value is greater than the line length it defaults back to the
|
||||
* line length.
|
||||
*/
|
||||
Character float64 `json:"character"`
|
||||
}
|
||||
|
||||
// Range in a text document expressed as (zero-based) start and end positions.
|
||||
// A range is comparable to a selection in an editor.
|
||||
// Therefore the end position is exclusive.
|
||||
// If you want to specify a range that contains a line including the line
|
||||
// ending character(s) then use an end position denoting the start of the next
|
||||
// line.
|
||||
type Range struct {
|
||||
/**
|
||||
* The range's start position.
|
||||
*/
|
||||
Start Position `json:"start"`
|
||||
|
||||
/**
|
||||
* The range's end position.
|
||||
*/
|
||||
End Position `json:"end"`
|
||||
}
|
||||
|
||||
// Location represents a location inside a resource, such as a line inside a text file.
|
||||
type Location struct {
|
||||
URI DocumentURI `json:"uri"`
|
||||
Range Range `json:"range"`
|
||||
}
|
||||
|
||||
// Diagnostic represents a diagnostic, such as a compiler error or warning.
|
||||
// Diagnostic objects are only valid in the scope of a resource.
|
||||
type Diagnostic struct {
|
||||
/**
|
||||
* The range at which the message applies.
|
||||
*/
|
||||
Range Range `json:"range"`
|
||||
|
||||
/**
|
||||
* The diagnostic's severity. Can be omitted. If omitted it is up to the
|
||||
* client to interpret diagnostics as error, warning, info or hint.
|
||||
*/
|
||||
Severity DiagnosticSeverity `json:"severity,omitempty"`
|
||||
|
||||
/**
|
||||
* The diagnostic's code, which might appear in the user interface.
|
||||
*/
|
||||
Code string `json:"code,omitempty"` // number | string
|
||||
|
||||
/**
|
||||
* A human-readable string describing the source of this
|
||||
* diagnostic, e.g. 'typescript' or 'super lint'.
|
||||
*/
|
||||
Source string `json:"source,omitempty"`
|
||||
|
||||
/**
|
||||
* The diagnostic's message.
|
||||
*/
|
||||
Message string `json:"message"`
|
||||
|
||||
/**
|
||||
* An array of related diagnostic information, e.g. when symbol-names within
|
||||
* a scope collide all definitions can be marked via this property.
|
||||
*/
|
||||
Related []DiagnosticRelatedInformation `json:"relatedInformation,omitempty"`
|
||||
}
|
||||
|
||||
// DiagnosticSeverity indicates the severity of a Diagnostic message.
|
||||
type DiagnosticSeverity float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* Reports an error.
|
||||
*/
|
||||
SeverityError DiagnosticSeverity = 1
|
||||
/**
|
||||
* Reports a warning.
|
||||
*/
|
||||
SeverityWarning DiagnosticSeverity = 2
|
||||
/**
|
||||
* Reports an information.
|
||||
*/
|
||||
SeverityInformation DiagnosticSeverity = 3
|
||||
/**
|
||||
* Reports a hint.
|
||||
*/
|
||||
SeverityHint DiagnosticSeverity = 4
|
||||
)
|
||||
|
||||
// DiagnosticRelatedInformation represents a related message and source code
|
||||
// location for a diagnostic.
|
||||
// This should be used to point to code locations that cause or related to a
|
||||
// diagnostics, e.g when duplicating a symbol in a scope.
|
||||
type DiagnosticRelatedInformation struct {
|
||||
/**
|
||||
* The location of this related diagnostic information.
|
||||
*/
|
||||
Location Location `json:"location"`
|
||||
|
||||
/**
|
||||
* The message of this related diagnostic information.
|
||||
*/
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Command represents a reference to a command.
|
||||
// Provides a title which will be used to represent a command in the UI.
|
||||
// Commands are identified by a string identifier.
|
||||
// The protocol currently doesn’t specify a set of well-known commands.
|
||||
// So executing a command requires some tool extension code.
|
||||
type Command struct {
|
||||
/**
|
||||
* Title of the command, like `save`.
|
||||
*/
|
||||
Title string `json:"title"`
|
||||
|
||||
/**
|
||||
* The identifier of the actual command handler.
|
||||
*/
|
||||
Command string `json:"command"`
|
||||
|
||||
/**
|
||||
* Arguments that the command handler should be
|
||||
* invoked with.
|
||||
*/
|
||||
Arguments []interface{} `json:"arguments,omitempty"`
|
||||
}
|
||||
|
||||
// TextEdit is a textual edit applicable to a text document.
|
||||
type TextEdit struct {
|
||||
/**
|
||||
* The range of the text document to be manipulated. To insert
|
||||
* text into a document create a range where start === end.
|
||||
*/
|
||||
Range Range `json:"range"`
|
||||
|
||||
/**
|
||||
* The string to be inserted. For delete operations use an
|
||||
* empty string.
|
||||
*/
|
||||
NewText string `json:"newText"`
|
||||
}
|
||||
|
||||
// TextDocumentEdit describes textual changes on a single text document.
|
||||
// The text document is referred to as a VersionedTextDocumentIdentifier to
|
||||
// allow clients to check the text document version before an edit is applied.
|
||||
// A TextDocumentEdit describes all changes on a version Si and after they are
|
||||
// applied move the document to version Si+1.
|
||||
// So the creator of a TextDocumentEdit doesn’t need to sort the array or do
|
||||
// any kind of ordering.
|
||||
// However the edits must be non overlapping.
|
||||
type TextDocumentEdit struct {
|
||||
/**
|
||||
* The text document to change.
|
||||
*/
|
||||
TextDocument VersionedTextDocumentIdentifier `json:"textDocument"`
|
||||
|
||||
/**
|
||||
* The edits to be applied.
|
||||
*/
|
||||
Edits []TextEdit `json:"edits"`
|
||||
}
|
||||
|
||||
// WorkspaceEdit represents changes to many resources managed in the workspace.
|
||||
// The edit should either provide Changes or DocumentChanges.
|
||||
// If the client can handle versioned document edits and if DocumentChanges are
|
||||
// present, the latter are preferred over Changes.
|
||||
type WorkspaceEdit struct {
|
||||
/**
|
||||
* Holds changes to existing resources.
|
||||
*/
|
||||
Changes map[DocumentURI][]TextEdit `json:"changes,omitempty"`
|
||||
|
||||
/**
|
||||
* An array of `TextDocumentEdit`s to express changes to n different text documents
|
||||
* where each text document edit addresses a specific version of a text document.
|
||||
* Whether a client supports versioned document edits is expressed via
|
||||
* `WorkspaceClientCapabilities.workspaceEdit.documentChanges`.
|
||||
*/
|
||||
DocumentChanges []TextDocumentEdit `json:"documentChanges,omitempty"`
|
||||
}
|
||||
|
||||
// TextDocumentIdentifier identifies a document using a URI.
|
||||
// On the protocol level, URIs are passed as strings.
|
||||
// The corresponding JSON structure looks like this.
|
||||
type TextDocumentIdentifier struct {
|
||||
/**
|
||||
* The text document's URI.
|
||||
*/
|
||||
URI DocumentURI `json:"uri"`
|
||||
}
|
||||
|
||||
// TextDocumentItem is an item to transfer a text document from the client to
|
||||
// the server.
|
||||
type TextDocumentItem struct {
|
||||
/**
|
||||
* The text document's URI.
|
||||
*/
|
||||
URI DocumentURI `json:"uri"`
|
||||
|
||||
/**
|
||||
* The text document's language identifier.
|
||||
*/
|
||||
LanguageID string `json:"languageId"`
|
||||
|
||||
/**
|
||||
* The version number of this document (it will increase after each
|
||||
* change, including undo/redo).
|
||||
*/
|
||||
Version float64 `json:"version"`
|
||||
|
||||
/**
|
||||
* The content of the opened text document.
|
||||
*/
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
// VersionedTextDocumentIdentifier is an identifier to denote a specific version of a text document.
|
||||
type VersionedTextDocumentIdentifier struct {
|
||||
TextDocumentIdentifier
|
||||
|
||||
/**
|
||||
* The version number of this document. If a versioned text document identifier
|
||||
* is sent from the server to the client and the file is not open in the editor
|
||||
* (the server has not received an open notification before) the server can send
|
||||
* `null` to indicate that the version is known and the content on disk is the
|
||||
* truth (as speced with document content ownership)
|
||||
*/
|
||||
Version *uint64 `json:"version"`
|
||||
}
|
||||
|
||||
// TextDocumentPositionParams is a parameter literal used in requests to pass
|
||||
// a text document and a position inside that document.
|
||||
type TextDocumentPositionParams struct {
|
||||
/**
|
||||
* The text document.
|
||||
*/
|
||||
TextDocument TextDocumentIdentifier `json:"textDocument"`
|
||||
|
||||
/**
|
||||
* The position inside the text document.
|
||||
*/
|
||||
Position Position `json:"position"`
|
||||
}
|
||||
|
||||
// DocumentFilter is a document filter denotes a document through properties
|
||||
// like language, scheme or pattern.
|
||||
// An example is a filter that applies to TypeScript files on disk.
|
||||
// Another example is a filter the applies to JSON files with name package.json:
|
||||
// { language: 'typescript', scheme: 'file' }
|
||||
// { language: 'json', pattern: '**/package.json' }
|
||||
type DocumentFilter struct {
|
||||
/**
|
||||
* A language id, like `typescript`.
|
||||
*/
|
||||
Language string `json:"language,omitempty"`
|
||||
|
||||
/**
|
||||
* A URI [scheme](#URI.scheme), like `file` or `untitled`.
|
||||
*/
|
||||
Scheme string `json:"scheme,omitempty"`
|
||||
|
||||
/**
|
||||
* A glob pattern, like `*.{ts,js}`.
|
||||
*/
|
||||
Pattern string `json:"pattern,omitempty"`
|
||||
}
|
||||
|
||||
// A document selector is the combination of one or more document filters.
|
||||
type DocumentSelector []DocumentFilter
|
||||
|
||||
/**
|
||||
* Describes the content type that a client supports in various
|
||||
* result literals like `Hover`, `ParameterInfo` or `CompletionItem`.
|
||||
*
|
||||
* Please note that `MarkupKinds` must not start with a `$`. This kinds
|
||||
* are reserved for internal usage.
|
||||
*/
|
||||
type MarkupKind string
|
||||
|
||||
const (
|
||||
/**
|
||||
* Plain text is supported as a content format
|
||||
*/
|
||||
PlainText MarkupKind = "plaintext"
|
||||
|
||||
/**
|
||||
* Markdown is supported as a content format
|
||||
*/
|
||||
Markdown MarkupKind = "markdown"
|
||||
)
|
||||
|
||||
/**
|
||||
* A `MarkupContent` literal represents a string value which content is interpreted base on its
|
||||
* kind flag. Currently the protocol supports `plaintext` and `markdown` as markup kinds.
|
||||
*
|
||||
* If the kind is `markdown` then the value can contain fenced code blocks like in GitHub issues.
|
||||
* See https://help.github.com/articles/creating-and-highlighting-code-blocks/#syntax-highlighting
|
||||
*
|
||||
* Here is an example how such a string can be constructed using JavaScript / TypeScript:
|
||||
* ```ts
|
||||
* let markdown: MarkdownContent = {
|
||||
* kind: MarkupKind.Markdown,
|
||||
* value: [
|
||||
* '# Header',
|
||||
* 'Some text',
|
||||
* '```typescript',
|
||||
* 'someCode();',
|
||||
* '```'
|
||||
* ].join('\n')
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* *Please Note* that clients might sanitize the return markdown. A client could decide to
|
||||
* remove HTML from the markdown to avoid script execution.
|
||||
*/
|
||||
type MarkupContent struct {
|
||||
/**
|
||||
* The type of the Markup
|
||||
*/
|
||||
Kind MarkupKind `json:"kind"`
|
||||
|
||||
/**
|
||||
* The content itself
|
||||
*/
|
||||
Value string `json:"value"`
|
||||
}
|
187
vendor/golang.org/x/tools/internal/lsp/protocol/client.go
generated
vendored
Normal file
187
vendor/golang.org/x/tools/internal/lsp/protocol/client.go
generated
vendored
Normal file
@@ -0,0 +1,187 @@
|
||||
// Copyright 2018 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 protocol
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"golang.org/x/tools/internal/jsonrpc2"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
ShowMessage(context.Context, *ShowMessageParams) error
|
||||
ShowMessageRequest(context.Context, *ShowMessageRequestParams) (*MessageActionItem, error)
|
||||
LogMessage(context.Context, *LogMessageParams) error
|
||||
Telemetry(context.Context, interface{}) error
|
||||
RegisterCapability(context.Context, *RegistrationParams) error
|
||||
UnregisterCapability(context.Context, *UnregistrationParams) error
|
||||
WorkspaceFolders(context.Context) ([]WorkspaceFolder, error)
|
||||
Configuration(context.Context, *ConfigurationParams) ([]interface{}, error)
|
||||
ApplyEdit(context.Context, *ApplyWorkspaceEditParams) (bool, error)
|
||||
PublishDiagnostics(context.Context, *PublishDiagnosticsParams) error
|
||||
}
|
||||
|
||||
func clientHandler(client Client) jsonrpc2.Handler {
|
||||
return func(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) {
|
||||
switch r.Method {
|
||||
case "$/cancelRequest":
|
||||
var params CancelParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
conn.Cancel(params.ID)
|
||||
|
||||
case "window/showMessage":
|
||||
var params ShowMessageParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.ShowMessage(ctx, ¶ms))
|
||||
|
||||
case "window/showMessageRequest":
|
||||
var params ShowMessageRequestParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := client.ShowMessageRequest(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "window/logMessage":
|
||||
var params LogMessageParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.LogMessage(ctx, ¶ms))
|
||||
|
||||
case "telemetry/event":
|
||||
var params interface{}
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.Telemetry(ctx, ¶ms))
|
||||
|
||||
case "client/registerCapability":
|
||||
var params RegistrationParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.RegisterCapability(ctx, ¶ms))
|
||||
|
||||
case "client/unregisterCapability":
|
||||
var params UnregistrationParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.UnregisterCapability(ctx, ¶ms))
|
||||
|
||||
case "workspace/workspaceFolders":
|
||||
if r.Params != nil {
|
||||
conn.Reply(ctx, r, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
|
||||
return
|
||||
}
|
||||
resp, err := client.WorkspaceFolders(ctx)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "workspace/configuration":
|
||||
var params ConfigurationParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := client.Configuration(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "workspace/applyEdit":
|
||||
var params ApplyWorkspaceEditParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := client.ApplyEdit(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/publishDiagnostics":
|
||||
var params PublishDiagnosticsParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(client.PublishDiagnostics(ctx, ¶ms))
|
||||
|
||||
default:
|
||||
if r.IsNotify() {
|
||||
conn.Reply(ctx, r, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeMethodNotFound, "method %q not found", r.Method))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type clientDispatcher struct {
|
||||
*jsonrpc2.Conn
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) ShowMessage(ctx context.Context, params *ShowMessageParams) error {
|
||||
return c.Conn.Notify(ctx, "window/showMessage", params)
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) ShowMessageRequest(ctx context.Context, params *ShowMessageRequestParams) (*MessageActionItem, error) {
|
||||
var result MessageActionItem
|
||||
if err := c.Conn.Call(ctx, "window/showMessageRequest", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) LogMessage(ctx context.Context, params *LogMessageParams) error {
|
||||
return c.Conn.Notify(ctx, "window/logMessage", params)
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) Telemetry(ctx context.Context, params interface{}) error {
|
||||
return c.Conn.Notify(ctx, "telemetry/event", params)
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) RegisterCapability(ctx context.Context, params *RegistrationParams) error {
|
||||
return c.Conn.Notify(ctx, "client/registerCapability", params)
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) UnregisterCapability(ctx context.Context, params *UnregistrationParams) error {
|
||||
return c.Conn.Notify(ctx, "client/unregisterCapability", params)
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) WorkspaceFolders(ctx context.Context) ([]WorkspaceFolder, error) {
|
||||
var result []WorkspaceFolder
|
||||
if err := c.Conn.Call(ctx, "workspace/workspaceFolders", nil, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) Configuration(ctx context.Context, params *ConfigurationParams) ([]interface{}, error) {
|
||||
var result []interface{}
|
||||
if err := c.Conn.Call(ctx, "workspace/configuration", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) ApplyEdit(ctx context.Context, params *ApplyWorkspaceEditParams) (bool, error) {
|
||||
var result bool
|
||||
if err := c.Conn.Call(ctx, "workspace/applyEdit", params, &result); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *clientDispatcher) PublishDiagnostics(ctx context.Context, params *PublishDiagnosticsParams) error {
|
||||
return c.Conn.Notify(ctx, "textDocument/publishDiagnostics", params)
|
||||
}
|
20
vendor/golang.org/x/tools/internal/lsp/protocol/diagnostics.go
generated
vendored
Normal file
20
vendor/golang.org/x/tools/internal/lsp/protocol/diagnostics.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Diagnostics" part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
type PublishDiagnosticsParams struct {
|
||||
/**
|
||||
* The URI for which diagnostic information is reported.
|
||||
*/
|
||||
URI DocumentURI `json:"uri"`
|
||||
|
||||
/**
|
||||
* An array of diagnostic information items.
|
||||
*/
|
||||
Diagnostics []Diagnostic `json:"diagnostics"`
|
||||
}
|
16
vendor/golang.org/x/tools/internal/lsp/protocol/doc.go
generated
vendored
Normal file
16
vendor/golang.org/x/tools/internal/lsp/protocol/doc.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 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 protocol contains the structs that map directly to the wire format
|
||||
// of the "Language Server Protocol".
|
||||
//
|
||||
// It is a literal transcription, with unmodified comments, and only the changes
|
||||
// required to make it go code.
|
||||
// Names are uppercased to export them.
|
||||
// All fields have JSON tags added to correct the names.
|
||||
// Fields marked with a ? are also marked as "omitempty"
|
||||
// Fields that are "|| null" are made pointers
|
||||
// Fields that are string or number are left as string
|
||||
// Fields that are type "number" are made float64
|
||||
package protocol
|
849
vendor/golang.org/x/tools/internal/lsp/protocol/general.go
generated
vendored
Normal file
849
vendor/golang.org/x/tools/internal/lsp/protocol/general.go
generated
vendored
Normal file
@@ -0,0 +1,849 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "General" messages part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
import "golang.org/x/tools/internal/jsonrpc2"
|
||||
|
||||
type CancelParams struct {
|
||||
/**
|
||||
* The request id to cancel.
|
||||
*/
|
||||
ID jsonrpc2.ID `json:"id"`
|
||||
}
|
||||
|
||||
type InitializeParams struct {
|
||||
/**
|
||||
* The process Id of the parent process that started
|
||||
* the server. Is null if the process has not been started by another process.
|
||||
* If the parent process is not alive then the server should exit (see exit notification) its process.
|
||||
*/
|
||||
ProcessID *float64 `json:"processId"`
|
||||
|
||||
/**
|
||||
* The rootPath of the workspace. Is null
|
||||
* if no folder is open.
|
||||
*
|
||||
* @deprecated in favour of rootURI.
|
||||
*/
|
||||
RootPath *string `json:"rootPath"`
|
||||
|
||||
/**
|
||||
* The rootURI of the workspace. Is null if no
|
||||
* folder is open. If both `rootPath` and `rootURI` are set
|
||||
* `rootURI` wins.
|
||||
*/
|
||||
RootURI *DocumentURI `json:"rootURI"`
|
||||
|
||||
/**
|
||||
* User provided initialization options.
|
||||
*/
|
||||
InitializationOptions interface{} `json:"initializationOptions"`
|
||||
|
||||
/**
|
||||
* The capabilities provided by the client (editor or tool)
|
||||
*/
|
||||
Capabilities ClientCapabilities `json:"capabilities"`
|
||||
|
||||
/**
|
||||
* The initial trace setting. If omitted trace is disabled ('off').
|
||||
*/
|
||||
Trace string `json:"trace"` // 'off' | 'messages' | 'verbose'
|
||||
|
||||
/**
|
||||
* The workspace folders configured in the client when the server starts.
|
||||
* This property is only available if the client supports workspace folders.
|
||||
* It can be `null` if the client supports workspace folders but none are
|
||||
* configured.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
WorkspaceFolders []WorkspaceFolder `json:"workspaceFolders,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace specific client capabilities.
|
||||
*/
|
||||
type WorkspaceClientCapabilities struct {
|
||||
/**
|
||||
* The client supports applying batch edits to the workspace by supporting
|
||||
* the request 'workspace/applyEdit'
|
||||
*/
|
||||
ApplyEdit bool `json:"applyEdit,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to `WorkspaceEdit`s
|
||||
*/
|
||||
WorkspaceEdit struct {
|
||||
/**
|
||||
* The client supports versioned document changes in `WorkspaceEdit`s
|
||||
*/
|
||||
DocumentChanges bool `json:"documentChanges,omitempty"`
|
||||
} `json:"workspaceEdit,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `workspace/didChangeConfiguration` notification.
|
||||
*/
|
||||
DidChangeConfiguration struct {
|
||||
/**
|
||||
* Did change configuration notification supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"didChangeConfiguration,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `workspace/didChangeWatchedFiles` notification.
|
||||
*/
|
||||
DidChangeWatchedFiles struct {
|
||||
/**
|
||||
* Did change watched files notification supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"didChangeWatchedFiles,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `workspace/symbol` request.
|
||||
*/
|
||||
Symbol struct {
|
||||
/**
|
||||
* Symbol request supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* Specific capabilities for the `SymbolKind` in the `workspace/symbol` request.
|
||||
*/
|
||||
SymbolKind struct {
|
||||
/**
|
||||
* The symbol kind values the client supports. When this
|
||||
* property exists the client also guarantees that it will
|
||||
* handle values outside its set gracefully and falls back
|
||||
* to a default value when unknown.
|
||||
*
|
||||
* If this property is not present the client only supports
|
||||
* the symbol kinds from `File` to `Array` as defined in
|
||||
* the initial version of the protocol.
|
||||
*/
|
||||
ValueSet []SymbolKind `json:"valueSet,omitempty"`
|
||||
} `json:"symbolKind,omitempty"`
|
||||
} `json:"symbol,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `workspace/executeCommand` request.
|
||||
*/
|
||||
ExecuteCommand struct {
|
||||
/**
|
||||
* Execute command supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"executeCommand,omitempty"`
|
||||
|
||||
/**
|
||||
* The client has support for workspace folders.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
WorkspaceFolders bool `json:"workspaceFolders,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports `workspace/configuration` requests.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
Configuration bool `json:"configuration,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Text document specific client capabilities.
|
||||
*/
|
||||
type TextDocumentClientCapabilities struct {
|
||||
Synchronization struct {
|
||||
/**
|
||||
* Whether text document synchronization supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports sending will save notifications.
|
||||
*/
|
||||
WillSave bool `json:"willSave,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports sending a will save request and
|
||||
* waits for a response providing text edits which will
|
||||
* be applied to the document before it is saved.
|
||||
*/
|
||||
WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports did save notifications.
|
||||
*/
|
||||
DidSave bool `json:"didSave,omitempty"`
|
||||
} `json:"synchronization,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/completion`
|
||||
*/
|
||||
Completion struct {
|
||||
/**
|
||||
* Whether completion supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports the following `CompletionItem` specific
|
||||
* capabilities.
|
||||
*/
|
||||
CompletionItem struct {
|
||||
/**
|
||||
* Client supports snippets as insert text.
|
||||
*
|
||||
* A snippet can define tab stops and placeholders with `$1`, `$2`
|
||||
* and `${3:foo}`. `$0` defines the final tab stop, it defaults to
|
||||
* the end of the snippet. Placeholders with equal identifiers are linked,
|
||||
* that is typing in one will update others too.
|
||||
*/
|
||||
SnippetSupport bool `json:"snippetSupport,omitempty"`
|
||||
|
||||
/**
|
||||
* Client supports commit characters on a completion item.
|
||||
*/
|
||||
CommitCharactersSupport bool `json:"commitCharactersSupport,omitempty"`
|
||||
|
||||
/**
|
||||
* Client supports the follow content formats for the documentation
|
||||
* property. The order describes the preferred format of the client.
|
||||
*/
|
||||
DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"`
|
||||
|
||||
/**
|
||||
* Client supports the deprecated property on a completion item.
|
||||
*/
|
||||
DeprecatedSupport bool `json:"deprecatedSupport,omitempty"`
|
||||
|
||||
/**
|
||||
* Client supports the preselect property on a completion item.
|
||||
*/
|
||||
PreselectSupport bool `json:"preselectSupport,omitempty"`
|
||||
} `json:"completionItem,omitempty"`
|
||||
|
||||
CompletionItemKind struct {
|
||||
/**
|
||||
* The completion item kind values the client supports. When this
|
||||
* property exists the client also guarantees that it will
|
||||
* handle values outside its set gracefully and falls back
|
||||
* to a default value when unknown.
|
||||
*
|
||||
* If this property is not present the client only supports
|
||||
* the completion items kinds from `Text` to `Reference` as defined in
|
||||
* the initial version of the protocol.
|
||||
*/
|
||||
ValueSet []CompletionItemKind `json:"valueSet,omitempty"`
|
||||
} `json:"completionItemKind,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports to send additional context information for a
|
||||
* `textDocument/completion` request.
|
||||
*/
|
||||
ContextSupport bool `json:"contextSupport,omitempty"`
|
||||
} `json:"completion"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/hover`
|
||||
*/
|
||||
Hover struct {
|
||||
/**
|
||||
* Whether hover supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* Client supports the follow content formats for the content
|
||||
* property. The order describes the preferred format of the client.
|
||||
*/
|
||||
ContentFormat []MarkupKind `json:"contentFormat,omitempty"`
|
||||
} `json:"hover,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/signatureHelp`
|
||||
*/
|
||||
SignatureHelp struct {
|
||||
/**
|
||||
* Whether signature help supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* The client supports the following `SignatureInformation`
|
||||
* specific properties.
|
||||
*/
|
||||
SignatureInformation struct {
|
||||
/**
|
||||
* Client supports the follow content formats for the documentation
|
||||
* property. The order describes the preferred format of the client.
|
||||
*/
|
||||
DocumentationFormat []MarkupKind `json:"documentationFormat,omitempty"`
|
||||
} `json:"signatureInformation,omitempty"`
|
||||
} `json:"signatureHelp,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/references`
|
||||
*/
|
||||
References struct {
|
||||
/**
|
||||
* Whether references supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"references,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/documentHighlight`
|
||||
*/
|
||||
DocumentHighlight struct {
|
||||
/**
|
||||
* Whether document highlight supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"documentHighlight,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/documentSymbol`
|
||||
*/
|
||||
DocumentSymbol struct {
|
||||
/**
|
||||
* Whether document symbol supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
|
||||
/**
|
||||
* Specific capabilities for the `SymbolKind`.
|
||||
*/
|
||||
SymbolKind struct {
|
||||
/**
|
||||
* The symbol kind values the client supports. When this
|
||||
* property exists the client also guarantees that it will
|
||||
* handle values outside its set gracefully and falls back
|
||||
* to a default value when unknown.
|
||||
*
|
||||
* If this property is not present the client only supports
|
||||
* the symbol kinds from `File` to `Array` as defined in
|
||||
* the initial version of the protocol.
|
||||
*/
|
||||
ValueSet []SymbolKind `json:"valueSet,omitempty"`
|
||||
} `json:"symbolKind,omitempty"`
|
||||
|
||||
/**
|
||||
* The client support hierarchical document symbols.
|
||||
*/
|
||||
HierarchicalDocumentSymbolSupport bool `json:"hierarchicalDocumentSymbolSupport,omitempty"`
|
||||
} `json:"documentSymbol,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/formatting`
|
||||
*/
|
||||
Formatting struct {
|
||||
/**
|
||||
* Whether formatting supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"formatting,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/rangeFormatting`
|
||||
*/
|
||||
RangeFormatting struct {
|
||||
/**
|
||||
* Whether range formatting supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"rangeFormatting,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/onTypeFormatting`
|
||||
*/
|
||||
OnTypeFormatting struct {
|
||||
/**
|
||||
* Whether on type formatting supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"onTypeFormatting,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/definition`
|
||||
*/
|
||||
Definition struct {
|
||||
/**
|
||||
* Whether definition supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"definition,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/typeDefinition`
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
TypeDefinition struct {
|
||||
/**
|
||||
* Whether typeDefinition supports dynamic registration. If this is set to `true`
|
||||
* the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
|
||||
* return value for the corresponding server capability as well.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"typeDefinition,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/implementation`.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
Implementation struct {
|
||||
/**
|
||||
* Whether implementation supports dynamic registration. If this is set to `true`
|
||||
* the client supports the new `(TextDocumentRegistrationOptions & StaticRegistrationOptions)`
|
||||
* return value for the corresponding server capability as well.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"implementation,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/codeAction`
|
||||
*/
|
||||
CodeAction struct {
|
||||
/**
|
||||
* Whether code action supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
/**
|
||||
* The client support code action literals as a valid
|
||||
* response of the `textDocument/codeAction` request.
|
||||
*
|
||||
* Since 3.8.0
|
||||
*/
|
||||
CodeActionLiteralSupport struct {
|
||||
/**
|
||||
* The code action kind is support with the following value
|
||||
* set.
|
||||
*/
|
||||
CodeActionKind struct {
|
||||
|
||||
/**
|
||||
* The code action kind values the client supports. When this
|
||||
* property exists the client also guarantees that it will
|
||||
* handle values outside its set gracefully and falls back
|
||||
* to a default value when unknown.
|
||||
*/
|
||||
ValueSet []CodeActionKind `json:"valueSet"`
|
||||
} `json:"codeActionKind"`
|
||||
} `json:"codeActionLiteralSupport,omitempty"`
|
||||
} `json:"codeAction,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/codeLens`
|
||||
*/
|
||||
CodeLens struct {
|
||||
/**
|
||||
* Whether code lens supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"codeLens,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/documentLink`
|
||||
*/
|
||||
DocumentLink struct {
|
||||
/**
|
||||
* Whether document link supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"documentLink,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/documentColor` and the
|
||||
* `textDocument/colorPresentation` request.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
ColorProvider struct {
|
||||
/**
|
||||
* Whether colorProvider supports dynamic registration. If this is set to `true`
|
||||
* the client supports the new `(ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
|
||||
* return value for the corresponding server capability as well.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"colorProvider,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to the `textDocument/rename`
|
||||
*/
|
||||
Rename struct {
|
||||
/**
|
||||
* Whether rename supports dynamic registration.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
} `json:"rename,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to `textDocument/publishDiagnostics`.
|
||||
*/
|
||||
PublishDiagnostics struct {
|
||||
/**
|
||||
* Whether the clients accepts diagnostics with related information.
|
||||
*/
|
||||
RelatedInformation bool `json:"relatedInformation,omitempty"`
|
||||
} `json:"publishDiagnostics,omitempty"`
|
||||
|
||||
/**
|
||||
* Capabilities specific to `textDocument/foldingRange` requests.
|
||||
*
|
||||
* Since 3.10.0
|
||||
*/
|
||||
FoldingRange struct {
|
||||
/**
|
||||
* Whether implementation supports dynamic registration for folding range providers. If this is set to `true`
|
||||
* the client supports the new `(FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)`
|
||||
* return value for the corresponding server capability as well.
|
||||
*/
|
||||
DynamicRegistration bool `json:"dynamicRegistration,omitempty"`
|
||||
/**
|
||||
* The maximum number of folding ranges that the client prefers to receive per document. The value serves as a
|
||||
* hint, servers are free to follow the limit.
|
||||
*/
|
||||
RangeLimit float64 `json:"rangeLimit,omitempty"`
|
||||
/**
|
||||
* If set, the client signals that it only supports folding complete lines. If set, client will
|
||||
* ignore specified `startCharacter` and `endCharacter` properties in a FoldingRange.
|
||||
*/
|
||||
LineFoldingOnly bool `json:"lineFoldingOnly,omitempty"`
|
||||
}
|
||||
}
|
||||
|
||||
// ClientCapabilities now define capabilities for dynamic registration, workspace
|
||||
// and text document features the client supports. The experimental can be used to
|
||||
// pass experimental capabilities under development. For future compatibility a
|
||||
// ClientCapabilities object literal can have more properties set than currently
|
||||
// defined. Servers receiving a ClientCapabilities object literal with unknown
|
||||
// properties should ignore these properties. A missing property should be
|
||||
// interpreted as an absence of the capability. If a property is missing that
|
||||
// defines sub properties all sub properties should be interpreted as an absence
|
||||
// of the capability.
|
||||
//
|
||||
// Client capabilities got introduced with version 3.0 of the protocol. They
|
||||
// therefore only describe capabilities that got introduced in 3.x or later.
|
||||
// Capabilities that existed in the 2.x version of the protocol are still
|
||||
// mandatory for clients. Clients cannot opt out of providing them. So even if a
|
||||
// client omits the ClientCapabilities.textDocument.synchronization it is still
|
||||
// required that the client provides text document synchronization (e.g. open,
|
||||
// changed and close notifications).
|
||||
type ClientCapabilities struct {
|
||||
/**
|
||||
* Workspace specific client capabilities.
|
||||
*/
|
||||
Workspace WorkspaceClientCapabilities `json:"workspace,omitempty"`
|
||||
|
||||
/**
|
||||
* Text document specific client capabilities.
|
||||
*/
|
||||
TextDocument TextDocumentClientCapabilities `json:"textDocument,omitempty"`
|
||||
|
||||
/**
|
||||
* Experimental client capabilities.
|
||||
*/
|
||||
Experimental interface{} `json:"experimental,omitempty"`
|
||||
}
|
||||
|
||||
type InitializeResult struct {
|
||||
/**
|
||||
* The capabilities the language server provides.
|
||||
*/
|
||||
Capabilities ServerCapabilities `json:"capabilities"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines how the host (editor) should sync document changes to the language server.
|
||||
*/
|
||||
type TextDocumentSyncKind float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* Documents should not be synced at all.
|
||||
*/
|
||||
None TextDocumentSyncKind = 0
|
||||
|
||||
/**
|
||||
* Documents are synced by always sending the full content
|
||||
* of the document.
|
||||
*/
|
||||
Full TextDocumentSyncKind = 1
|
||||
|
||||
/**
|
||||
* Documents are synced by sending the full content on open.
|
||||
* After that only incremental updates to the document are
|
||||
* send.
|
||||
*/
|
||||
Incremental TextDocumentSyncKind = 2
|
||||
)
|
||||
|
||||
/**
|
||||
* Completion options.
|
||||
*/
|
||||
type CompletionOptions struct {
|
||||
/**
|
||||
* The server provides support to resolve additional
|
||||
* information for a completion item.
|
||||
*/
|
||||
ResolveProvider bool `json:"resolveProvider,omitempty"`
|
||||
|
||||
/**
|
||||
* The characters that trigger completion automatically.
|
||||
*/
|
||||
TriggerCharacters []string `json:"triggerCharacters,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Signature help options.
|
||||
*/
|
||||
type SignatureHelpOptions struct {
|
||||
/**
|
||||
* The characters that trigger signature help
|
||||
* automatically.
|
||||
*/
|
||||
TriggerCharacters []string `json:"triggerCharacters,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Code Lens options.
|
||||
*/
|
||||
type CodeLensOptions struct {
|
||||
/**
|
||||
* Code lens has a resolve provider as well.
|
||||
*/
|
||||
ResolveProvider bool `json:"resolveProvider,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Format document on type options.
|
||||
*/
|
||||
type DocumentOnTypeFormattingOptions struct {
|
||||
/**
|
||||
* A character on which formatting should be triggered, like `}`.
|
||||
*/
|
||||
FirstTriggerCharacter string `json:"firstTriggerCharacter"`
|
||||
|
||||
/**
|
||||
* More trigger characters.
|
||||
*/
|
||||
MoreTriggerCharacter []string `json:"moreTriggerCharacter,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Document link options.
|
||||
*/
|
||||
type DocumentLinkOptions struct {
|
||||
/**
|
||||
* Document links have a resolve provider as well.
|
||||
*/
|
||||
ResolveProvider bool `json:"resolveProvider,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute command options.
|
||||
*/
|
||||
type ExecuteCommandOptions struct {
|
||||
/**
|
||||
* The commands to be executed on the server
|
||||
*/
|
||||
Commands []string `json:"commands"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Save options.
|
||||
*/
|
||||
type SaveOptions struct {
|
||||
/**
|
||||
* The client is supposed to include the content on save.
|
||||
*/
|
||||
IncludeText bool `json:"includeText,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Color provider options.
|
||||
*/
|
||||
type ColorProviderOptions struct {
|
||||
}
|
||||
|
||||
/**
|
||||
* Folding range provider options.
|
||||
*/
|
||||
type FoldingRangeProviderOptions struct {
|
||||
}
|
||||
|
||||
type TextDocumentSyncOptions struct {
|
||||
/**
|
||||
* Open and close notifications are sent to the server.
|
||||
*/
|
||||
OpenClose bool `json:"openClose,omitempty"`
|
||||
/**
|
||||
* Change notifications are sent to the server. See TextDocumentSyncKind.None, TextDocumentSyncKind.Full
|
||||
* and TextDocumentSyncKind.Incremental. If omitted it defaults to TextDocumentSyncKind.None.
|
||||
*/
|
||||
Change float64 `json:"change,omitempty"`
|
||||
/**
|
||||
* Will save notifications are sent to the server.
|
||||
*/
|
||||
WillSave bool `json:"willSave,omitempty"`
|
||||
/**
|
||||
* Will save wait until requests are sent to the server.
|
||||
*/
|
||||
WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"`
|
||||
/**
|
||||
* Save notifications are sent to the server.
|
||||
*/
|
||||
Save SaveOptions `json:"save,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Static registration options to be returned in the initialize request.
|
||||
*/
|
||||
type StaticRegistrationOptions struct {
|
||||
/**
|
||||
* The id used to register the request. The id can be used to deregister
|
||||
* the request again. See also Registration#id.
|
||||
*/
|
||||
ID string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type ServerCapabilities struct {
|
||||
/**
|
||||
* Defines how text documents are synced. Is either a detailed structure defining each notification or
|
||||
* for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
|
||||
*/
|
||||
TextDocumentSync interface{} `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | number
|
||||
/**
|
||||
* The server provides hover support.
|
||||
*/
|
||||
HoverProvider bool `json:"hoverProvider,omitempty"`
|
||||
/**
|
||||
* The server provides completion support.
|
||||
*/
|
||||
CompletionProvider CompletionOptions `json:"completionProvider,omitempty"`
|
||||
/**
|
||||
* The server provides signature help support.
|
||||
*/
|
||||
SignatureHelpProvider SignatureHelpOptions `json:"signatureHelpProvider,omitempty"`
|
||||
/**
|
||||
* The server provides goto definition support.
|
||||
*/
|
||||
DefinitionProvider bool `json:"definitionProvider,omitempty"`
|
||||
/**
|
||||
* The server provides Goto Type Definition support.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
TypeDefinitionProvider interface{} `json:"typeDefinitionProvider,omitempty"` // boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions)
|
||||
/**
|
||||
* The server provides Goto Implementation support.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
ImplementationProvider interface{} `json:"implementationProvider,omitempty"` // boolean | (TextDocumentRegistrationOptions & StaticRegistrationOptions)
|
||||
/**
|
||||
* The server provides find references support.
|
||||
*/
|
||||
ReferencesProvider bool `json:"referencesProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document highlight support.
|
||||
*/
|
||||
DocumentHighlightProvider bool `json:"documentHighlightProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document symbol support.
|
||||
*/
|
||||
DocumentSymbolProvider bool `json:"documentSymbolProvider,omitempty"`
|
||||
/**
|
||||
* The server provides workspace symbol support.
|
||||
*/
|
||||
WorkspaceSymbolProvider bool `json:"workspaceSymbolProvider,omitempty"`
|
||||
/**
|
||||
* The server provides code actions.
|
||||
*/
|
||||
CodeActionProvider bool `json:"codeActionProvider,omitempty"`
|
||||
/**
|
||||
* The server provides code lens.
|
||||
*/
|
||||
CodeLensProvider CodeLensOptions `json:"codeLensProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document formatting.
|
||||
*/
|
||||
DocumentFormattingProvider bool `json:"documentFormattingProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document range formatting.
|
||||
*/
|
||||
DocumentRangeFormattingProvider bool `json:"documentRangeFormattingProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document formatting on typing.
|
||||
*/
|
||||
DocumentOnTypeFormattingProvider DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"`
|
||||
/**
|
||||
* The server provides rename support.
|
||||
*/
|
||||
RenameProvider bool `json:"renameProvider,omitempty"`
|
||||
/**
|
||||
* The server provides document link support.
|
||||
*/
|
||||
DocumentLinkProvider DocumentLinkOptions `json:"documentLinkProvider,omitempty"`
|
||||
/**
|
||||
* The server provides color provider support.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
//TODO: complex union type to decode here
|
||||
ColorProvider interface{} `json:"colorProvider,omitempty"` // boolean | ColorProviderOptions | (ColorProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)
|
||||
/**
|
||||
* The server provides folding provider support.
|
||||
*
|
||||
* Since 3.10.0
|
||||
*/
|
||||
//TODO: complex union type to decode here
|
||||
FoldingRangeProvider interface{} `json:"foldingRangeProvider,omitempty"` // boolean | FoldingRangeProviderOptions | (FoldingRangeProviderOptions & TextDocumentRegistrationOptions & StaticRegistrationOptions)
|
||||
/**
|
||||
* The server provides execute command support.
|
||||
*/
|
||||
ExecuteCommandProvider ExecuteCommandOptions `json:"executeCommandProvider,omitempty"`
|
||||
/**
|
||||
* Workspace specific server capabilities
|
||||
*/
|
||||
Workspace struct {
|
||||
/**
|
||||
* The server supports workspace folder.
|
||||
*
|
||||
* Since 3.6.0
|
||||
*/
|
||||
WorkspaceFolders struct {
|
||||
/**
|
||||
* The server has support for workspace folders
|
||||
*/
|
||||
Supported bool `json:"supported,omitempty"`
|
||||
/**
|
||||
* Whether the server wants to receive workspace folder
|
||||
* change notifications.
|
||||
*
|
||||
* If a strings is provided the string is treated as a ID
|
||||
* under which the notification is registered on the client
|
||||
* side. The ID can be used to unregister for these events
|
||||
* using the `client/unregisterCapability` request.
|
||||
*/
|
||||
ChangeNotifications interface{} `json:"changeNotifications,omitempty"` // string | boolean
|
||||
} `json:"workspaceFolders,omitempty"`
|
||||
} `json:"workspace,omitempty"`
|
||||
/**
|
||||
* Experimental server capabilities.
|
||||
*/
|
||||
Experimental interface{} `json:"experimental,omitempty"`
|
||||
}
|
||||
|
||||
type InitializedParams struct {
|
||||
}
|
1020
vendor/golang.org/x/tools/internal/lsp/protocol/language.go
generated
vendored
Normal file
1020
vendor/golang.org/x/tools/internal/lsp/protocol/language.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
39
vendor/golang.org/x/tools/internal/lsp/protocol/printers.go
generated
vendored
Normal file
39
vendor/golang.org/x/tools/internal/lsp/protocol/printers.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains formatting functions for types that
|
||||
// are commonly printed in debugging information.
|
||||
// They are separated from their types and gathered here as
|
||||
// they are hand written and not generated from the spec.
|
||||
// They should not be relied on for programmatic use (their
|
||||
// results should never be parsed for instance) but are meant
|
||||
// for temporary debugging and error messages.
|
||||
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (p Position) Format(f fmt.State, c rune) {
|
||||
fmt.Fprintf(f, "%d", int(p.Line))
|
||||
if p.Character >= 0 {
|
||||
fmt.Fprintf(f, ":%d", int(p.Character))
|
||||
}
|
||||
}
|
||||
|
||||
func (r Range) Format(f fmt.State, c rune) {
|
||||
switch {
|
||||
case r.Start == r.End || r.End.Line < 0:
|
||||
fmt.Fprintf(f, "%v", r.Start)
|
||||
case r.End.Line == r.Start.Line:
|
||||
fmt.Fprintf(f, "%v¦%d", r.Start, int(r.End.Character))
|
||||
default:
|
||||
fmt.Fprintf(f, "%v¦%v", r.Start, r.End)
|
||||
}
|
||||
}
|
||||
|
||||
func (l Location) Format(f fmt.State, c rune) {
|
||||
fmt.Fprintf(f, "%s:%v", l.URI, l.Range)
|
||||
}
|
49
vendor/golang.org/x/tools/internal/lsp/protocol/protocol.go
generated
vendored
Normal file
49
vendor/golang.org/x/tools/internal/lsp/protocol/protocol.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2018 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 protocol
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"golang.org/x/tools/internal/jsonrpc2"
|
||||
)
|
||||
|
||||
func canceller(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
|
||||
conn.Notify(context.Background(), "$/cancelRequest", &CancelParams{ID: *req.ID})
|
||||
}
|
||||
|
||||
func RunClient(ctx context.Context, stream jsonrpc2.Stream, client Client, opts ...interface{}) (*jsonrpc2.Conn, Server) {
|
||||
opts = append([]interface{}{clientHandler(client), jsonrpc2.Canceler(canceller)}, opts...)
|
||||
conn := jsonrpc2.NewConn(ctx, stream, opts...)
|
||||
return conn, &serverDispatcher{Conn: conn}
|
||||
}
|
||||
|
||||
func RunServer(ctx context.Context, stream jsonrpc2.Stream, server Server, opts ...interface{}) (*jsonrpc2.Conn, Client) {
|
||||
opts = append([]interface{}{serverHandler(server), jsonrpc2.Canceler(canceller)}, opts...)
|
||||
conn := jsonrpc2.NewConn(ctx, stream, opts...)
|
||||
return conn, &clientDispatcher{Conn: conn}
|
||||
}
|
||||
|
||||
func sendParseError(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request, err error) {
|
||||
if _, ok := err.(*jsonrpc2.Error); !ok {
|
||||
err = jsonrpc2.NewErrorf(jsonrpc2.CodeParseError, "%v", err)
|
||||
}
|
||||
unhandledError(conn.Reply(ctx, req, nil, err))
|
||||
}
|
||||
|
||||
// unhandledError is used in places where an error may occur that cannot be handled.
|
||||
// This occurs in things like rpc handlers that are a notify, where we cannot
|
||||
// reply to the caller, or in a call when we are actually attempting to reply.
|
||||
// In these cases, there is nothing we can do with the error except log it, so
|
||||
// we do that in this function, and the presence of this function acts as a
|
||||
// useful reminder of why we are effectively dropping the error and also a
|
||||
// good place to hook in when debugging those kinds of errors.
|
||||
func unhandledError(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
log.Printf("%v", err)
|
||||
}
|
61
vendor/golang.org/x/tools/internal/lsp/protocol/registration.go
generated
vendored
Normal file
61
vendor/golang.org/x/tools/internal/lsp/protocol/registration.go
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Client" part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
/**
|
||||
* General parameters to register for a capability.
|
||||
*/
|
||||
type Registration struct {
|
||||
/**
|
||||
* The id used to register the request. The id can be used to deregister
|
||||
* the request again.
|
||||
*/
|
||||
ID string `json:"id"`
|
||||
|
||||
/**
|
||||
* The method / capability to register for.
|
||||
*/
|
||||
Method string `json:"method"`
|
||||
|
||||
/**
|
||||
* Options necessary for the registration.
|
||||
*/
|
||||
RegisterOptions interface{} `json:"registerOptions,omitempty"`
|
||||
}
|
||||
|
||||
type RegistrationParams struct {
|
||||
Registrations []Registration `json:"registrations"`
|
||||
}
|
||||
|
||||
type TextDocumentRegistrationOptions struct {
|
||||
/**
|
||||
* A document selector to identify the scope of the registration. If set to null
|
||||
* the document selector provided on the client side will be used.
|
||||
*/
|
||||
DocumentSelector *DocumentSelector `json:"documentSelector"`
|
||||
}
|
||||
|
||||
/**
|
||||
* General parameters to unregister a capability.
|
||||
*/
|
||||
type Unregistration struct {
|
||||
/**
|
||||
* The id used to unregister the request or notification. Usually an id
|
||||
* provided during the register request.
|
||||
*/
|
||||
ID string `json:"id"`
|
||||
|
||||
/**
|
||||
* The method / capability to unregister for.
|
||||
*/
|
||||
Method string `json:"method"`
|
||||
}
|
||||
|
||||
type UnregistrationParams struct {
|
||||
Unregisterations []Unregistration `json:"unregisterations"`
|
||||
}
|
646
vendor/golang.org/x/tools/internal/lsp/protocol/server.go
generated
vendored
Normal file
646
vendor/golang.org/x/tools/internal/lsp/protocol/server.go
generated
vendored
Normal file
@@ -0,0 +1,646 @@
|
||||
// Copyright 2018 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 protocol
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"golang.org/x/tools/internal/jsonrpc2"
|
||||
)
|
||||
|
||||
type Server interface {
|
||||
Initialize(context.Context, *InitializeParams) (*InitializeResult, error)
|
||||
Initialized(context.Context, *InitializedParams) error
|
||||
Shutdown(context.Context) error
|
||||
Exit(context.Context) error
|
||||
DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error
|
||||
DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error
|
||||
DidChangeWatchedFiles(context.Context, *DidChangeWatchedFilesParams) error
|
||||
Symbols(context.Context, *WorkspaceSymbolParams) ([]SymbolInformation, error)
|
||||
ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{}, error)
|
||||
DidOpen(context.Context, *DidOpenTextDocumentParams) error
|
||||
DidChange(context.Context, *DidChangeTextDocumentParams) error
|
||||
WillSave(context.Context, *WillSaveTextDocumentParams) error
|
||||
WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit, error)
|
||||
DidSave(context.Context, *DidSaveTextDocumentParams) error
|
||||
DidClose(context.Context, *DidCloseTextDocumentParams) error
|
||||
Completion(context.Context, *CompletionParams) (*CompletionList, error)
|
||||
CompletionResolve(context.Context, *CompletionItem) (*CompletionItem, error)
|
||||
Hover(context.Context, *TextDocumentPositionParams) (*Hover, error)
|
||||
SignatureHelp(context.Context, *TextDocumentPositionParams) (*SignatureHelp, error)
|
||||
Definition(context.Context, *TextDocumentPositionParams) ([]Location, error)
|
||||
TypeDefinition(context.Context, *TextDocumentPositionParams) ([]Location, error)
|
||||
Implementation(context.Context, *TextDocumentPositionParams) ([]Location, error)
|
||||
References(context.Context, *ReferenceParams) ([]Location, error)
|
||||
DocumentHighlight(context.Context, *TextDocumentPositionParams) ([]DocumentHighlight, error)
|
||||
DocumentSymbol(context.Context, *DocumentSymbolParams) ([]DocumentSymbol, error)
|
||||
CodeAction(context.Context, *CodeActionParams) ([]CodeAction, error)
|
||||
CodeLens(context.Context, *CodeLensParams) ([]CodeLens, error)
|
||||
CodeLensResolve(context.Context, *CodeLens) (*CodeLens, error)
|
||||
DocumentLink(context.Context, *DocumentLinkParams) ([]DocumentLink, error)
|
||||
DocumentLinkResolve(context.Context, *DocumentLink) (*DocumentLink, error)
|
||||
DocumentColor(context.Context, *DocumentColorParams) ([]ColorInformation, error)
|
||||
ColorPresentation(context.Context, *ColorPresentationParams) ([]ColorPresentation, error)
|
||||
Formatting(context.Context, *DocumentFormattingParams) ([]TextEdit, error)
|
||||
RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit, error)
|
||||
OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit, error)
|
||||
Rename(context.Context, *RenameParams) ([]WorkspaceEdit, error)
|
||||
FoldingRanges(context.Context, *FoldingRangeRequestParam) ([]FoldingRange, error)
|
||||
}
|
||||
|
||||
func serverHandler(server Server) jsonrpc2.Handler {
|
||||
return func(ctx context.Context, conn *jsonrpc2.Conn, r *jsonrpc2.Request) {
|
||||
switch r.Method {
|
||||
case "initialize":
|
||||
var params InitializeParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Initialize(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "initialized":
|
||||
var params InitializedParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.Initialized(ctx, ¶ms))
|
||||
|
||||
case "shutdown":
|
||||
if r.Params != nil {
|
||||
conn.Reply(ctx, r, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
|
||||
return
|
||||
}
|
||||
unhandledError(server.Shutdown(ctx))
|
||||
|
||||
case "exit":
|
||||
if r.Params != nil {
|
||||
conn.Reply(ctx, r, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidParams, "Expected no params"))
|
||||
return
|
||||
}
|
||||
unhandledError(server.Exit(ctx))
|
||||
|
||||
case "$/cancelRequest":
|
||||
var params CancelParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
conn.Cancel(params.ID)
|
||||
|
||||
case "workspace/didChangeWorkspaceFolders":
|
||||
var params DidChangeWorkspaceFoldersParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidChangeWorkspaceFolders(ctx, ¶ms))
|
||||
|
||||
case "workspace/didChangeConfiguration":
|
||||
var params DidChangeConfigurationParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidChangeConfiguration(ctx, ¶ms))
|
||||
|
||||
case "workspace/didChangeWatchedFiles":
|
||||
var params DidChangeWatchedFilesParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidChangeWatchedFiles(ctx, ¶ms))
|
||||
|
||||
case "workspace/symbol":
|
||||
var params WorkspaceSymbolParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Symbols(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "workspace/executeCommand":
|
||||
var params ExecuteCommandParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.ExecuteCommand(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/didOpen":
|
||||
var params DidOpenTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidOpen(ctx, ¶ms))
|
||||
|
||||
case "textDocument/didChange":
|
||||
var params DidChangeTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidChange(ctx, ¶ms))
|
||||
|
||||
case "textDocument/willSave":
|
||||
var params WillSaveTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.WillSave(ctx, ¶ms))
|
||||
|
||||
case "textDocument/willSaveWaitUntil":
|
||||
var params WillSaveTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.WillSaveWaitUntil(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/didSave":
|
||||
var params DidSaveTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidSave(ctx, ¶ms))
|
||||
|
||||
case "textDocument/didClose":
|
||||
var params DidCloseTextDocumentParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
unhandledError(server.DidClose(ctx, ¶ms))
|
||||
|
||||
case "textDocument/completion":
|
||||
var params CompletionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Completion(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "completionItem/resolve":
|
||||
var params CompletionItem
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.CompletionResolve(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/hover":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Hover(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/signatureHelp":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.SignatureHelp(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/definition":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Definition(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/typeDefinition":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.TypeDefinition(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/implementation":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Implementation(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/references":
|
||||
var params ReferenceParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.References(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/documentHighlight":
|
||||
var params TextDocumentPositionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.DocumentHighlight(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/documentSymbol":
|
||||
var params DocumentSymbolParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.DocumentSymbol(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/codeAction":
|
||||
var params CodeActionParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.CodeAction(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/codeLens":
|
||||
var params CodeLensParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.CodeLens(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "codeLens/resolve":
|
||||
var params CodeLens
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.CodeLensResolve(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/documentLink":
|
||||
var params DocumentLinkParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.DocumentLink(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "documentLink/resolve":
|
||||
var params DocumentLink
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.DocumentLinkResolve(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/documentColor":
|
||||
var params DocumentColorParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.DocumentColor(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/colorPresentation":
|
||||
var params ColorPresentationParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.ColorPresentation(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/formatting":
|
||||
var params DocumentFormattingParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Formatting(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/rangeFormatting":
|
||||
var params DocumentRangeFormattingParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.RangeFormatting(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/onTypeFormatting":
|
||||
var params DocumentOnTypeFormattingParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.OnTypeFormatting(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/rename":
|
||||
var params RenameParams
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.Rename(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
|
||||
case "textDocument/foldingRanges":
|
||||
var params FoldingRangeRequestParam
|
||||
if err := json.Unmarshal(*r.Params, ¶ms); err != nil {
|
||||
sendParseError(ctx, conn, r, err)
|
||||
return
|
||||
}
|
||||
resp, err := server.FoldingRanges(ctx, ¶ms)
|
||||
unhandledError(conn.Reply(ctx, r, resp, err))
|
||||
default:
|
||||
if r.IsNotify() {
|
||||
conn.Reply(ctx, r, nil, jsonrpc2.NewErrorf(jsonrpc2.CodeMethodNotFound, "method %q not found", r.Method))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type serverDispatcher struct {
|
||||
*jsonrpc2.Conn
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Initialize(ctx context.Context, params *InitializeParams) (*InitializeResult, error) {
|
||||
var result InitializeResult
|
||||
if err := s.Conn.Call(ctx, "initialize", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Initialized(ctx context.Context, params *InitializedParams) error {
|
||||
return s.Conn.Notify(ctx, "initialized", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Shutdown(ctx context.Context) error {
|
||||
return s.Conn.Call(ctx, "shutdown", nil, nil)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Exit(ctx context.Context) error {
|
||||
return s.Conn.Notify(ctx, "exit", nil)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidChangeWorkspaceFolders(ctx context.Context, params *DidChangeWorkspaceFoldersParams) error {
|
||||
return s.Conn.Notify(ctx, "workspace/didChangeWorkspaceFolders", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidChangeConfiguration(ctx context.Context, params *DidChangeConfigurationParams) error {
|
||||
return s.Conn.Notify(ctx, "workspace/didChangeConfiguration", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidChangeWatchedFiles(ctx context.Context, params *DidChangeWatchedFilesParams) error {
|
||||
return s.Conn.Notify(ctx, "workspace/didChangeWatchedFiles", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Symbols(ctx context.Context, params *WorkspaceSymbolParams) ([]SymbolInformation, error) {
|
||||
var result []SymbolInformation
|
||||
if err := s.Conn.Call(ctx, "workspace/symbol", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) ExecuteCommand(ctx context.Context, params *ExecuteCommandParams) (interface{}, error) {
|
||||
var result interface{}
|
||||
if err := s.Conn.Call(ctx, "workspace/executeCommand", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidOpen(ctx context.Context, params *DidOpenTextDocumentParams) error {
|
||||
return s.Conn.Notify(ctx, "textDocument/didOpen", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidChange(ctx context.Context, params *DidChangeTextDocumentParams) error {
|
||||
return s.Conn.Notify(ctx, "textDocument/didChange", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) WillSave(ctx context.Context, params *WillSaveTextDocumentParams) error {
|
||||
return s.Conn.Notify(ctx, "textDocument/willSave", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) WillSaveWaitUntil(ctx context.Context, params *WillSaveTextDocumentParams) ([]TextEdit, error) {
|
||||
var result []TextEdit
|
||||
if err := s.Conn.Call(ctx, "textDocument/willSaveWaitUntil", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidSave(ctx context.Context, params *DidSaveTextDocumentParams) error {
|
||||
return s.Conn.Notify(ctx, "textDocument/didSave", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DidClose(ctx context.Context, params *DidCloseTextDocumentParams) error {
|
||||
return s.Conn.Notify(ctx, "textDocument/didClose", params)
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Completion(ctx context.Context, params *CompletionParams) (*CompletionList, error) {
|
||||
var result CompletionList
|
||||
if err := s.Conn.Call(ctx, "textDocument/completion", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) CompletionResolve(ctx context.Context, params *CompletionItem) (*CompletionItem, error) {
|
||||
var result CompletionItem
|
||||
if err := s.Conn.Call(ctx, "completionItem/resolve", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Hover(ctx context.Context, params *TextDocumentPositionParams) (*Hover, error) {
|
||||
var result Hover
|
||||
if err := s.Conn.Call(ctx, "textDocument/hover", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) SignatureHelp(ctx context.Context, params *TextDocumentPositionParams) (*SignatureHelp, error) {
|
||||
var result SignatureHelp
|
||||
if err := s.Conn.Call(ctx, "textDocument/signatureHelp", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Definition(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
|
||||
var result []Location
|
||||
if err := s.Conn.Call(ctx, "textDocument/definition", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) TypeDefinition(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
|
||||
var result []Location
|
||||
if err := s.Conn.Call(ctx, "textDocument/typeDefinition", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Implementation(ctx context.Context, params *TextDocumentPositionParams) ([]Location, error) {
|
||||
var result []Location
|
||||
if err := s.Conn.Call(ctx, "textDocument/implementation", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) References(ctx context.Context, params *ReferenceParams) ([]Location, error) {
|
||||
var result []Location
|
||||
if err := s.Conn.Call(ctx, "textDocument/references", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DocumentHighlight(ctx context.Context, params *TextDocumentPositionParams) ([]DocumentHighlight, error) {
|
||||
var result []DocumentHighlight
|
||||
if err := s.Conn.Call(ctx, "textDocument/documentHighlight", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DocumentSymbol(ctx context.Context, params *DocumentSymbolParams) ([]DocumentSymbol, error) {
|
||||
var result []DocumentSymbol
|
||||
if err := s.Conn.Call(ctx, "textDocument/documentSymbol", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) CodeAction(ctx context.Context, params *CodeActionParams) ([]CodeAction, error) {
|
||||
var result []CodeAction
|
||||
if err := s.Conn.Call(ctx, "textDocument/codeAction", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) CodeLens(ctx context.Context, params *CodeLensParams) ([]CodeLens, error) {
|
||||
var result []CodeLens
|
||||
if err := s.Conn.Call(ctx, "textDocument/codeLens", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) CodeLensResolve(ctx context.Context, params *CodeLens) (*CodeLens, error) {
|
||||
var result CodeLens
|
||||
if err := s.Conn.Call(ctx, "codeLens/resolve", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DocumentLink(ctx context.Context, params *DocumentLinkParams) ([]DocumentLink, error) {
|
||||
var result []DocumentLink
|
||||
if err := s.Conn.Call(ctx, "textDocument/documentLink", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DocumentLinkResolve(ctx context.Context, params *DocumentLink) (*DocumentLink, error) {
|
||||
var result DocumentLink
|
||||
if err := s.Conn.Call(ctx, "documentLink/resolve", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) DocumentColor(ctx context.Context, params *DocumentColorParams) ([]ColorInformation, error) {
|
||||
var result []ColorInformation
|
||||
if err := s.Conn.Call(ctx, "textDocument/documentColor", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) ColorPresentation(ctx context.Context, params *ColorPresentationParams) ([]ColorPresentation, error) {
|
||||
var result []ColorPresentation
|
||||
if err := s.Conn.Call(ctx, "textDocument/colorPresentation", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Formatting(ctx context.Context, params *DocumentFormattingParams) ([]TextEdit, error) {
|
||||
var result []TextEdit
|
||||
if err := s.Conn.Call(ctx, "textDocument/formatting", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) RangeFormatting(ctx context.Context, params *DocumentRangeFormattingParams) ([]TextEdit, error) {
|
||||
var result []TextEdit
|
||||
if err := s.Conn.Call(ctx, "textDocument/rangeFormatting", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) OnTypeFormatting(ctx context.Context, params *DocumentOnTypeFormattingParams) ([]TextEdit, error) {
|
||||
var result []TextEdit
|
||||
if err := s.Conn.Call(ctx, "textDocument/onTypeFormatting", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) Rename(ctx context.Context, params *RenameParams) ([]WorkspaceEdit, error) {
|
||||
var result []WorkspaceEdit
|
||||
if err := s.Conn.Call(ctx, "textDocument/rename", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *serverDispatcher) FoldingRanges(ctx context.Context, params *FoldingRangeRequestParam) ([]FoldingRange, error) {
|
||||
var result []FoldingRange
|
||||
if err := s.Conn.Call(ctx, "textDocument/foldingRanges", params, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
130
vendor/golang.org/x/tools/internal/lsp/protocol/text.go
generated
vendored
Normal file
130
vendor/golang.org/x/tools/internal/lsp/protocol/text.go
generated
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Text Synchronization" part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
type DidOpenTextDocumentParams struct {
|
||||
/**
|
||||
* The document that was opened.
|
||||
*/
|
||||
TextDocument TextDocumentItem `json:"textDocument"`
|
||||
}
|
||||
|
||||
type DidChangeTextDocumentParams struct {
|
||||
/**
|
||||
* The document that did change. The version number points
|
||||
* to the version after all provided content changes have
|
||||
* been applied.
|
||||
*/
|
||||
TextDocument VersionedTextDocumentIdentifier `json:"textDocument"`
|
||||
|
||||
/**
|
||||
* The actual content changes. The content changes describe single state changes
|
||||
* to the document. So if there are two content changes c1 and c2 for a document
|
||||
* in state S10 then c1 move the document to S11 and c2 to S12.
|
||||
*/
|
||||
ContentChanges []TextDocumentContentChangeEvent `json:"contentChanges"`
|
||||
}
|
||||
|
||||
/**
|
||||
* An event describing a change to a text document. If range and rangeLength are omitted
|
||||
* the new text is considered to be the full content of the document.
|
||||
*/
|
||||
type TextDocumentContentChangeEvent struct {
|
||||
/**
|
||||
* The range of the document that changed.
|
||||
*/
|
||||
Range Range `json:"range,omitempty"`
|
||||
|
||||
/**
|
||||
* The length of the range that got replaced.
|
||||
*/
|
||||
RangeLength float64 `json:"rangeLength,omitempty"`
|
||||
|
||||
/**
|
||||
* The new text of the range/document.
|
||||
*/
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe options to be used when registering for text document change events.
|
||||
*/
|
||||
type TextDocumentChangeRegistrationOptions struct {
|
||||
TextDocumentRegistrationOptions
|
||||
/**
|
||||
* How documents are synced to the server. See TextDocumentSyncKind.Full
|
||||
* and TextDocumentSyncKind.Incremental.
|
||||
*/
|
||||
SyncKind float64 `json:"syncKind"`
|
||||
}
|
||||
|
||||
/**
|
||||
* The parameters send in a will save text document notification.
|
||||
*/
|
||||
type WillSaveTextDocumentParams struct {
|
||||
/**
|
||||
* The document that will be saved.
|
||||
*/
|
||||
TextDocument TextDocumentIdentifier `json:"textDocument"`
|
||||
|
||||
/**
|
||||
* The 'TextDocumentSaveReason'.
|
||||
*/
|
||||
Reason TextDocumentSaveReason `json:"reason"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents reasons why a text document is saved.
|
||||
*/
|
||||
type TextDocumentSaveReason float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* Manually triggered, e.g. by the user pressing save, by starting debugging,
|
||||
* or by an API call.
|
||||
*/
|
||||
Manual TextDocumentSaveReason = 1
|
||||
|
||||
/**
|
||||
* Automatic after a delay.
|
||||
*/
|
||||
AfterDelay TextDocumentSaveReason = 2
|
||||
|
||||
/**
|
||||
* When the editor lost focus.
|
||||
*/
|
||||
FocusOut TextDocumentSaveReason = 3
|
||||
)
|
||||
|
||||
type DidSaveTextDocumentParams struct {
|
||||
/**
|
||||
* The document that was saved.
|
||||
*/
|
||||
TextDocument TextDocumentIdentifier `json:"textDocument"`
|
||||
|
||||
/**
|
||||
* Optional the content when saved. Depends on the includeText value
|
||||
* when the save notification was requested.
|
||||
*/
|
||||
Text string `json:"text,omitempty"`
|
||||
}
|
||||
|
||||
type TextDocumentSaveRegistrationOptions struct {
|
||||
TextDocumentRegistrationOptions
|
||||
/**
|
||||
* The client is supposed to include the content on save.
|
||||
*/
|
||||
IncludeText bool `json:"includeText,omitempty"`
|
||||
}
|
||||
|
||||
type DidCloseTextDocumentParams struct {
|
||||
/**
|
||||
* The document that was closed.
|
||||
*/
|
||||
TextDocument TextDocumentIdentifier `json:"textDocument"`
|
||||
}
|
77
vendor/golang.org/x/tools/internal/lsp/protocol/window.go
generated
vendored
Normal file
77
vendor/golang.org/x/tools/internal/lsp/protocol/window.go
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Window" messages part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
type ShowMessageParams struct {
|
||||
/**
|
||||
* The message type. See {@link MessageType}.
|
||||
*/
|
||||
Type MessageType `json:"type"`
|
||||
|
||||
/**
|
||||
* The actual message.
|
||||
*/
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type MessageType float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* An error message.
|
||||
*/
|
||||
Error MessageType = 1
|
||||
/**
|
||||
* A warning message.
|
||||
*/
|
||||
Warning MessageType = 2
|
||||
/**
|
||||
* An information message.
|
||||
*/
|
||||
Info MessageType = 3
|
||||
/**
|
||||
* A log message.
|
||||
*/
|
||||
Log MessageType = 4
|
||||
)
|
||||
|
||||
type ShowMessageRequestParams struct {
|
||||
/**
|
||||
* The message type. See {@link MessageType}.
|
||||
*/
|
||||
Type MessageType `json:"type"`
|
||||
|
||||
/**
|
||||
* The actual message.
|
||||
*/
|
||||
Message string `json:"message"`
|
||||
|
||||
/**
|
||||
* The message action items to present.
|
||||
*/
|
||||
Actions []MessageActionItem `json:"actions,omitempty"`
|
||||
}
|
||||
|
||||
type MessageActionItem struct {
|
||||
/**
|
||||
* A short title like 'Retry', 'Open Log' etc.
|
||||
*/
|
||||
Title string
|
||||
}
|
||||
|
||||
type LogMessageParams struct {
|
||||
/**
|
||||
* The message type. See {@link MessageType}.
|
||||
*/
|
||||
Type MessageType `json:"type"`
|
||||
|
||||
/**
|
||||
* The actual message.
|
||||
*/
|
||||
Message string `json:"message"`
|
||||
}
|
203
vendor/golang.org/x/tools/internal/lsp/protocol/workspace.go
generated
vendored
Normal file
203
vendor/golang.org/x/tools/internal/lsp/protocol/workspace.go
generated
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This file contains the corresponding structures to the
|
||||
// "Workspace" part of the LSP specification.
|
||||
|
||||
package protocol
|
||||
|
||||
type WorkspaceFolder struct {
|
||||
/**
|
||||
* The associated URI for this workspace folder.
|
||||
*/
|
||||
URI string `json:"uri"`
|
||||
|
||||
/**
|
||||
* The name of the workspace folder. Defaults to the
|
||||
* uri's basename.
|
||||
*/
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type DidChangeWorkspaceFoldersParams struct {
|
||||
/**
|
||||
* The actual workspace folder change event.
|
||||
*/
|
||||
Event WorkspaceFoldersChangeEvent `json:"event"`
|
||||
}
|
||||
|
||||
/**
|
||||
* The workspace folder change event.
|
||||
*/
|
||||
type WorkspaceFoldersChangeEvent struct {
|
||||
/**
|
||||
* The array of added workspace folders
|
||||
*/
|
||||
Added []WorkspaceFolder `json:"added"`
|
||||
|
||||
/**
|
||||
* The array of the removed workspace folders
|
||||
*/
|
||||
Removed []WorkspaceFolder `json:"removed"`
|
||||
}
|
||||
|
||||
type DidChangeConfigurationParams struct {
|
||||
/**
|
||||
* The actual changed settings
|
||||
*/
|
||||
Settings interface{} `json:"settings"`
|
||||
}
|
||||
|
||||
type ConfigurationParams struct {
|
||||
Items []ConfigurationItem `json:"items"`
|
||||
}
|
||||
|
||||
type ConfigurationItem struct {
|
||||
/**
|
||||
* The scope to get the configuration section for.
|
||||
*/
|
||||
ScopeURI string `json:"scopeURI,omitempty"`
|
||||
|
||||
/**
|
||||
* The configuration section asked for.
|
||||
*/
|
||||
Section string `json:"section,omitempty"`
|
||||
}
|
||||
|
||||
type DidChangeWatchedFilesParams struct {
|
||||
/**
|
||||
* The actual file events.
|
||||
*/
|
||||
Changes []FileEvent `json:"changes"`
|
||||
}
|
||||
|
||||
/**
|
||||
* An event describing a file change.
|
||||
*/
|
||||
type FileEvent struct {
|
||||
/**
|
||||
* The file's URI.
|
||||
*/
|
||||
URI DocumentURI `json:"uri"`
|
||||
/**
|
||||
* The change type.
|
||||
*/
|
||||
Type float64 `json:"type"`
|
||||
}
|
||||
|
||||
/**
|
||||
* The file event type.
|
||||
*/
|
||||
type FileChangeType float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* The file got created.
|
||||
*/
|
||||
Created FileChangeType = 1
|
||||
/**
|
||||
* The file got changed.
|
||||
*/
|
||||
Changed FileChangeType = 2
|
||||
/**
|
||||
* The file got deleted.
|
||||
*/
|
||||
Deleted FileChangeType = 3
|
||||
)
|
||||
|
||||
/**
|
||||
* Describe options to be used when registering for text document change events.
|
||||
*/
|
||||
type DidChangeWatchedFilesRegistrationOptions struct {
|
||||
/**
|
||||
* The watchers to register.
|
||||
*/
|
||||
Watchers []FileSystemWatcher `json:"watchers"`
|
||||
}
|
||||
|
||||
type FileSystemWatcher struct {
|
||||
/**
|
||||
* The glob pattern to watch
|
||||
*/
|
||||
GlobPattern string `json:"globPattern"`
|
||||
|
||||
/**
|
||||
* The kind of events of interest. If omitted it defaults
|
||||
* to WatchKind.Create | WatchKind.Change | WatchKind.Delete
|
||||
* which is 7.
|
||||
*/
|
||||
Kind float64 `json:"kind,omitempty"`
|
||||
}
|
||||
|
||||
type WatchKind float64
|
||||
|
||||
const (
|
||||
/**
|
||||
* Interested in create events.
|
||||
*/
|
||||
Create WatchKind = 1
|
||||
|
||||
/**
|
||||
* Interested in change events
|
||||
*/
|
||||
Change WatchKind = 2
|
||||
|
||||
/**
|
||||
* Interested in delete events
|
||||
*/
|
||||
Delete WatchKind = 4
|
||||
)
|
||||
|
||||
/**
|
||||
* The parameters of a Workspace Symbol Request.
|
||||
*/
|
||||
type WorkspaceSymbolParams struct {
|
||||
/**
|
||||
* A non-empty query string
|
||||
*/
|
||||
Query string `json:"query"`
|
||||
}
|
||||
|
||||
type ExecuteCommandParams struct {
|
||||
|
||||
/**
|
||||
* The identifier of the actual command handler.
|
||||
*/
|
||||
Command string `json:"command"`
|
||||
/**
|
||||
* Arguments that the command should be invoked with.
|
||||
*/
|
||||
Arguments []interface{} `json:"arguments,omitempty"`
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute command registration options.
|
||||
*/
|
||||
type ExecuteCommandRegistrationOptions struct {
|
||||
/**
|
||||
* The commands to be executed on the server
|
||||
*/
|
||||
Commands []string `json:"commands"`
|
||||
}
|
||||
|
||||
type ApplyWorkspaceEditParams struct {
|
||||
/**
|
||||
* An optional label of the workspace edit. This label is
|
||||
* presented in the user interface for example on an undo
|
||||
* stack to undo the workspace edit.
|
||||
*/
|
||||
Label string `json:"label,omitempty"`
|
||||
|
||||
/**
|
||||
* The edits to apply.
|
||||
*/
|
||||
Edit WorkspaceEdit `json:"edit"`
|
||||
}
|
||||
|
||||
type ApplyWorkspaceEditResponse struct {
|
||||
/**
|
||||
* Indicates whether the edit was applied or not.
|
||||
*/
|
||||
Applied bool `json:"applied"`
|
||||
}
|
315
vendor/golang.org/x/tools/internal/lsp/server.go
generated
vendored
Normal file
315
vendor/golang.org/x/tools/internal/lsp/server.go
generated
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go/token"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/internal/jsonrpc2"
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
// RunServer starts an LSP server on the supplied stream, and waits until the
|
||||
// stream is closed.
|
||||
func RunServer(ctx context.Context, stream jsonrpc2.Stream, opts ...interface{}) error {
|
||||
s := &server{}
|
||||
conn, client := protocol.RunServer(ctx, stream, s, opts...)
|
||||
s.client = client
|
||||
return conn.Wait(ctx)
|
||||
}
|
||||
|
||||
type server struct {
|
||||
client protocol.Client
|
||||
|
||||
initializedMu sync.Mutex
|
||||
initialized bool // set once the server has received "initialize" request
|
||||
|
||||
view *source.View
|
||||
}
|
||||
|
||||
func (s *server) Initialize(ctx context.Context, params *protocol.InitializeParams) (*protocol.InitializeResult, error) {
|
||||
s.initializedMu.Lock()
|
||||
defer s.initializedMu.Unlock()
|
||||
if s.initialized {
|
||||
return nil, jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server already initialized")
|
||||
}
|
||||
s.view = source.NewView()
|
||||
s.initialized = true
|
||||
return &protocol.InitializeResult{
|
||||
Capabilities: protocol.ServerCapabilities{
|
||||
CompletionProvider: protocol.CompletionOptions{
|
||||
TriggerCharacters: []string{"."},
|
||||
},
|
||||
DefinitionProvider: true,
|
||||
DocumentFormattingProvider: true,
|
||||
DocumentRangeFormattingProvider: true,
|
||||
SignatureHelpProvider: protocol.SignatureHelpOptions{
|
||||
TriggerCharacters: []string{"("},
|
||||
},
|
||||
TextDocumentSync: protocol.TextDocumentSyncOptions{
|
||||
Change: float64(protocol.Full), // full contents of file sent on each update
|
||||
OpenClose: true,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) Initialized(context.Context, *protocol.InitializedParams) error {
|
||||
return nil // ignore
|
||||
}
|
||||
|
||||
func (s *server) Shutdown(context.Context) error {
|
||||
s.initializedMu.Lock()
|
||||
defer s.initializedMu.Unlock()
|
||||
if !s.initialized {
|
||||
return jsonrpc2.NewErrorf(jsonrpc2.CodeInvalidRequest, "server not initialized")
|
||||
}
|
||||
s.initialized = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) Exit(ctx context.Context) error {
|
||||
if s.initialized {
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) DidChangeWorkspaceFolders(context.Context, *protocol.DidChangeWorkspaceFoldersParams) error {
|
||||
return notImplemented("DidChangeWorkspaceFolders")
|
||||
}
|
||||
|
||||
func (s *server) DidChangeConfiguration(context.Context, *protocol.DidChangeConfigurationParams) error {
|
||||
return notImplemented("DidChangeConfiguration")
|
||||
}
|
||||
|
||||
func (s *server) DidChangeWatchedFiles(context.Context, *protocol.DidChangeWatchedFilesParams) error {
|
||||
return notImplemented("DidChangeWatchedFiles")
|
||||
}
|
||||
|
||||
func (s *server) Symbols(context.Context, *protocol.WorkspaceSymbolParams) ([]protocol.SymbolInformation, error) {
|
||||
return nil, notImplemented("Symbols")
|
||||
}
|
||||
|
||||
func (s *server) ExecuteCommand(context.Context, *protocol.ExecuteCommandParams) (interface{}, error) {
|
||||
return nil, notImplemented("ExecuteCommand")
|
||||
}
|
||||
|
||||
func (s *server) DidOpen(ctx context.Context, params *protocol.DidOpenTextDocumentParams) error {
|
||||
s.cacheAndDiagnoseFile(ctx, params.TextDocument.URI, params.TextDocument.Text)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) DidChange(ctx context.Context, params *protocol.DidChangeTextDocumentParams) error {
|
||||
if len(params.ContentChanges) < 1 {
|
||||
return jsonrpc2.NewErrorf(jsonrpc2.CodeInternalError, "no content changes provided")
|
||||
}
|
||||
// We expect the full content of file, i.e. a single change with no range.
|
||||
if change := params.ContentChanges[0]; change.RangeLength == 0 {
|
||||
s.cacheAndDiagnoseFile(ctx, params.TextDocument.URI, change.Text)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) cacheAndDiagnoseFile(ctx context.Context, uri protocol.DocumentURI, text string) {
|
||||
f := s.view.GetFile(source.URI(uri))
|
||||
f.SetContent([]byte(text))
|
||||
go func() {
|
||||
f := s.view.GetFile(source.URI(uri))
|
||||
reports, err := source.Diagnostics(ctx, s.view, f)
|
||||
if err != nil {
|
||||
return // handle error?
|
||||
}
|
||||
for filename, diagnostics := range reports {
|
||||
s.client.PublishDiagnostics(ctx, &protocol.PublishDiagnosticsParams{
|
||||
URI: protocol.DocumentURI(source.ToURI(filename)),
|
||||
Diagnostics: toProtocolDiagnostics(s.view, diagnostics),
|
||||
})
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (s *server) WillSave(context.Context, *protocol.WillSaveTextDocumentParams) error {
|
||||
return notImplemented("WillSave")
|
||||
}
|
||||
|
||||
func (s *server) WillSaveWaitUntil(context.Context, *protocol.WillSaveTextDocumentParams) ([]protocol.TextEdit, error) {
|
||||
return nil, notImplemented("WillSaveWaitUntil")
|
||||
}
|
||||
|
||||
func (s *server) DidSave(context.Context, *protocol.DidSaveTextDocumentParams) error {
|
||||
// TODO(rstambler): Should we clear the cache here?
|
||||
return nil // ignore
|
||||
}
|
||||
|
||||
func (s *server) DidClose(ctx context.Context, params *protocol.DidCloseTextDocumentParams) error {
|
||||
s.view.GetFile(source.URI(params.TextDocument.URI)).SetContent(nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) Completion(ctx context.Context, params *protocol.CompletionParams) (*protocol.CompletionList, error) {
|
||||
f := s.view.GetFile(source.URI(params.TextDocument.URI))
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pos := fromProtocolPosition(tok, params.Position)
|
||||
items, err := source.Completion(ctx, f, pos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &protocol.CompletionList{
|
||||
IsIncomplete: false,
|
||||
Items: toProtocolCompletionItems(items),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *server) CompletionResolve(context.Context, *protocol.CompletionItem) (*protocol.CompletionItem, error) {
|
||||
return nil, notImplemented("CompletionResolve")
|
||||
}
|
||||
|
||||
func (s *server) Hover(context.Context, *protocol.TextDocumentPositionParams) (*protocol.Hover, error) {
|
||||
return nil, notImplemented("Hover")
|
||||
}
|
||||
|
||||
func (s *server) SignatureHelp(ctx context.Context, params *protocol.TextDocumentPositionParams) (*protocol.SignatureHelp, error) {
|
||||
f := s.view.GetFile(source.URI(params.TextDocument.URI))
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pos := fromProtocolPosition(tok, params.Position)
|
||||
info, err := source.SignatureHelp(ctx, f, pos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toProtocolSignatureHelp(info), nil
|
||||
}
|
||||
|
||||
func (s *server) Definition(ctx context.Context, params *protocol.TextDocumentPositionParams) ([]protocol.Location, error) {
|
||||
f := s.view.GetFile(source.URI(params.TextDocument.URI))
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pos := fromProtocolPosition(tok, params.Position)
|
||||
r, err := source.Definition(ctx, f, pos)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []protocol.Location{toProtocolLocation(s.view, r)}, nil
|
||||
}
|
||||
|
||||
func (s *server) TypeDefinition(context.Context, *protocol.TextDocumentPositionParams) ([]protocol.Location, error) {
|
||||
return nil, notImplemented("TypeDefinition")
|
||||
}
|
||||
|
||||
func (s *server) Implementation(context.Context, *protocol.TextDocumentPositionParams) ([]protocol.Location, error) {
|
||||
return nil, notImplemented("Implementation")
|
||||
}
|
||||
|
||||
func (s *server) References(context.Context, *protocol.ReferenceParams) ([]protocol.Location, error) {
|
||||
return nil, notImplemented("References")
|
||||
}
|
||||
|
||||
func (s *server) DocumentHighlight(context.Context, *protocol.TextDocumentPositionParams) ([]protocol.DocumentHighlight, error) {
|
||||
return nil, notImplemented("DocumentHighlight")
|
||||
}
|
||||
|
||||
func (s *server) DocumentSymbol(context.Context, *protocol.DocumentSymbolParams) ([]protocol.DocumentSymbol, error) {
|
||||
return nil, notImplemented("DocumentSymbol")
|
||||
}
|
||||
|
||||
func (s *server) CodeAction(context.Context, *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
|
||||
return nil, notImplemented("CodeAction")
|
||||
}
|
||||
|
||||
func (s *server) CodeLens(context.Context, *protocol.CodeLensParams) ([]protocol.CodeLens, error) {
|
||||
return nil, nil // ignore
|
||||
}
|
||||
|
||||
func (s *server) CodeLensResolve(context.Context, *protocol.CodeLens) (*protocol.CodeLens, error) {
|
||||
return nil, notImplemented("CodeLensResolve")
|
||||
}
|
||||
|
||||
func (s *server) DocumentLink(context.Context, *protocol.DocumentLinkParams) ([]protocol.DocumentLink, error) {
|
||||
return nil, nil // ignore
|
||||
}
|
||||
|
||||
func (s *server) DocumentLinkResolve(context.Context, *protocol.DocumentLink) (*protocol.DocumentLink, error) {
|
||||
return nil, notImplemented("DocumentLinkResolve")
|
||||
}
|
||||
|
||||
func (s *server) DocumentColor(context.Context, *protocol.DocumentColorParams) ([]protocol.ColorInformation, error) {
|
||||
return nil, notImplemented("DocumentColor")
|
||||
}
|
||||
|
||||
func (s *server) ColorPresentation(context.Context, *protocol.ColorPresentationParams) ([]protocol.ColorPresentation, error) {
|
||||
return nil, notImplemented("ColorPresentation")
|
||||
}
|
||||
|
||||
func (s *server) Formatting(ctx context.Context, params *protocol.DocumentFormattingParams) ([]protocol.TextEdit, error) {
|
||||
return formatRange(ctx, s.view, params.TextDocument.URI, nil)
|
||||
}
|
||||
|
||||
func (s *server) RangeFormatting(ctx context.Context, params *protocol.DocumentRangeFormattingParams) ([]protocol.TextEdit, error) {
|
||||
return formatRange(ctx, s.view, params.TextDocument.URI, ¶ms.Range)
|
||||
}
|
||||
|
||||
// formatRange formats a document with a given range.
|
||||
func formatRange(ctx context.Context, v *source.View, uri protocol.DocumentURI, rng *protocol.Range) ([]protocol.TextEdit, error) {
|
||||
f := v.GetFile(source.URI(uri))
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var r source.Range
|
||||
if rng == nil {
|
||||
r.Start = tok.Pos(0)
|
||||
r.End = tok.Pos(tok.Size())
|
||||
} else {
|
||||
r = fromProtocolRange(tok, *rng)
|
||||
}
|
||||
edits, err := source.Format(ctx, f, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return toProtocolEdits(tok, edits), nil
|
||||
}
|
||||
|
||||
func toProtocolEdits(f *token.File, edits []source.TextEdit) []protocol.TextEdit {
|
||||
if edits == nil {
|
||||
return nil
|
||||
}
|
||||
result := make([]protocol.TextEdit, len(edits))
|
||||
for i, edit := range edits {
|
||||
result[i] = protocol.TextEdit{
|
||||
Range: toProtocolRange(f, edit.Range),
|
||||
NewText: edit.NewText,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (s *server) OnTypeFormatting(context.Context, *protocol.DocumentOnTypeFormattingParams) ([]protocol.TextEdit, error) {
|
||||
return nil, notImplemented("OnTypeFormatting")
|
||||
}
|
||||
|
||||
func (s *server) Rename(context.Context, *protocol.RenameParams) ([]protocol.WorkspaceEdit, error) {
|
||||
return nil, notImplemented("Rename")
|
||||
}
|
||||
|
||||
func (s *server) FoldingRanges(context.Context, *protocol.FoldingRangeRequestParam) ([]protocol.FoldingRange, error) {
|
||||
return nil, notImplemented("FoldingRanges")
|
||||
}
|
||||
|
||||
func notImplemented(method string) *jsonrpc2.Error {
|
||||
return jsonrpc2.NewErrorf(jsonrpc2.CodeMethodNotFound, "method %q not yet implemented", method)
|
||||
}
|
33
vendor/golang.org/x/tools/internal/lsp/signature_help.go
generated
vendored
Normal file
33
vendor/golang.org/x/tools/internal/lsp/signature_help.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright 2018 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 lsp
|
||||
|
||||
import (
|
||||
"golang.org/x/tools/internal/lsp/protocol"
|
||||
"golang.org/x/tools/internal/lsp/source"
|
||||
)
|
||||
|
||||
func toProtocolSignatureHelp(info *source.SignatureInformation) *protocol.SignatureHelp {
|
||||
return &protocol.SignatureHelp{
|
||||
ActiveParameter: float64(info.ActiveParameter),
|
||||
ActiveSignature: 0, // there is only ever one possible signature
|
||||
Signatures: []protocol.SignatureInformation{
|
||||
{
|
||||
Label: info.Label,
|
||||
Parameters: toProtocolParameterInformation(info.Parameters),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func toProtocolParameterInformation(info []source.ParameterInformation) []protocol.ParameterInformation {
|
||||
var result []protocol.ParameterInformation
|
||||
for _, p := range info {
|
||||
result = append(result, protocol.ParameterInformation{
|
||||
Label: p.Label,
|
||||
})
|
||||
}
|
||||
return result
|
||||
}
|
734
vendor/golang.org/x/tools/internal/lsp/source/completion.go
generated
vendored
Normal file
734
vendor/golang.org/x/tools/internal/lsp/source/completion.go
generated
vendored
Normal file
@@ -0,0 +1,734 @@
|
||||
package source
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
type CompletionItem struct {
|
||||
Label, Detail string
|
||||
Kind CompletionItemKind
|
||||
Score int
|
||||
}
|
||||
|
||||
type CompletionItemKind int
|
||||
|
||||
const (
|
||||
Unknown CompletionItemKind = iota
|
||||
InterfaceCompletionItem
|
||||
StructCompletionItem
|
||||
TypeCompletionItem
|
||||
ConstantCompletionItem
|
||||
FieldCompletionItem
|
||||
ParameterCompletionItem
|
||||
VariableCompletionItem
|
||||
FunctionCompletionItem
|
||||
MethodCompletionItem
|
||||
PackageCompletionItem
|
||||
)
|
||||
|
||||
func Completion(ctx context.Context, f *File, pos token.Pos) ([]CompletionItem, error) {
|
||||
file, err := f.GetAST()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkg, err := f.GetPackage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items, _, err := completions(file, pos, pkg.Fset, pkg.Types, pkg.TypesInfo)
|
||||
return items, err
|
||||
}
|
||||
|
||||
type finder func(types.Object, float64, []CompletionItem) []CompletionItem
|
||||
|
||||
// completions returns the map of possible candidates for completion, given a
|
||||
// position, a file AST, and type information. The prefix is computed based on
|
||||
// the preceding identifier and can be used by the client to score the quality
|
||||
// of the completion. For instance, some clients may tolerate imperfect matches
|
||||
// as valid completion results, since users may make typos.
|
||||
func completions(file *ast.File, pos token.Pos, fset *token.FileSet, pkg *types.Package, info *types.Info) (items []CompletionItem, prefix string, err error) {
|
||||
path, _ := astutil.PathEnclosingInterval(file, pos, pos)
|
||||
if path == nil {
|
||||
return nil, "", fmt.Errorf("cannot find node enclosing position")
|
||||
}
|
||||
// If the position is not an identifier but immediately follows
|
||||
// an identifier or selector period (as is common when
|
||||
// requesting a completion), use the path to the preceding node.
|
||||
if _, ok := path[0].(*ast.Ident); !ok {
|
||||
if p, _ := astutil.PathEnclosingInterval(file, pos-1, pos-1); p != nil {
|
||||
switch p[0].(type) {
|
||||
case *ast.Ident, *ast.SelectorExpr:
|
||||
path = p // use preceding ident/selector
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save certain facts about the query position, including the expected type
|
||||
// of the completion result, the signature of the function enclosing the
|
||||
// position.
|
||||
typ := expectedType(path, pos, info)
|
||||
sig := enclosingFunction(path, pos, info)
|
||||
pkgStringer := qualifier(file, pkg, info)
|
||||
|
||||
seen := make(map[types.Object]bool)
|
||||
|
||||
// found adds a candidate completion.
|
||||
// Only the first candidate of a given name is considered.
|
||||
found := func(obj types.Object, weight float64, items []CompletionItem) []CompletionItem {
|
||||
if obj.Pkg() != nil && obj.Pkg() != pkg && !obj.Exported() {
|
||||
return items // inaccessible
|
||||
}
|
||||
if !seen[obj] {
|
||||
seen[obj] = true
|
||||
if typ != nil && matchingTypes(typ, obj.Type()) {
|
||||
weight *= 10
|
||||
}
|
||||
if !strings.HasPrefix(obj.Name(), prefix) {
|
||||
return items
|
||||
}
|
||||
item := formatCompletion(obj, pkgStringer, weight, func(v *types.Var) bool {
|
||||
return isParameter(sig, v)
|
||||
})
|
||||
items = append(items, item)
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
// The position is within a composite literal.
|
||||
if items, ok := complit(path, pos, pkg, info, found); ok {
|
||||
return items, "", nil
|
||||
}
|
||||
switch n := path[0].(type) {
|
||||
case *ast.Ident:
|
||||
// Set the filter prefix.
|
||||
prefix = n.Name[:pos-n.Pos()]
|
||||
|
||||
// Is this the Sel part of a selector?
|
||||
if sel, ok := path[1].(*ast.SelectorExpr); ok && sel.Sel == n {
|
||||
return selector(sel, info, found)
|
||||
}
|
||||
// reject defining identifiers
|
||||
if obj, ok := info.Defs[n]; ok {
|
||||
if v, ok := obj.(*types.Var); ok && v.IsField() {
|
||||
// An anonymous field is also a reference to a type.
|
||||
} else {
|
||||
of := ""
|
||||
if obj != nil {
|
||||
qual := types.RelativeTo(pkg)
|
||||
of += ", of " + types.ObjectString(obj, qual)
|
||||
}
|
||||
return nil, "", fmt.Errorf("this is a definition%s", of)
|
||||
}
|
||||
}
|
||||
|
||||
items = append(items, lexical(path, pos, pkg, info, found)...)
|
||||
|
||||
// The function name hasn't been typed yet, but the parens are there:
|
||||
// recv.‸(arg)
|
||||
case *ast.TypeAssertExpr:
|
||||
// Create a fake selector expression.
|
||||
return selector(&ast.SelectorExpr{X: n.X}, info, found)
|
||||
|
||||
case *ast.SelectorExpr:
|
||||
return selector(n, info, found)
|
||||
|
||||
default:
|
||||
// fallback to lexical completions
|
||||
return lexical(path, pos, pkg, info, found), "", nil
|
||||
}
|
||||
|
||||
return items, prefix, nil
|
||||
}
|
||||
|
||||
// selector finds completions for
|
||||
// the specified selector expression.
|
||||
// TODO(rstambler): Set the prefix filter correctly for selectors.
|
||||
func selector(sel *ast.SelectorExpr, info *types.Info, found finder) (items []CompletionItem, prefix string, err error) {
|
||||
// Is sel a qualified identifier?
|
||||
if id, ok := sel.X.(*ast.Ident); ok {
|
||||
if pkgname, ok := info.Uses[id].(*types.PkgName); ok {
|
||||
// Enumerate package members.
|
||||
// TODO(adonovan): can Imported() be nil?
|
||||
scope := pkgname.Imported().Scope()
|
||||
// TODO testcase: bad import
|
||||
for _, name := range scope.Names() {
|
||||
items = found(scope.Lookup(name), 1, items)
|
||||
}
|
||||
return items, prefix, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Inv: sel is a true selector.
|
||||
tv, ok := info.Types[sel.X]
|
||||
if !ok {
|
||||
return nil, "", fmt.Errorf("cannot resolve %s", sel.X)
|
||||
}
|
||||
|
||||
// methods of T
|
||||
mset := types.NewMethodSet(tv.Type)
|
||||
for i := 0; i < mset.Len(); i++ {
|
||||
items = found(mset.At(i).Obj(), 1, items)
|
||||
}
|
||||
|
||||
// methods of *T
|
||||
if tv.Addressable() && !types.IsInterface(tv.Type) && !isPointer(tv.Type) {
|
||||
mset := types.NewMethodSet(types.NewPointer(tv.Type))
|
||||
for i := 0; i < mset.Len(); i++ {
|
||||
items = found(mset.At(i).Obj(), 1, items)
|
||||
}
|
||||
}
|
||||
|
||||
// fields of T
|
||||
for _, f := range fieldSelections(tv.Type) {
|
||||
items = found(f, 1, items)
|
||||
}
|
||||
|
||||
return items, prefix, nil
|
||||
}
|
||||
|
||||
// lexical finds completions in the lexical environment.
|
||||
func lexical(path []ast.Node, pos token.Pos, pkg *types.Package, info *types.Info, found finder) (items []CompletionItem) {
|
||||
var scopes []*types.Scope // scopes[i], where i<len(path), is the possibly nil Scope of path[i].
|
||||
for _, n := range path {
|
||||
switch node := n.(type) {
|
||||
case *ast.FuncDecl:
|
||||
n = node.Type
|
||||
case *ast.FuncLit:
|
||||
n = node.Type
|
||||
}
|
||||
scopes = append(scopes, info.Scopes[n])
|
||||
}
|
||||
scopes = append(scopes, pkg.Scope())
|
||||
|
||||
// Process scopes innermost first.
|
||||
for i, scope := range scopes {
|
||||
if scope == nil {
|
||||
continue
|
||||
}
|
||||
for _, name := range scope.Names() {
|
||||
declScope, obj := scope.LookupParent(name, pos)
|
||||
if declScope != scope {
|
||||
continue // Name was declared in some enclosing scope, or not at all.
|
||||
}
|
||||
// If obj's type is invalid, find the AST node that defines the lexical block
|
||||
// containing the declaration of obj. Don't resolve types for packages.
|
||||
if _, ok := obj.(*types.PkgName); !ok && obj.Type() == types.Typ[types.Invalid] {
|
||||
// Match the scope to its ast.Node. If the scope is the package scope,
|
||||
// use the *ast.File as the starting node.
|
||||
var node ast.Node
|
||||
if i < len(path) {
|
||||
node = path[i]
|
||||
} else if i == len(path) { // use the *ast.File for package scope
|
||||
node = path[i-1]
|
||||
}
|
||||
if node != nil {
|
||||
if resolved := resolveInvalid(obj, node, info); resolved != nil {
|
||||
obj = resolved
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
score := 1.0
|
||||
// Rank builtins significantly lower than other results.
|
||||
if scope == types.Universe {
|
||||
score *= 0.1
|
||||
}
|
||||
items = found(obj, score, items)
|
||||
}
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
// complit finds completions for field names inside a composite literal.
|
||||
// It reports whether the node was handled as part of a composite literal.
|
||||
func complit(path []ast.Node, pos token.Pos, pkg *types.Package, info *types.Info, found finder) (items []CompletionItem, ok bool) {
|
||||
var lit *ast.CompositeLit
|
||||
|
||||
// First, determine if the pos is within a composite literal.
|
||||
switch n := path[0].(type) {
|
||||
case *ast.CompositeLit:
|
||||
// The enclosing node will be a composite literal if the user has just
|
||||
// opened the curly brace (e.g. &x{<>) or the completion request is triggered
|
||||
// from an already completed composite literal expression (e.g. &x{foo: 1, <>})
|
||||
//
|
||||
// If the cursor position is within a key-value expression inside the composite
|
||||
// literal, we try to determine if it is before or after the colon. If it is before
|
||||
// the colon, we return field completions. If the cursor does not belong to any
|
||||
// expression within the composite literal, we show composite literal completions.
|
||||
var expr ast.Expr
|
||||
for _, e := range n.Elts {
|
||||
if e.Pos() <= pos && pos < e.End() {
|
||||
expr = e
|
||||
break
|
||||
}
|
||||
}
|
||||
lit = n
|
||||
// If the position belongs to a key-value expression and is after the colon,
|
||||
// don't show composite literal completions.
|
||||
if kv, ok := expr.(*ast.KeyValueExpr); ok && pos > kv.Colon {
|
||||
lit = nil
|
||||
}
|
||||
case *ast.KeyValueExpr:
|
||||
// If the enclosing node is a key-value expression (e.g. &x{foo: <>}),
|
||||
// we show composite literal completions if the cursor position is before the colon.
|
||||
if len(path) > 1 && pos < n.Colon {
|
||||
if l, ok := path[1].(*ast.CompositeLit); ok {
|
||||
lit = l
|
||||
}
|
||||
}
|
||||
case *ast.Ident:
|
||||
// If the enclosing node is an identifier, it can either be an identifier that is
|
||||
// part of a composite literal (e.g. &x{fo<>}), or it can be an identifier that is
|
||||
// part of a key-value expression, which is part of a composite literal (e.g. &x{foo: ba<>).
|
||||
// We handle both of these cases, showing composite literal completions only if
|
||||
// the cursor position for the key-value expression is before the colon.
|
||||
if len(path) > 1 {
|
||||
if l, ok := path[1].(*ast.CompositeLit); ok {
|
||||
lit = l
|
||||
} else if len(path) > 2 {
|
||||
if l, ok := path[2].(*ast.CompositeLit); ok {
|
||||
// Confirm that cursor position is inside curly braces.
|
||||
if l.Lbrace <= pos && pos <= l.Rbrace {
|
||||
lit = l
|
||||
if kv, ok := path[1].(*ast.KeyValueExpr); ok {
|
||||
if pos > kv.Colon {
|
||||
lit = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// We are not in a composite literal.
|
||||
if lit == nil {
|
||||
return nil, false
|
||||
}
|
||||
// Mark fields of the composite literal that have already been set,
|
||||
// except for the current field.
|
||||
hasKeys := false // true if the composite literal already has key-value pairs
|
||||
addedFields := make(map[*types.Var]bool)
|
||||
for _, el := range lit.Elts {
|
||||
if kv, ok := el.(*ast.KeyValueExpr); ok {
|
||||
hasKeys = true
|
||||
if kv.Pos() <= pos && pos <= kv.End() {
|
||||
continue
|
||||
}
|
||||
if key, ok := kv.Key.(*ast.Ident); ok {
|
||||
if used, ok := info.Uses[key]; ok {
|
||||
if usedVar, ok := used.(*types.Var); ok {
|
||||
addedFields[usedVar] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the underlying type of the composite literal is a struct,
|
||||
// collect completions for the fields of this struct.
|
||||
if tv, ok := info.Types[lit]; ok {
|
||||
var structPkg *types.Package // package containing the struct type declaration
|
||||
if s, ok := tv.Type.Underlying().(*types.Struct); ok {
|
||||
for i := 0; i < s.NumFields(); i++ {
|
||||
field := s.Field(i)
|
||||
if i == 0 {
|
||||
structPkg = field.Pkg()
|
||||
}
|
||||
if !addedFields[field] {
|
||||
items = found(field, 10, items)
|
||||
}
|
||||
}
|
||||
// Add lexical completions if the user hasn't typed a key value expression
|
||||
// and if the struct fields are defined in the same package as the user is in.
|
||||
if !hasKeys && structPkg == pkg {
|
||||
items = append(items, lexical(path, pos, pkg, info, found)...)
|
||||
}
|
||||
return items, true
|
||||
}
|
||||
}
|
||||
return items, false
|
||||
}
|
||||
|
||||
// formatCompletion creates a completion item for a given types.Object.
|
||||
func formatCompletion(obj types.Object, qualifier types.Qualifier, score float64, isParam func(*types.Var) bool) CompletionItem {
|
||||
label := obj.Name()
|
||||
detail := types.TypeString(obj.Type(), qualifier)
|
||||
var kind CompletionItemKind
|
||||
|
||||
switch o := obj.(type) {
|
||||
case *types.TypeName:
|
||||
detail, kind = formatType(o.Type(), qualifier)
|
||||
if obj.Parent() == types.Universe {
|
||||
detail = ""
|
||||
}
|
||||
case *types.Const:
|
||||
if obj.Parent() == types.Universe {
|
||||
detail = ""
|
||||
} else {
|
||||
val := o.Val().ExactString()
|
||||
if !strings.Contains(val, "\\n") { // skip any multiline constants
|
||||
label += " = " + o.Val().ExactString()
|
||||
}
|
||||
}
|
||||
kind = ConstantCompletionItem
|
||||
case *types.Var:
|
||||
if _, ok := o.Type().(*types.Struct); ok {
|
||||
detail = "struct{...}" // for anonymous structs
|
||||
}
|
||||
if o.IsField() {
|
||||
kind = FieldCompletionItem
|
||||
} else if isParam(o) {
|
||||
kind = ParameterCompletionItem
|
||||
} else {
|
||||
kind = VariableCompletionItem
|
||||
}
|
||||
case *types.Func:
|
||||
if sig, ok := o.Type().(*types.Signature); ok {
|
||||
label += formatParams(sig.Params(), sig.Variadic(), qualifier)
|
||||
detail = strings.Trim(types.TypeString(sig.Results(), qualifier), "()")
|
||||
kind = FunctionCompletionItem
|
||||
if sig.Recv() != nil {
|
||||
kind = MethodCompletionItem
|
||||
}
|
||||
}
|
||||
case *types.Builtin:
|
||||
item, ok := builtinDetails[obj.Name()]
|
||||
if !ok {
|
||||
break
|
||||
}
|
||||
label, detail = item.label, item.detail
|
||||
kind = FunctionCompletionItem
|
||||
case *types.PkgName:
|
||||
kind = PackageCompletionItem
|
||||
detail = fmt.Sprintf("\"%s\"", o.Imported().Path())
|
||||
case *types.Nil:
|
||||
kind = VariableCompletionItem
|
||||
detail = ""
|
||||
}
|
||||
detail = strings.TrimPrefix(detail, "untyped ")
|
||||
|
||||
return CompletionItem{
|
||||
Label: label,
|
||||
Detail: detail,
|
||||
Kind: kind,
|
||||
}
|
||||
}
|
||||
|
||||
// formatType returns the detail and kind for an object of type *types.TypeName.
|
||||
func formatType(typ types.Type, qualifier types.Qualifier) (detail string, kind CompletionItemKind) {
|
||||
if types.IsInterface(typ) {
|
||||
detail = "interface{...}"
|
||||
kind = InterfaceCompletionItem
|
||||
} else if _, ok := typ.(*types.Struct); ok {
|
||||
detail = "struct{...}"
|
||||
kind = StructCompletionItem
|
||||
} else if typ != typ.Underlying() {
|
||||
detail, kind = formatType(typ.Underlying(), qualifier)
|
||||
} else {
|
||||
detail = types.TypeString(typ, qualifier)
|
||||
kind = TypeCompletionItem
|
||||
}
|
||||
return detail, kind
|
||||
}
|
||||
|
||||
// formatParams correctly format the parameters of a function.
|
||||
func formatParams(t *types.Tuple, variadic bool, qualifier types.Qualifier) string {
|
||||
var b bytes.Buffer
|
||||
b.WriteByte('(')
|
||||
for i := 0; i < t.Len(); i++ {
|
||||
if i > 0 {
|
||||
b.WriteString(", ")
|
||||
}
|
||||
el := t.At(i)
|
||||
typ := types.TypeString(el.Type(), qualifier)
|
||||
// Handle a variadic parameter (can only be the final parameter).
|
||||
if variadic && i == t.Len()-1 {
|
||||
typ = strings.Replace(typ, "[]", "...", 1)
|
||||
}
|
||||
fmt.Fprintf(&b, "%v %v", el.Name(), typ)
|
||||
}
|
||||
b.WriteByte(')')
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// isParameter returns true if the given *types.Var is a parameter to the given
|
||||
// *types.Signature.
|
||||
func isParameter(sig *types.Signature, v *types.Var) bool {
|
||||
if sig == nil {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < sig.Params().Len(); i++ {
|
||||
if sig.Params().At(i) == v {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// qualifier returns a function that appropriately formats a types.PkgName
|
||||
// appearing in a *ast.File.
|
||||
func qualifier(f *ast.File, pkg *types.Package, info *types.Info) types.Qualifier {
|
||||
// Construct mapping of import paths to their defined or implicit names.
|
||||
imports := make(map[*types.Package]string)
|
||||
for _, imp := range f.Imports {
|
||||
var obj types.Object
|
||||
if imp.Name != nil {
|
||||
obj = info.Defs[imp.Name]
|
||||
} else {
|
||||
obj = info.Implicits[imp]
|
||||
}
|
||||
if pkgname, ok := obj.(*types.PkgName); ok {
|
||||
imports[pkgname.Imported()] = pkgname.Name()
|
||||
}
|
||||
}
|
||||
// Define qualifier to replace full package paths with names of the imports.
|
||||
return func(pkg *types.Package) string {
|
||||
if pkg == pkg {
|
||||
return ""
|
||||
}
|
||||
if name, ok := imports[pkg]; ok {
|
||||
return name
|
||||
}
|
||||
return pkg.Name()
|
||||
}
|
||||
}
|
||||
|
||||
// enclosingFunction returns the signature of the function enclosing the given
|
||||
// position.
|
||||
func enclosingFunction(path []ast.Node, pos token.Pos, info *types.Info) *types.Signature {
|
||||
for _, node := range path {
|
||||
switch t := node.(type) {
|
||||
case *ast.FuncDecl:
|
||||
if obj, ok := info.Defs[t.Name]; ok {
|
||||
return obj.Type().(*types.Signature)
|
||||
}
|
||||
case *ast.FuncLit:
|
||||
if typ, ok := info.Types[t]; ok {
|
||||
return typ.Type.(*types.Signature)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// expectedType returns the expected type for an expression at the query position.
|
||||
func expectedType(path []ast.Node, pos token.Pos, info *types.Info) types.Type {
|
||||
for i, node := range path {
|
||||
if i == 2 {
|
||||
break
|
||||
}
|
||||
switch expr := node.(type) {
|
||||
case *ast.BinaryExpr:
|
||||
// Determine if query position comes from left or right of op.
|
||||
e := expr.X
|
||||
if pos < expr.OpPos {
|
||||
e = expr.Y
|
||||
}
|
||||
if tv, ok := info.Types[e]; ok {
|
||||
return tv.Type
|
||||
}
|
||||
case *ast.AssignStmt:
|
||||
// Only rank completions if you are on the right side of the token.
|
||||
if pos <= expr.TokPos {
|
||||
break
|
||||
}
|
||||
i := exprAtPos(pos, expr.Rhs)
|
||||
if i >= len(expr.Lhs) {
|
||||
i = len(expr.Lhs) - 1
|
||||
}
|
||||
if tv, ok := info.Types[expr.Lhs[i]]; ok {
|
||||
return tv.Type
|
||||
}
|
||||
case *ast.CallExpr:
|
||||
if tv, ok := info.Types[expr.Fun]; ok {
|
||||
if sig, ok := tv.Type.(*types.Signature); ok {
|
||||
if sig.Params().Len() == 0 {
|
||||
return nil
|
||||
}
|
||||
i := exprAtPos(pos, expr.Args)
|
||||
// Make sure not to run past the end of expected parameters.
|
||||
if i >= sig.Params().Len() {
|
||||
i = sig.Params().Len() - 1
|
||||
}
|
||||
return sig.Params().At(i).Type()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// matchingTypes reports whether actual is a good candidate type
|
||||
// for a completion in a context of the expected type.
|
||||
func matchingTypes(expected, actual types.Type) bool {
|
||||
// Use a function's return type as its type.
|
||||
if sig, ok := actual.(*types.Signature); ok {
|
||||
if sig.Results().Len() == 1 {
|
||||
actual = sig.Results().At(0).Type()
|
||||
}
|
||||
}
|
||||
return types.Identical(types.Default(expected), types.Default(actual))
|
||||
}
|
||||
|
||||
// exprAtPos returns the index of the expression containing pos.
|
||||
func exprAtPos(pos token.Pos, args []ast.Expr) int {
|
||||
for i, expr := range args {
|
||||
if expr.Pos() <= pos && pos <= expr.End() {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return len(args)
|
||||
}
|
||||
|
||||
// fieldSelections returns the set of fields that can
|
||||
// be selected from a value of type T.
|
||||
func fieldSelections(T types.Type) (fields []*types.Var) {
|
||||
// TODO(adonovan): this algorithm doesn't exclude ambiguous
|
||||
// selections that match more than one field/method.
|
||||
// types.NewSelectionSet should do that for us.
|
||||
|
||||
seen := make(map[types.Type]bool) // for termination on recursive types
|
||||
var visit func(T types.Type)
|
||||
visit = func(T types.Type) {
|
||||
if !seen[T] {
|
||||
seen[T] = true
|
||||
if T, ok := deref(T).Underlying().(*types.Struct); ok {
|
||||
for i := 0; i < T.NumFields(); i++ {
|
||||
f := T.Field(i)
|
||||
fields = append(fields, f)
|
||||
if f.Anonymous() {
|
||||
visit(f.Type())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
visit(T)
|
||||
|
||||
return fields
|
||||
}
|
||||
|
||||
func isPointer(T types.Type) bool {
|
||||
_, ok := T.(*types.Pointer)
|
||||
return ok
|
||||
}
|
||||
|
||||
// deref returns a pointer's element type; otherwise it returns typ.
|
||||
func deref(typ types.Type) types.Type {
|
||||
if p, ok := typ.Underlying().(*types.Pointer); ok {
|
||||
return p.Elem()
|
||||
}
|
||||
return typ
|
||||
}
|
||||
|
||||
// resolveInvalid traverses the node of the AST that defines the scope
|
||||
// containing the declaration of obj, and attempts to find a user-friendly
|
||||
// name for its invalid type. The resulting Object and its Type are fake.
|
||||
func resolveInvalid(obj types.Object, node ast.Node, info *types.Info) types.Object {
|
||||
// Construct a fake type for the object and return a fake object with this type.
|
||||
formatResult := func(expr ast.Expr) types.Object {
|
||||
var typename string
|
||||
switch t := expr.(type) {
|
||||
case *ast.SelectorExpr:
|
||||
typename = fmt.Sprintf("%s.%s", t.X, t.Sel)
|
||||
case *ast.Ident:
|
||||
typename = t.String()
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
typ := types.NewNamed(types.NewTypeName(token.NoPos, obj.Pkg(), typename, nil), nil, nil)
|
||||
return types.NewVar(obj.Pos(), obj.Pkg(), obj.Name(), typ)
|
||||
}
|
||||
var resultExpr ast.Expr
|
||||
ast.Inspect(node, func(node ast.Node) bool {
|
||||
switch n := node.(type) {
|
||||
case *ast.ValueSpec:
|
||||
for _, name := range n.Names {
|
||||
if info.Defs[name] == obj {
|
||||
resultExpr = n.Type
|
||||
}
|
||||
}
|
||||
return false
|
||||
case *ast.Field: // This case handles parameters and results of a FuncDecl or FuncLit.
|
||||
for _, name := range n.Names {
|
||||
if info.Defs[name] == obj {
|
||||
resultExpr = n.Type
|
||||
}
|
||||
}
|
||||
return false
|
||||
// TODO(rstambler): Handle range statements.
|
||||
default:
|
||||
return true
|
||||
}
|
||||
})
|
||||
return formatResult(resultExpr)
|
||||
}
|
||||
|
||||
type itemDetails struct {
|
||||
label, detail string
|
||||
}
|
||||
|
||||
var builtinDetails = map[string]itemDetails{
|
||||
"append": { // append(slice []T, elems ...T)
|
||||
label: "append(slice []T, elems ...T)",
|
||||
detail: "[]T",
|
||||
},
|
||||
"cap": { // cap(v []T) int
|
||||
label: "cap(v []T)",
|
||||
detail: "int",
|
||||
},
|
||||
"close": { // close(c chan<- T)
|
||||
label: "close(c chan<- T)",
|
||||
},
|
||||
"complex": { // complex(r, i float64) complex128
|
||||
label: "complex(real, imag float64)",
|
||||
detail: "complex128",
|
||||
},
|
||||
"copy": { // copy(dst, src []T) int
|
||||
label: "copy(dst, src []T)",
|
||||
detail: "int",
|
||||
},
|
||||
"delete": { // delete(m map[T]T1, key T)
|
||||
label: "delete(m map[K]V, key K)",
|
||||
},
|
||||
"imag": { // imag(c complex128) float64
|
||||
label: "imag(complex128)",
|
||||
detail: "float64",
|
||||
},
|
||||
"len": { // len(v T) int
|
||||
label: "len(T)",
|
||||
detail: "int",
|
||||
},
|
||||
"make": { // make(t T, size ...int) T
|
||||
label: "make(t T, size ...int)",
|
||||
detail: "T",
|
||||
},
|
||||
"new": { // new(T) *T
|
||||
label: "new(T)",
|
||||
detail: "*T",
|
||||
},
|
||||
"panic": { // panic(v interface{})
|
||||
label: "panic(interface{})",
|
||||
},
|
||||
"print": { // print(args ...T)
|
||||
label: "print(args ...T)",
|
||||
},
|
||||
"println": { // println(args ...T)
|
||||
label: "println(args ...T)",
|
||||
},
|
||||
"real": { // real(c complex128) float64
|
||||
label: "real(complex128)",
|
||||
detail: "float64",
|
||||
},
|
||||
"recover": { // recover() interface{}
|
||||
label: "recover()",
|
||||
detail: "interface{}",
|
||||
},
|
||||
}
|
95
vendor/golang.org/x/tools/internal/lsp/source/definition.go
generated
vendored
Normal file
95
vendor/golang.org/x/tools/internal/lsp/source/definition.go
generated
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
func Definition(ctx context.Context, f *File, pos token.Pos) (Range, error) {
|
||||
fAST, err := f.GetAST()
|
||||
if err != nil {
|
||||
return Range{}, err
|
||||
}
|
||||
pkg, err := f.GetPackage()
|
||||
if err != nil {
|
||||
return Range{}, err
|
||||
}
|
||||
i, err := findIdentifier(fAST, pos)
|
||||
if err != nil {
|
||||
return Range{}, err
|
||||
}
|
||||
if i.ident == nil {
|
||||
return Range{}, fmt.Errorf("definition was not a valid identifier")
|
||||
}
|
||||
obj := pkg.TypesInfo.ObjectOf(i.ident)
|
||||
if obj == nil {
|
||||
return Range{}, fmt.Errorf("no object")
|
||||
}
|
||||
if i.wasEmbeddedField {
|
||||
// the original position was on the embedded field declaration
|
||||
// so we try to dig out the type and jump to that instead
|
||||
if v, ok := obj.(*types.Var); ok {
|
||||
if n, ok := v.Type().(*types.Named); ok {
|
||||
obj = n.Obj()
|
||||
}
|
||||
}
|
||||
}
|
||||
return Range{
|
||||
Start: obj.Pos(),
|
||||
End: obj.Pos() + token.Pos(len([]byte(obj.Name()))), // TODO: use real range of obj
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ident returns the ident plus any extra information needed
|
||||
type ident struct {
|
||||
ident *ast.Ident
|
||||
wasEmbeddedField bool
|
||||
}
|
||||
|
||||
// findIdentifier returns the ast.Ident for a position
|
||||
// in a file, accounting for a potentially incomplete selector.
|
||||
func findIdentifier(f *ast.File, pos token.Pos) (ident, error) {
|
||||
m, err := checkIdentifier(f, pos)
|
||||
if err != nil {
|
||||
return ident{}, err
|
||||
}
|
||||
if m.ident != nil {
|
||||
return m, nil
|
||||
}
|
||||
// If the position is not an identifier but immediately follows
|
||||
// an identifier or selector period (as is common when
|
||||
// requesting a completion), use the path to the preceding node.
|
||||
return checkIdentifier(f, pos-1)
|
||||
}
|
||||
|
||||
// checkIdentifier checks a single position for a potential identifier.
|
||||
func checkIdentifier(f *ast.File, pos token.Pos) (ident, error) {
|
||||
path, _ := astutil.PathEnclosingInterval(f, pos, pos)
|
||||
result := ident{}
|
||||
if path == nil {
|
||||
return result, fmt.Errorf("can't find node enclosing position")
|
||||
}
|
||||
switch node := path[0].(type) {
|
||||
case *ast.Ident:
|
||||
result.ident = node
|
||||
case *ast.SelectorExpr:
|
||||
result.ident = node.Sel
|
||||
}
|
||||
if result.ident != nil {
|
||||
for _, n := range path[1:] {
|
||||
if field, ok := n.(*ast.Field); ok {
|
||||
result.wasEmbeddedField = len(field.Names) == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
148
vendor/golang.org/x/tools/internal/lsp/source/diagnostics.go
generated
vendored
Normal file
148
vendor/golang.org/x/tools/internal/lsp/source/diagnostics.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"context"
|
||||
"go/token"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
type Diagnostic struct {
|
||||
Range Range
|
||||
Severity DiagnosticSeverity
|
||||
Message string
|
||||
}
|
||||
|
||||
type DiagnosticSeverity int
|
||||
|
||||
const (
|
||||
SeverityError DiagnosticSeverity = iota
|
||||
SeverityWarning
|
||||
SeverityHint
|
||||
SeverityInformation
|
||||
)
|
||||
|
||||
func Diagnostics(ctx context.Context, v *View, f *File) (map[string][]Diagnostic, error) {
|
||||
pkg, err := f.GetPackage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Prepare the reports we will send for this package.
|
||||
reports := make(map[string][]Diagnostic)
|
||||
for _, filename := range pkg.GoFiles {
|
||||
reports[filename] = []Diagnostic{}
|
||||
}
|
||||
var parseErrors, typeErrors []packages.Error
|
||||
for _, err := range pkg.Errors {
|
||||
switch err.Kind {
|
||||
case packages.ParseError:
|
||||
parseErrors = append(parseErrors, err)
|
||||
case packages.TypeError:
|
||||
typeErrors = append(typeErrors, err)
|
||||
default:
|
||||
// ignore other types of errors
|
||||
continue
|
||||
}
|
||||
}
|
||||
// Don't report type errors if there are parse errors.
|
||||
diags := typeErrors
|
||||
if len(parseErrors) > 0 {
|
||||
diags = parseErrors
|
||||
}
|
||||
for _, diag := range diags {
|
||||
filename, start := v.errorPos(diag)
|
||||
// TODO(rstambler): Add support for diagnostic ranges.
|
||||
end := start
|
||||
diagnostic := Diagnostic{
|
||||
Range: Range{
|
||||
Start: start,
|
||||
End: end,
|
||||
},
|
||||
Message: diag.Msg,
|
||||
Severity: SeverityError,
|
||||
}
|
||||
if _, ok := reports[filename]; ok {
|
||||
reports[filename] = append(reports[filename], diagnostic)
|
||||
}
|
||||
}
|
||||
return reports, nil
|
||||
}
|
||||
|
||||
func (v *View) errorPos(pkgErr packages.Error) (string, token.Pos) {
|
||||
remainder1, first, hasLine := chop(pkgErr.Pos)
|
||||
remainder2, second, hasColumn := chop(remainder1)
|
||||
var pos token.Position
|
||||
if hasLine && hasColumn {
|
||||
pos.Filename = remainder2
|
||||
pos.Line = second
|
||||
pos.Column = first
|
||||
} else if hasLine {
|
||||
pos.Filename = remainder1
|
||||
pos.Line = first
|
||||
}
|
||||
f := v.GetFile(ToURI(pos.Filename))
|
||||
if f == nil {
|
||||
return "", token.NoPos
|
||||
}
|
||||
tok, err := f.GetToken()
|
||||
if err != nil {
|
||||
return "", token.NoPos
|
||||
}
|
||||
return pos.Filename, fromTokenPosition(tok, pos)
|
||||
}
|
||||
|
||||
func chop(text string) (remainder string, value int, ok bool) {
|
||||
i := strings.LastIndex(text, ":")
|
||||
if i < 0 {
|
||||
return text, 0, false
|
||||
}
|
||||
v, err := strconv.ParseInt(text[i+1:], 10, 64)
|
||||
if err != nil {
|
||||
return text, 0, false
|
||||
}
|
||||
return text[:i], int(v), true
|
||||
}
|
||||
|
||||
// fromTokenPosition converts a token.Position (1-based line and column
|
||||
// number) to a token.Pos (byte offset value).
|
||||
// It requires the token file the pos belongs to in order to do this.
|
||||
func fromTokenPosition(f *token.File, pos token.Position) token.Pos {
|
||||
line := lineStart(f, pos.Line)
|
||||
return line + token.Pos(pos.Column-1) // TODO: this is wrong, bytes not characters
|
||||
}
|
||||
|
||||
// this functionality was borrowed from the analysisutil package
|
||||
func lineStart(f *token.File, line int) token.Pos {
|
||||
// Use binary search to find the start offset of this line.
|
||||
//
|
||||
// TODO(adonovan): eventually replace this function with the
|
||||
// simpler and more efficient (*go/token.File).LineStart, added
|
||||
// in go1.12.
|
||||
|
||||
min := 0 // inclusive
|
||||
max := f.Size() // exclusive
|
||||
for {
|
||||
offset := (min + max) / 2
|
||||
pos := f.Pos(offset)
|
||||
posn := f.Position(pos)
|
||||
if posn.Line == line {
|
||||
return pos - (token.Pos(posn.Column) - 1)
|
||||
}
|
||||
|
||||
if min+1 >= max {
|
||||
return token.NoPos
|
||||
}
|
||||
|
||||
if posn.Line < line {
|
||||
min = offset
|
||||
} else {
|
||||
max = offset
|
||||
}
|
||||
}
|
||||
}
|
131
vendor/golang.org/x/tools/internal/lsp/source/file.go
generated
vendored
Normal file
131
vendor/golang.org/x/tools/internal/lsp/source/file.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
// File holds all the information we know about a file.
|
||||
type File struct {
|
||||
URI URI
|
||||
view *View
|
||||
active bool
|
||||
content []byte
|
||||
ast *ast.File
|
||||
token *token.File
|
||||
pkg *packages.Package
|
||||
}
|
||||
|
||||
// Range represents a start and end position.
|
||||
// Because Range is based purely on two token.Pos entries, it is not self
|
||||
// contained. You need access to a token.FileSet to regain the file
|
||||
// information.
|
||||
type Range struct {
|
||||
Start token.Pos
|
||||
End token.Pos
|
||||
}
|
||||
|
||||
// TextEdit represents a change to a section of a document.
|
||||
// The text within the specified range should be replaced by the supplied new text.
|
||||
type TextEdit struct {
|
||||
Range Range
|
||||
NewText string
|
||||
}
|
||||
|
||||
// SetContent sets the overlay contents for a file.
|
||||
// Setting it to nil will revert it to the on disk contents, and remove it
|
||||
// from the active set.
|
||||
func (f *File) SetContent(content []byte) {
|
||||
f.view.mu.Lock()
|
||||
defer f.view.mu.Unlock()
|
||||
f.content = content
|
||||
// the ast and token fields are invalid
|
||||
f.ast = nil
|
||||
f.token = nil
|
||||
f.pkg = nil
|
||||
// and we might need to update the overlay
|
||||
switch {
|
||||
case f.active && content == nil:
|
||||
// we were active, and want to forget the content
|
||||
f.active = false
|
||||
if filename, err := f.URI.Filename(); err == nil {
|
||||
delete(f.view.Config.Overlay, filename)
|
||||
}
|
||||
f.content = nil
|
||||
case content != nil:
|
||||
// an active overlay, update the map
|
||||
f.active = true
|
||||
if filename, err := f.URI.Filename(); err == nil {
|
||||
f.view.Config.Overlay[filename] = f.content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read returns the contents of the file, reading it from file system if needed.
|
||||
func (f *File) Read() ([]byte, error) {
|
||||
f.view.mu.Lock()
|
||||
defer f.view.mu.Unlock()
|
||||
return f.read()
|
||||
}
|
||||
|
||||
func (f *File) GetToken() (*token.File, error) {
|
||||
f.view.mu.Lock()
|
||||
defer f.view.mu.Unlock()
|
||||
if f.token == nil {
|
||||
if err := f.view.parse(f.URI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if f.token == nil {
|
||||
return nil, fmt.Errorf("failed to find or parse %v", f.URI)
|
||||
}
|
||||
}
|
||||
return f.token, nil
|
||||
}
|
||||
|
||||
func (f *File) GetAST() (*ast.File, error) {
|
||||
f.view.mu.Lock()
|
||||
defer f.view.mu.Unlock()
|
||||
if f.ast == nil {
|
||||
if err := f.view.parse(f.URI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return f.ast, nil
|
||||
}
|
||||
|
||||
func (f *File) GetPackage() (*packages.Package, error) {
|
||||
f.view.mu.Lock()
|
||||
defer f.view.mu.Unlock()
|
||||
if f.pkg == nil {
|
||||
if err := f.view.parse(f.URI); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return f.pkg, nil
|
||||
}
|
||||
|
||||
// read is the internal part of Read that presumes the lock is already held
|
||||
func (f *File) read() ([]byte, error) {
|
||||
if f.content != nil {
|
||||
return f.content, nil
|
||||
}
|
||||
// we don't know the content yet, so read it
|
||||
filename, err := f.URI.Filename()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.content = content
|
||||
return f.content, nil
|
||||
}
|
59
vendor/golang.org/x/tools/internal/lsp/source/format.go
generated
vendored
Normal file
59
vendor/golang.org/x/tools/internal/lsp/source/format.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/format"
|
||||
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
// Format formats a document with a given range.
|
||||
func Format(ctx context.Context, f *File, rng Range) ([]TextEdit, error) {
|
||||
fAST, err := f.GetAST()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
path, exact := astutil.PathEnclosingInterval(fAST, rng.Start, rng.End)
|
||||
if !exact || len(path) == 0 {
|
||||
return nil, fmt.Errorf("no exact AST node matching the specified range")
|
||||
}
|
||||
node := path[0]
|
||||
// format.Node can fail when the AST contains a bad expression or
|
||||
// statement. For now, we preemptively check for one.
|
||||
// TODO(rstambler): This should really return an error from format.Node.
|
||||
var isBad bool
|
||||
ast.Inspect(node, func(n ast.Node) bool {
|
||||
switch n.(type) {
|
||||
case *ast.BadDecl, *ast.BadExpr, *ast.BadStmt:
|
||||
isBad = true
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
})
|
||||
if isBad {
|
||||
return nil, fmt.Errorf("unable to format file due to a badly formatted AST")
|
||||
}
|
||||
// format.Node changes slightly from one release to another, so the version
|
||||
// of Go used to build the LSP server will determine how it formats code.
|
||||
// This should be acceptable for all users, who likely be prompted to rebuild
|
||||
// the LSP server on each Go release.
|
||||
buf := &bytes.Buffer{}
|
||||
if err := format.Node(buf, f.view.Config.Fset, node); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO(rstambler): Compute text edits instead of replacing whole file.
|
||||
return []TextEdit{
|
||||
{
|
||||
Range: rng,
|
||||
NewText: buf.String(),
|
||||
},
|
||||
}, nil
|
||||
}
|
118
vendor/golang.org/x/tools/internal/lsp/source/signature_help.go
generated
vendored
Normal file
118
vendor/golang.org/x/tools/internal/lsp/source/signature_help.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/go/ast/astutil"
|
||||
)
|
||||
|
||||
type SignatureInformation struct {
|
||||
Label string
|
||||
Parameters []ParameterInformation
|
||||
ActiveParameter int
|
||||
}
|
||||
|
||||
type ParameterInformation struct {
|
||||
Label string
|
||||
}
|
||||
|
||||
func SignatureHelp(ctx context.Context, f *File, pos token.Pos) (*SignatureInformation, error) {
|
||||
fAST, err := f.GetAST()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pkg, err := f.GetPackage()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Find a call expression surrounding the query position.
|
||||
var callExpr *ast.CallExpr
|
||||
path, _ := astutil.PathEnclosingInterval(fAST, pos, pos)
|
||||
if path == nil {
|
||||
return nil, fmt.Errorf("cannot find node enclosing position")
|
||||
}
|
||||
for _, node := range path {
|
||||
if c, ok := node.(*ast.CallExpr); ok {
|
||||
callExpr = c
|
||||
break
|
||||
}
|
||||
}
|
||||
if callExpr == nil || callExpr.Fun == nil {
|
||||
return nil, fmt.Errorf("cannot find an enclosing function")
|
||||
}
|
||||
|
||||
// Get the type information for the function corresponding to the call expression.
|
||||
var obj types.Object
|
||||
switch t := callExpr.Fun.(type) {
|
||||
case *ast.Ident:
|
||||
obj = pkg.TypesInfo.ObjectOf(t)
|
||||
case *ast.SelectorExpr:
|
||||
obj = pkg.TypesInfo.ObjectOf(t.Sel)
|
||||
default:
|
||||
return nil, fmt.Errorf("the enclosing function is malformed")
|
||||
}
|
||||
if obj == nil {
|
||||
return nil, fmt.Errorf("cannot resolve %s", callExpr.Fun)
|
||||
}
|
||||
// Find the signature corresponding to the object.
|
||||
var sig *types.Signature
|
||||
switch obj.(type) {
|
||||
case *types.Var:
|
||||
if underlying, ok := obj.Type().Underlying().(*types.Signature); ok {
|
||||
sig = underlying
|
||||
}
|
||||
case *types.Func:
|
||||
sig = obj.Type().(*types.Signature)
|
||||
}
|
||||
if sig == nil {
|
||||
return nil, fmt.Errorf("no function signatures found for %s", obj.Name())
|
||||
}
|
||||
pkgStringer := qualifier(fAST, pkg.Types, pkg.TypesInfo)
|
||||
var paramInfo []ParameterInformation
|
||||
for i := 0; i < sig.Params().Len(); i++ {
|
||||
param := sig.Params().At(i)
|
||||
label := types.TypeString(param.Type(), pkgStringer)
|
||||
if param.Name() != "" {
|
||||
label = fmt.Sprintf("%s %s", param.Name(), label)
|
||||
}
|
||||
paramInfo = append(paramInfo, ParameterInformation{
|
||||
Label: label,
|
||||
})
|
||||
}
|
||||
// Determine the query position relative to the number of parameters in the function.
|
||||
var activeParam int
|
||||
var start, end token.Pos
|
||||
for i, expr := range callExpr.Args {
|
||||
if start == token.NoPos {
|
||||
start = expr.Pos()
|
||||
}
|
||||
end = expr.End()
|
||||
if i < len(callExpr.Args)-1 {
|
||||
end = callExpr.Args[i+1].Pos() - 1 // comma
|
||||
}
|
||||
if start <= pos && pos <= end {
|
||||
break
|
||||
}
|
||||
activeParam++
|
||||
start = expr.Pos() + 1 // to account for commas
|
||||
}
|
||||
// Label for function, qualified by package name.
|
||||
label := obj.Name()
|
||||
if pkg := pkgStringer(obj.Pkg()); pkg != "" {
|
||||
label = pkg + "." + label
|
||||
}
|
||||
return &SignatureInformation{
|
||||
Label: label + formatParams(sig.Params(), sig.Variadic(), pkgStringer),
|
||||
Parameters: paramInfo,
|
||||
ActiveParameter: activeParam,
|
||||
}, nil
|
||||
}
|
47
vendor/golang.org/x/tools/internal/lsp/source/uri.go
generated
vendored
Normal file
47
vendor/golang.org/x/tools/internal/lsp/source/uri.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const fileSchemePrefix = "file://"
|
||||
|
||||
// URI represents the full uri for a file.
|
||||
type URI string
|
||||
|
||||
// Filename gets the file path for the URI.
|
||||
// It will return an error if the uri is not valid, or if the URI was not
|
||||
// a file URI
|
||||
func (uri URI) Filename() (string, error) {
|
||||
s := string(uri)
|
||||
if !strings.HasPrefix(s, fileSchemePrefix) {
|
||||
return "", fmt.Errorf("only file URI's are supported, got %v", uri)
|
||||
}
|
||||
s = s[len(fileSchemePrefix):]
|
||||
s, err := url.PathUnescape(s)
|
||||
if err != nil {
|
||||
return s, err
|
||||
}
|
||||
s = filepath.FromSlash(s)
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// ToURI returns a protocol URI for the supplied path.
|
||||
// It will always have the file scheme.
|
||||
func ToURI(path string) URI {
|
||||
const prefix = "$GOROOT"
|
||||
if strings.EqualFold(prefix, path[:len(prefix)]) {
|
||||
suffix := path[len(prefix):]
|
||||
//TODO: we need a better way to get the GOROOT that uses the packages api
|
||||
path = runtime.GOROOT() + suffix
|
||||
}
|
||||
return URI(fileSchemePrefix + filepath.ToSlash(path))
|
||||
}
|
82
vendor/golang.org/x/tools/internal/lsp/source/view.go
generated
vendored
Normal file
82
vendor/golang.org/x/tools/internal/lsp/source/view.go
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2018 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 source
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/token"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
type View struct {
|
||||
mu sync.Mutex // protects all mutable state of the view
|
||||
|
||||
Config *packages.Config
|
||||
|
||||
files map[URI]*File
|
||||
}
|
||||
|
||||
func NewView() *View {
|
||||
return &View{
|
||||
Config: &packages.Config{
|
||||
Mode: packages.LoadSyntax,
|
||||
Fset: token.NewFileSet(),
|
||||
Tests: true,
|
||||
Overlay: make(map[string][]byte),
|
||||
},
|
||||
files: make(map[URI]*File),
|
||||
}
|
||||
}
|
||||
|
||||
// GetFile returns a File for the given uri.
|
||||
// It will always succeed, adding the file to the managed set if needed.
|
||||
func (v *View) GetFile(uri URI) *File {
|
||||
v.mu.Lock()
|
||||
f := v.getFile(uri)
|
||||
v.mu.Unlock()
|
||||
return f
|
||||
}
|
||||
|
||||
// getFile is the unlocked internal implementation of GetFile.
|
||||
func (v *View) getFile(uri URI) *File {
|
||||
f, found := v.files[uri]
|
||||
if !found {
|
||||
f = &File{
|
||||
URI: uri,
|
||||
view: v,
|
||||
}
|
||||
v.files[f.URI] = f
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (v *View) parse(uri URI) error {
|
||||
path, err := uri.Filename()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pkgs, err := packages.Load(v.Config, fmt.Sprintf("file=%s", path))
|
||||
if len(pkgs) == 0 {
|
||||
if err == nil {
|
||||
err = fmt.Errorf("no packages found for %s", path)
|
||||
}
|
||||
return err
|
||||
}
|
||||
for _, pkg := range pkgs {
|
||||
// add everything we find to the files cache
|
||||
for _, fAST := range pkg.Syntax {
|
||||
// if a file was in multiple packages, which token/ast/pkg do we store
|
||||
fToken := v.Config.Fset.File(fAST.Pos())
|
||||
fURI := ToURI(fToken.Name())
|
||||
f := v.getFile(fURI)
|
||||
f.token = fToken
|
||||
f.ast = fAST
|
||||
f.pkg = pkg
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
21
vendor/golang.org/x/tools/internal/lsp/testdata/bad/bad.go
generated
vendored
Normal file
21
vendor/golang.org/x/tools/internal/lsp/testdata/bad/bad.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// +build go1.11
|
||||
|
||||
package bad
|
||||
|
||||
func stuff() {
|
||||
x := "heeeeyyyy"
|
||||
random2(x) //@diag("x", "cannot use x (variable of type string) as int value in argument to random2")
|
||||
random2(1)
|
||||
y := 3 //@diag("y", "y declared but not used")
|
||||
}
|
||||
|
||||
type bob struct {
|
||||
x int
|
||||
}
|
||||
|
||||
func _() {
|
||||
var q int
|
||||
_ = &bob{
|
||||
f: q, //@diag("f", "unknown field f in struct literal")
|
||||
}
|
||||
}
|
8
vendor/golang.org/x/tools/internal/lsp/testdata/bad/bad_util.go
generated
vendored
Normal file
8
vendor/golang.org/x/tools/internal/lsp/testdata/bad/bad_util.go
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
// +build go1.11
|
||||
|
||||
package bad
|
||||
|
||||
func random2(y int) int {
|
||||
x := 6 //@diag("x", "x declared but not used")
|
||||
return y
|
||||
}
|
7
vendor/golang.org/x/tools/internal/lsp/testdata/bar/bar.go
generated
vendored
Normal file
7
vendor/golang.org/x/tools/internal/lsp/testdata/bar/bar.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package bar
|
||||
|
||||
import "golang.org/x/tools/internal/lsp/foo"
|
||||
|
||||
func Bar() {
|
||||
foo.Foo()
|
||||
}
|
7
vendor/golang.org/x/tools/internal/lsp/testdata/baz/baz.go
generated
vendored
Normal file
7
vendor/golang.org/x/tools/internal/lsp/testdata/baz/baz.go
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
package baz
|
||||
|
||||
import "golang.org/x/tools/internal/lsp/bar"
|
||||
|
||||
func Baz() {
|
||||
bar.Bar()
|
||||
}
|
23
vendor/golang.org/x/tools/internal/lsp/testdata/foo/foo.go
generated
vendored
Normal file
23
vendor/golang.org/x/tools/internal/lsp/testdata/foo/foo.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
package foo
|
||||
|
||||
type StructFoo struct { //@item(StructFoo, "StructFoo", "struct{...}", "struct")
|
||||
Value int //@item(Value, "Value", "int", "field")
|
||||
}
|
||||
|
||||
// TODO(rstambler): Create pre-set builtins?
|
||||
/* Error() */ //@item(Error, "Error()", "string", "method")
|
||||
|
||||
func Foo() { //@item(Foo, "Foo()", "", "func")
|
||||
var err error
|
||||
err.Error() //@complete("E", Error)
|
||||
}
|
||||
|
||||
func _() {
|
||||
var sFoo StructFoo //@complete("t", StructFoo)
|
||||
if x := sFoo; x.Value == 1 { //@complete("V", Value)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//@complete("", Foo, IntFoo, StructFoo)
|
||||
type IntFoo int //@item(IntFoo, "IntFoo", "int", "type")
|
21
vendor/golang.org/x/tools/internal/lsp/testdata/format/bad_format.go
generated
vendored
Normal file
21
vendor/golang.org/x/tools/internal/lsp/testdata/format/bad_format.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package format //@format("package")
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"log"
|
||||
)
|
||||
|
||||
func hello() {
|
||||
|
||||
var x int //@diag("x", "x declared but not used")
|
||||
}
|
||||
|
||||
func hi() {
|
||||
|
||||
runtime.GOROOT()
|
||||
fmt.Printf("")
|
||||
|
||||
log.Printf("")
|
||||
}
|
9
vendor/golang.org/x/tools/internal/lsp/testdata/format/good_format.go
generated
vendored
Normal file
9
vendor/golang.org/x/tools/internal/lsp/testdata/format/good_format.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
package format //@format("package")
|
||||
|
||||
import (
|
||||
"log"
|
||||
)
|
||||
|
||||
func goodbye() {
|
||||
log.Printf("byeeeee")
|
||||
}
|
6
vendor/golang.org/x/tools/internal/lsp/testdata/good/good.go
generated
vendored
Normal file
6
vendor/golang.org/x/tools/internal/lsp/testdata/good/good.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package good
|
||||
|
||||
func stuff() {
|
||||
x := 5
|
||||
random2(x)
|
||||
}
|
10
vendor/golang.org/x/tools/internal/lsp/testdata/good/good_util.go
generated
vendored
Normal file
10
vendor/golang.org/x/tools/internal/lsp/testdata/good/good_util.go
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
package good
|
||||
|
||||
func random() int {
|
||||
y := 6 + 7
|
||||
return y
|
||||
}
|
||||
|
||||
func random2(y int) int {
|
||||
return y
|
||||
}
|
11
vendor/golang.org/x/tools/internal/lsp/testdata/noparse/noparse.go.in
generated
vendored
Normal file
11
vendor/golang.org/x/tools/internal/lsp/testdata/noparse/noparse.go.in
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package noparse
|
||||
|
||||
func bye(x int) {
|
||||
hi()
|
||||
}
|
||||
|
||||
func stuff() {
|
||||
x := 5
|
||||
}
|
||||
|
||||
func .() {} //@diag(".", "expected 'IDENT', found '.'")
|
9
vendor/golang.org/x/tools/internal/lsp/testdata/noparse_format/noparse_format.go.in
generated
vendored
Normal file
9
vendor/golang.org/x/tools/internal/lsp/testdata/noparse_format/noparse_format.go.in
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// +build go1.11
|
||||
|
||||
package noparse_format //@format("package")
|
||||
|
||||
func what() {
|
||||
var b int
|
||||
if { hi() //@diag("{", "missing condition in if statement")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user