1
0
mirror of https://github.com/golang/go synced 2024-11-18 00:14:47 -07:00

internal/lsp/protocol: add support for upcoming LSP 3.16

These are the changes needed to support Semantic Tokens in the LSP protocol.

Added a function to server.go to make generating server_gen.go work again.

Change-Id: I2e09220560b080dd666e25eaf1a39b9960b6f871
Reviewed-on: https://go-review.googlesource.com/c/tools/+/253938
Run-TryBot: Peter Weinberger <pjw@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Peter Weinbergr 2020-09-10 11:09:39 -04:00 committed by Peter Weinberger
parent d179df38ff
commit d49a6cb6ca
7 changed files with 169 additions and 74 deletions

View File

@ -2,8 +2,8 @@ package protocol
// Package protocol contains data types and code for LSP jsonrpcs
// generated automatically from vscode-languageserver-node
// commit: 399de64448129835b53c7efe8962de91681d6cde
// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time)
// commit: 60a5a7825e6f54f57917091f394fd8db7d1724bc
// last fetched Thu Sep 10 2020 09:21:57 GMT-0400 (Eastern Daylight Time)
// Code generated (see typescript/README.md) DO NOT EDIT.

View File

@ -1,7 +1,7 @@
// Package protocol contains data types and code for LSP jsonrpcs
// generated automatically from vscode-languageserver-node
// commit: 399de64448129835b53c7efe8962de91681d6cde
// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time)
// commit: 60a5a7825e6f54f57917091f394fd8db7d1724bc
// last fetched Thu Sep 10 2020 09:21:57 GMT-0400 (Eastern Daylight Time)
package protocol
// Code generated (see typescript/README.md) DO NOT EDIT.
@ -390,7 +390,7 @@ type CodeLens struct {
*/
Command Command `json:"command,omitempty"`
/**
* An data entry field that is preserved on a code lens item between
* A data entry field that is preserved on a code lens item between
* a [CodeLensRequest](#CodeLensRequest) and a [CodeLensResolveRequest]
* (#CodeLensResolveRequest)
*/
@ -748,7 +748,7 @@ type CompletionItem struct {
*/
Command *Command `json:"command,omitempty"`
/**
* An data entry field that is preserved on a completion item between
* A data entry field that is preserved on a completion item between
* a [CompletionRequest](#CompletionRequest) and a [CompletionResolveRequest]
* (#CompletionResolveRequest)
*/
@ -900,7 +900,7 @@ type CreateFileOptions struct {
type Declaration = []Location /*Location | Location[]*/
/**
* Since 3.14.0
* @since 3.14.0
*/
type DeclarationClientCapabilities struct {
/**
@ -1862,7 +1862,7 @@ type HoverParams struct {
}
/**
* Since 3.6.0
* @since 3.6.0
*/
type ImplementationClientCapabilities struct {
/**
@ -1874,7 +1874,7 @@ type ImplementationClientCapabilities struct {
/**
* The client supports additional metadata in the form of definition links.
*
* Since 3.14.0
* @since 3.14.0
*/
LinkSupport bool `json:"linkSupport,omitempty"`
}
@ -2113,8 +2113,16 @@ type InnerServerCapabilities struct {
ExecuteCommandProvider ExecuteCommandOptions `json:"executeCommandProvider,omitempty"`
/**
* The server provides Call Hierarchy support.
*
* @since 3.16.0 - Proposed state
*/
CallHierarchyProvider interface{}/* bool | CallHierarchyOptions | CallHierarchyRegistrationOptions*/ `json:"callHierarchyProvider,omitempty"`
/**
* The server provides semantic tokens support.
*
* @since 3.16.0 - Proposed state
*/
SemanticTokensProvider interface{}/*SemanticTokensOptions | SemanticTokensRegistrationOptions*/ `json:"semanticTokensProvider,omitempty"`
/**
* Experimental server capabilities.
*/
@ -2506,6 +2514,12 @@ type RenameClientCapabilities struct {
* @since version 3.12.0
*/
PrepareSupport bool `json:"prepareSupport,omitempty"`
/**
* Client supports the default behavior result.
*
* @since version 3.16.0
*/
PrepareSupportDefaultBehavior bool `json:"prepareSupportDefaultBehavior,omitempty"`
}
/**
@ -2682,7 +2696,8 @@ type SemanticTokensDeltaParams struct {
*/
TextDocument TextDocumentIdentifier `json:"textDocument"`
/**
* The previous result id.
* The result id of a previous response. The result Id can either point to a full response
* or a delta response depending on what was recevied last.
*/
PreviousResultID string `json:"previousResultId"`
WorkDoneProgressParams
@ -2707,6 +2722,40 @@ type SemanticTokensEdit struct {
Data []float64 `json:"data,omitempty"`
}
/**
* @since 3.16.0 - Proposed state
*/
type SemanticTokensLegend struct {
/**
* The token types a server uses.
*/
TokenTypes []string `json:"tokenTypes"`
/**
* The token modifiers a server uses.
*/
TokenModifiers []string `json:"tokenModifiers"`
}
/**
* @since 3.16.0 - Proposed state
*/
type SemanticTokensOptions struct {
/**
* The legend used by the server
*/
Legend SemanticTokensLegend `json:"legend"`
/**
* Server supports providing semantic tokens for a sepcific range
* of a document.
*/
Range bool/*boolean | { }*/ `json:"range,omitempty"`
/**
* Server supports providing semantic tokens for a full document.
*/
Full bool/*boolean | <elided struct>*/ `json:"full,omitempty"`
WorkDoneProgressOptions
}
/**
* @since 3.16.0 - Proposed state
*/
@ -2735,6 +2784,15 @@ type SemanticTokensRangeParams struct {
PartialResultParams
}
/**
* @since 3.16.0 - Proposed state
*/
type SemanticTokensRegistrationOptions struct {
TextDocumentRegistrationOptions
SemanticTokensOptions
StaticRegistrationOptions
}
type ServerCapabilities = struct {
/**
* Defines how text documents are synced. Is either a detailed structure defining each notification or
@ -2835,8 +2893,16 @@ type ServerCapabilities = struct {
ExecuteCommandProvider ExecuteCommandOptions `json:"executeCommandProvider,omitempty"`
/**
* The server provides Call Hierarchy support.
*
* @since 3.16.0 - Proposed state
*/
CallHierarchyProvider interface{}/* bool | CallHierarchyOptions | CallHierarchyRegistrationOptions*/ `json:"callHierarchyProvider,omitempty"`
/**
* The server provides semantic tokens support.
*
* @since 3.16.0 - Proposed state
*/
SemanticTokensProvider interface{}/*SemanticTokensOptions | SemanticTokensRegistrationOptions*/ `json:"semanticTokensProvider,omitempty"`
/**
* Experimental server capabilities.
*/

View File

@ -2,8 +2,8 @@ package protocol
// Package protocol contains data types and code for LSP jsonrpcs
// generated automatically from vscode-languageserver-node
// commit: 399de64448129835b53c7efe8962de91681d6cde
// last fetched Wed Aug 26 2020 20:34:24 GMT-0400 (Eastern Daylight Time)
// commit: 60a5a7825e6f54f57917091f394fd8db7d1724bc
// last fetched Thu Sep 10 2020 09:21:57 GMT-0400 (Eastern Daylight Time)
// Code generated (see typescript/README.md) DO NOT EDIT.
@ -18,6 +18,7 @@ import (
type Server interface {
DidChangeWorkspaceFolders(context.Context, *DidChangeWorkspaceFoldersParams) error
WorkDoneProgressCancel(context.Context, *WorkDoneProgressCancelParams) error
SemanticTokensRefresh(context.Context) error
Initialized(context.Context, *InitializedParams) error
Exit(context.Context) error
DidChangeConfiguration(context.Context, *DidChangeConfigurationParams) error
@ -39,6 +40,9 @@ type Server interface {
PrepareCallHierarchy(context.Context, *CallHierarchyPrepareParams) ([]CallHierarchyItem /*CallHierarchyItem[] | null*/, error)
IncomingCalls(context.Context, *CallHierarchyIncomingCallsParams) ([]CallHierarchyIncomingCall /*CallHierarchyIncomingCall[] | null*/, error)
OutgoingCalls(context.Context, *CallHierarchyOutgoingCallsParams) ([]CallHierarchyOutgoingCall /*CallHierarchyOutgoingCall[] | null*/, error)
SemanticTokensFull(context.Context, *SemanticTokensParams) (*SemanticTokens /*SemanticTokens | null*/, error)
SemanticTokensFullDelta(context.Context, *SemanticTokensDeltaParams) (interface{} /* SemanticTokens | SemanticTokensDelta | nil*/, error)
SemanticTokensRange(context.Context, *SemanticTokensRangeParams) (*SemanticTokens /*SemanticTokens | null*/, error)
Initialize(context.Context, *ParamInitialize) (*InitializeResult, error)
Shutdown(context.Context) error
WillSaveWaitUntil(context.Context, *WillSaveTextDocumentParams) ([]TextEdit /*TextEdit[] | null*/, error)
@ -60,11 +64,8 @@ type Server interface {
RangeFormatting(context.Context, *DocumentRangeFormattingParams) ([]TextEdit /*TextEdit[] | null*/, error)
OnTypeFormatting(context.Context, *DocumentOnTypeFormattingParams) ([]TextEdit /*TextEdit[] | null*/, error)
Rename(context.Context, *RenameParams) (*WorkspaceEdit /*WorkspaceEdit | null*/, error)
PrepareRename(context.Context, *PrepareRenameParams) (*Range /*Range | { range: Range, placeholder: string } | null*/, error)
PrepareRename(context.Context, *PrepareRenameParams) (*Range /*Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null*/, error)
ExecuteCommand(context.Context, *ExecuteCommandParams) (interface{} /*any | null*/, error)
SemanticTokensFull(context.Context, *SemanticTokensParams) (*SemanticTokens /*SemanticTokens | null*/, error)
SemanticTokensFullDelta(context.Context, *SemanticTokensDeltaParams) (interface{} /* SemanticTokens | SemanticTokensDelta | nil*/, error)
SemanticTokensRange(context.Context, *SemanticTokensRangeParams) (*SemanticTokens /*SemanticTokens | null*/, error)
NonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error)
}
@ -84,6 +85,9 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier,
}
err := server.WorkDoneProgressCancel(ctx, &params)
return true, reply(ctx, nil, err)
case "workspace/semanticTokens/refresh": // notif
err := server.SemanticTokensRefresh(ctx)
return true, reply(ctx, nil, err)
case "initialized": // notif
var params InitializedParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
@ -227,6 +231,27 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier,
}
resp, err := server.OutgoingCalls(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/full": // req
var params SemanticTokensParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensFull(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/full/delta": // req
var params SemanticTokensDeltaParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensFullDelta(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/range": // req
var params SemanticTokensRangeParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensRange(ctx, &params)
return true, reply(ctx, resp, err)
case "initialize": // req
var params ParamInitialize
if err := json.Unmarshal(r.Params(), &params); err != nil {
@ -387,27 +412,6 @@ func serverDispatch(ctx context.Context, server Server, reply jsonrpc2.Replier,
}
resp, err := server.ExecuteCommand(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/full": // req
var params SemanticTokensParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensFull(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/full/delta": // req
var params SemanticTokensDeltaParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensFullDelta(ctx, &params)
return true, reply(ctx, resp, err)
case "textDocument/semanticTokens/range": // req
var params SemanticTokensRangeParams
if err := json.Unmarshal(r.Params(), &params); err != nil {
return true, sendParseError(ctx, reply, err)
}
resp, err := server.SemanticTokensRange(ctx, &params)
return true, reply(ctx, resp, err)
default:
return false, nil
@ -422,6 +426,10 @@ func (s *serverDispatcher) WorkDoneProgressCancel(ctx context.Context, params *W
return s.Conn.Notify(ctx, "window/workDoneProgress/cancel", params)
}
func (s *serverDispatcher) SemanticTokensRefresh(ctx context.Context) error {
return s.Conn.Notify(ctx, "workspace/semanticTokens/refresh", nil)
}
func (s *serverDispatcher) Initialized(ctx context.Context, params *InitializedParams) error {
return s.Conn.Notify(ctx, "initialized", params)
}
@ -545,6 +553,30 @@ func (s *serverDispatcher) OutgoingCalls(ctx context.Context, params *CallHierar
return result, nil
}
func (s *serverDispatcher) SemanticTokensFull(ctx context.Context, params *SemanticTokensParams) (*SemanticTokens /*SemanticTokens | null*/, error) {
var result *SemanticTokens /*SemanticTokens | null*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/full", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) SemanticTokensFullDelta(ctx context.Context, params *SemanticTokensDeltaParams) (interface{} /* SemanticTokens | SemanticTokensDelta | nil*/, error) {
var result interface{} /* SemanticTokens | SemanticTokensDelta | nil*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/full/delta", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) SemanticTokensRange(ctx context.Context, params *SemanticTokensRangeParams) (*SemanticTokens /*SemanticTokens | null*/, error) {
var result *SemanticTokens /*SemanticTokens | null*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/range", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) Initialize(ctx context.Context, params *ParamInitialize) (*InitializeResult, error) {
var result *InitializeResult
if err := Call(ctx, s.Conn, "initialize", params, &result); err != nil {
@ -709,8 +741,8 @@ func (s *serverDispatcher) Rename(ctx context.Context, params *RenameParams) (*W
return result, nil
}
func (s *serverDispatcher) PrepareRename(ctx context.Context, params *PrepareRenameParams) (*Range /*Range | { range: Range, placeholder: string } | null*/, error) {
var result *Range /*Range | { range: Range, placeholder: string } | null*/
func (s *serverDispatcher) PrepareRename(ctx context.Context, params *PrepareRenameParams) (*Range /*Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null*/, error) {
var result *Range /*Range | { range: Range, placeholder: string } | { defaultBehavior: boolean } | null*/
if err := Call(ctx, s.Conn, "textDocument/prepareRename", params, &result); err != nil {
return nil, err
}
@ -725,30 +757,6 @@ func (s *serverDispatcher) ExecuteCommand(ctx context.Context, params *ExecuteCo
return result, nil
}
func (s *serverDispatcher) SemanticTokensFull(ctx context.Context, params *SemanticTokensParams) (*SemanticTokens /*SemanticTokens | null*/, error) {
var result *SemanticTokens /*SemanticTokens | null*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/full", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) SemanticTokensFullDelta(ctx context.Context, params *SemanticTokensDeltaParams) (interface{} /* SemanticTokens | SemanticTokensDelta | nil*/, error) {
var result interface{} /* SemanticTokens | SemanticTokensDelta | nil*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/full/delta", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) SemanticTokensRange(ctx context.Context, params *SemanticTokensRangeParams) (*SemanticTokens /*SemanticTokens | null*/, error) {
var result *SemanticTokens /*SemanticTokens | null*/
if err := Call(ctx, s.Conn, "textDocument/semanticTokens/range", params, &result); err != nil {
return nil, err
}
return result, nil
}
func (s *serverDispatcher) NonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) {
var result interface{}
if err := Call(ctx, s.Conn, method, params, &result); err != nil {

View File

@ -70,9 +70,13 @@ function findRPCs(node: ts.Node) {
const decl: ts.VariableDeclaration = dl.declarations[0];
const name = decl.name.getText()
// we want the initializers
if (name == 'method') { // StringLiteral
if (!ts.isStringLiteral(decl.initializer))
throw new Error(`expect StringLiteral at ${loc(decl)}`);
if (name == 'method') { // mostly StringLiteral but NoSubstitutionTemplateLiteral in protocol.semanticTokens.ts
if (!ts.isStringLiteral(decl.initializer)) {
if (!ts.isNoSubstitutionTemplateLiteral(decl.initializer)) {
console.log(`${decl.initializer.getText()}`);
throw new Error(`expect StringLiteral at ${loc(decl)} got ${strKind(decl.initializer)}`);
}
}
rpc = decl.initializer.getText()
}
else if (name == 'type') { // NewExpression
@ -520,7 +524,7 @@ function goInterface(d: Data, nm: string) {
ans = ans.concat(getComments(n));
const json = u.JSON(n);
// SelectionRange is a recursive type
let gt = goType(n.type, n.name.getText());
let gt = goType(n.type, n.name.getText(), nm);
if (gt == d.name) gt = '*' + gt; // avoid recursive types
// there are several cases where a * is needed
starred.forEach(([a, b]) => {
@ -613,12 +617,12 @@ function goTypeAlias(d: Data, nm: string) {
}
// return a go type and maybe an assocated javascript tag
function goType(n: ts.TypeNode, nm: string): string {
function goType(n: ts.TypeNode, nm: string, parent?: string): string {
if (n.getText() == 'T') return 'interface{}'; // should check it's generic
if (ts.isTypeReferenceNode(n)) {
return goName(n.typeName.getText()); // avoid <T>
} else if (ts.isUnionTypeNode(n)) {
return goUnionType(n, nm);
return goUnionType(n, nm, parent);
} else if (ts.isIntersectionTypeNode(n)) {
return goIntersectionType(n, nm);
} else if (strKind(n) == 'StringKeyword') {
@ -659,8 +663,16 @@ function goType(n: ts.TypeNode, nm: string): string {
// The choice is uniform interface{}, or some heuristically assigned choice,
// or some better sytematic idea I haven't thought of. Using interface{}
// is, in practice, impossibly complex in the existing code.
function goUnionType(n: ts.UnionTypeNode, nm: string): string {
const help = `/*${n.getText()}*/` // show the original as a comment
function goUnionType(n: ts.UnionTypeNode, nm: string, parent?: string): string {
let help = `/*${n.getText()}*/` // show the original as a comment
// There are some bad cases with newlines:
// range?: boolean | {\n };
// full?: boolean | {\n /**\n * The server supports deltas for full documents.\n */\n delta?: boolean;\n }
// These are handled specially:
if (parent == 'SemanticTokensOptions') {
if (nm == 'range') help = help.replace(/\n/, '');
if (nm == 'full') help = '/*boolean | <elided struct>*/';
}
// handle all the special cases
switch (n.types.length) {
case 2:
@ -725,8 +737,9 @@ function goUnionType(n: ts.UnionTypeNode, nm: string): string {
break;
case 4:
if (nm == 'documentChanges') return `TextDocumentEdit ${help} `;
if (nm == 'textDocument/prepareRename') return `Range ${help} `;
default:
throw new Error(`goUnionType ${n.types.length} `)
throw new Error(`goUnionType len=${n.types.length} nm=${nm}`)
}
// Result will be interface{} with a comment

View File

@ -14,7 +14,7 @@ export const fnames = [
`${dir}/${srcDir}/protocol/src/browser/main.ts`, `${dir}${srcDir}/types/src/main.ts`,
`${dir}${srcDir}/jsonrpc/src/node/main.ts`
];
export const gitHash = '399de64448129835b53c7efe8962de91681d6cde'
export const gitHash = '60a5a7825e6f54f57917091f394fd8db7d1724bc'
let outFname = 'tsprotocol.go';
let fda: number, fdb: number, fde: number; // file descriptors

View File

@ -104,6 +104,10 @@ type sentDiagnostics struct {
snapshotID uint64
}
func (s *Server) workDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error {
return s.progress.cancel(ctx, params.Token)
}
func (s *Server) nonstandardRequest(ctx context.Context, method string, params interface{}) (interface{}, error) {
paramMap := params.(map[string]interface{})
if method == "gopls/diagnoseFiles" {

View File

@ -176,6 +176,10 @@ func (s *Server) SemanticTokensRange(context.Context, *protocol.SemanticTokensRa
return nil, notImplemented("SemanticTokensRange")
}
func (s *Server) SemanticTokensRefresh(context.Context) error {
return notImplemented("SemanticTokensRefresh")
}
func (s *Server) SetTrace(context.Context, *protocol.SetTraceParams) error {
return notImplemented("SetTrace")
}
@ -205,5 +209,5 @@ func (s *Server) WillSaveWaitUntil(context.Context, *protocol.WillSaveTextDocume
}
func (s *Server) WorkDoneProgressCancel(ctx context.Context, params *protocol.WorkDoneProgressCancelParams) error {
return s.progress.cancel(ctx, params.Token)
return s.workDoneProgressCancel(ctx, params)
}