diff --git a/capabilities_server.go b/capabilities_server.go index b06851e..d74f32e 100644 --- a/capabilities_server.go +++ b/capabilities_server.go @@ -1,51 +1,161 @@ package protocol // ServerCapabilities defines the capabilities of the language server. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#serverCapabilities type ServerCapabilities struct { - // The position encoding the server picked from the encodings offered - // by the client via the client capability `general.positionEncodings`. + // The position encoding the server picked from the encodings offered by the + // client via the client capability `general.positionEncodings`. // - // If the client didn't provide any position encodings the only valid - // value that a server can return is 'utf-16'. + // If the client didn't provide any position encodings the only valid value + // that a server can return is `utf-16`. // - // If omitted it defaults to 'utf-16'. + // If omitted it defaults to `utf-16`. // // @since 3.17.0 PositionEncoding *PositionEncodingKind `json:"positionEncoding,omitempty"` - // 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 any `json:"textDocumentSync,omitempty"` // *TextDocumentSyncOptions | TextDocumentSyncKind + // Defines how text documents are synced. + // + // This can be either: + // - `TextDocumentSyncOptions`, or + // - `TextDocumentSyncKind` (for backwards compatibility). + TextDocumentSync any `json:"textDocumentSync,omitempty"` // TextDocumentSyncOptions | TextDocumentSyncKind + + // Defines notebook document synchronization support. + // + // @since 3.17.0 + NotebookDocumentSync any `json:"notebookDocumentSync,omitempty"` // NotebookDocumentSyncOptions | NotebookDocumentSyncRegistrationOptions // The server provides completion support. CompletionProvider *CompletionOptions `json:"completionProvider,omitempty"` // The server provides hover support. - HoverProvider bool `json:"hoverProvider,omitempty"` + HoverProvider any `json:"hoverProvider,omitempty"` // bool | HoverOptions // 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 declaration support. + // + // @since 3.14.0 + DeclarationProvider any `json:"declarationProvider,omitempty"` // bool | DeclarationOptions | DeclarationRegistrationOptions - // The server provides code actions. The `CodeActionOptions` return type is - // only valid if the client signals code action literal support via the - // property `textDocument.codeAction.codeActionLiteralSupport`. - CodeActionProvider bool `json:"codeActionProvider,omitempty"` + // The server provides goto definition support. + DefinitionProvider any `json:"definitionProvider,omitempty"` // bool | DefinitionOptions + + // The server provides goto type definition support. + // + // @since 3.6.0 + TypeDefinitionProvider any `json:"typeDefinitionProvider,omitempty"` // bool | TypeDefinitionOptions | TypeDefinitionRegistrationOptions + + // The server provides goto implementation support. + // + // @since 3.6.0 + ImplementationProvider any `json:"implementationProvider,omitempty"` // bool | ImplementationOptions | ImplementationRegistrationOptions + + // The server provides find references support. + ReferencesProvider any `json:"referencesProvider,omitempty"` // bool | ReferenceOptions + + // The server provides document highlight support. + DocumentHighlightProvider any `json:"documentHighlightProvider,omitempty"` // bool | DocumentHighlightOptions + + // The server provides document symbol support. + DocumentSymbolProvider any `json:"documentSymbolProvider,omitempty"` // bool | DocumentSymbolOptions + + // The server provides code action support. + CodeActionProvider any `json:"codeActionProvider,omitempty"` // bool | CodeActionOptions + + // The server provides code lens support. + CodeLensProvider *CodeLensOptions `json:"codeLensProvider,omitempty"` + + // The server provides document link support. + DocumentLinkProvider *DocumentLinkOptions `json:"documentLinkProvider,omitempty"` + + // The server provides color provider support. + // + // @since 3.6.0 + ColorProvider any `json:"colorProvider,omitempty"` // bool | DocumentColorOptions | DocumentColorRegistrationOptions + + // The server provides document formatting support. + DocumentFormattingProvider any `json:"documentFormattingProvider,omitempty"` // bool | DocumentFormattingOptions + + // The server provides document range formatting support. + DocumentRangeFormattingProvider any `json:"documentRangeFormattingProvider,omitempty"` // bool | DocumentRangeFormattingOptions + + // The server provides document on type formatting support. + DocumentOnTypeFormattingProvider *DocumentOnTypeFormattingOptions `json:"documentOnTypeFormattingProvider,omitempty"` + + // The server provides rename support. + RenameProvider any `json:"renameProvider,omitempty"` // bool | RenameOptions + + // The server provides folding range support. + // + // @since 3.10.0 + FoldingRangeProvider any `json:"foldingRangeProvider,omitempty"` // bool | FoldingRangeOptions | FoldingRangeRegistrationOptions + + // The server provides execute command support. + ExecuteCommandProvider *ExecuteCommandOptions `json:"executeCommandProvider,omitempty"` + + // The server provides selection range support. + // + // @since 3.15.0 + SelectionRangeProvider any `json:"selectionRangeProvider,omitempty"` // bool | SelectionRangeOptions | SelectionRangeRegistrationOptions + + // The server provides linked editing range support. + // + // @since 3.16.0 + LinkedEditingRangeProvider any `json:"linkedEditingRangeProvider,omitempty"` // bool | LinkedEditingRangeOptions | LinkedEditingRangeRegistrationOptions + + // The server provides call hierarchy support. + // + // @since 3.16.0 + CallHierarchyProvider any `json:"callHierarchyProvider,omitempty"` // bool | CallHierarchyOptions | CallHierarchyRegistrationOptions + + // The server provides semantic tokens support. + // + // @since 3.16.0 + SemanticTokensProvider any `json:"semanticTokensProvider,omitempty"` // SemanticTokensOptions | SemanticTokensRegistrationOptions + + // The server provides moniker support. + // + // @since 3.16.0 + MonikerProvider any `json:"monikerProvider,omitempty"` // bool | MonikerOptions | MonikerRegistrationOptions + + // The server provides type hierarchy support. + // + // @since 3.17.0 + TypeHierarchyProvider any `json:"typeHierarchyProvider,omitempty"` // bool | TypeHierarchyOptions | TypeHierarchyRegistrationOptions + + // The server provides inline value support. + // + // @since 3.17.0 + InlineValueProvider any `json:"inlineValueProvider,omitempty"` // bool | InlineValueOptions | InlineValueRegistrationOptions + + // The server provides inlay hint support. + // + // @since 3.17.0 + InlayHintProvider any `json:"inlayHintProvider,omitempty"` // bool | InlayHintOptions | InlayHintRegistrationOptions // The server has support for pull model diagnostics. // // @since 3.17.0 DiagnosticProvider any `json:"diagnosticProvider,omitempty"` // DiagnosticOptions | DiagnosticRegistrationOptions - // Experimental server capabilities. + // The server provides workspace symbol support. + // + // @since 3.17.0 + WorkspaceSymbolProvider any `json:"workspaceSymbolProvider,omitempty"` // bool | WorkspaceSymbolOptions + + // Workspace-specific server capabilities. + Workspace *WorkspaceServerCapabilities `json:"workspace,omitempty"` + + // Experimental server capabilities. The value can be any JSON type. Experimental *LSPAny `json:"experimental,omitempty"` } -// TextDocumentSyncKind Defines how the host (editor) should sync document changes to the language server. +// TextDocumentSyncKind defines how the host (editor) should sync document +// changes to the language server. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentSyncKind type TextDocumentSyncKind int @@ -57,75 +167,222 @@ const ( // Documents are synced by always sending the full content of the document. TextDocumentSyncKindFull TextDocumentSyncKind = 1 - // Documents are synced by sending the full content on open and close. - // After that only incremental updates to the document are sent. + // Documents are synced by sending the full content on open and close. After + // that only incremental updates to the document are sent. TextDocumentSyncKindIncremental TextDocumentSyncKind = 2 ) -// CompletionOptions used during `initialize` or server capabilities registration. +// TextDocumentSyncOptions defines detailed text document synchronization +// options. +// +// See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentSyncOptions +type TextDocumentSyncOptions struct { + OpenClose bool `json:"openClose,omitempty"` + Change TextDocumentSyncKind `json:"change,omitempty"` + WillSave bool `json:"willSave,omitempty"` + WillSaveWaitUntil bool `json:"willSaveWaitUntil,omitempty"` + Save any `json:"save,omitempty"` // bool | SaveOptions +} + +// SaveOptions options for save notifications. +type SaveOptions struct { + IncludeText bool `json:"includeText,omitempty"` +} + +// CompletionOptions used during `initialize` or server capabilities +// registration. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionOptions type CompletionOptions struct { WorkDoneProgressOptions - // The additional characters, beyond the defaults provided by the client (typically - // [a-zA-Z]), that should automatically trigger a completion request. For example - // `.` in JavaScript represents the beginning of an object property or method and is - // thus a good candidate for triggering a completion request. - // - // Most tools trigger a completion request automatically without explicitly - // requesting it using a keyboard shortcut (e.g. Ctrl+Space). Typically they - // do so when the user starts to type an identifier. For example if the user - // types `c` in a JavaScript file code complete will automatically pop up - // present `console` besides others as a completion item. Characters that - // make up identifiers don't need to be listed here. + // The additional characters that should trigger completion. TriggerCharacters []string `json:"triggerCharacters,omitempty"` - // The list of all possible characters that commit a completion. This field - // can be used if clients don't support individual commit characters per - // completion item. See client capability - // `completion.completionItem.commitCharactersSupport`. - // - // If a server provides both `allCommitCharacters` and commit characters on - // an individual completion item the ones on the completion item win. + // Characters that commit a completion item. // // @since 3.2.0 AllCommitCharacters []string `json:"allCommitCharacters,omitempty"` - // The server provides support to resolve additional - // information for a completion item. + // The server supports completion item resolve. ResolveProvider *bool `json:"resolveProvider,omitempty"` - // The server supports the following `CompletionItem` specific - // capabilities. + // Completion item-specific server capabilities. // // @since 3.17.0 - CompletionItem *CompletionItemCapability `json:"completionItem,omitempty"` + CompletionItem *CompletionOptionsCompletionItem `json:"completionItem,omitempty"` } -// CompletionItemCapability Capabilities specific to the `CompletionItem`. +// CompletionOptionsCompletionItem capabilities specific to completion items. // // @since 3.17.0 -type CompletionItemCapability struct { - // The server has support for completion item label details (see also `CompletionItemLabelDetails`) - // when receiving a completion item in a resolve call. - // @since 3.17.0 +type CompletionOptionsCompletionItem struct { + // The server supports `CompletionItemLabelDetails` in resolve responses. LabelDetailsSupport *bool `json:"labelDetailsSupport,omitempty"` } -// SignatureHelpOptions Server capabilities for signature help requests. +// Backward compatible alias. +type CompletionItemCapability = CompletionOptionsCompletionItem + +// SignatureHelpOptions server capabilities for signature help requests. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#signatureHelpOptions type SignatureHelpOptions struct { - // The characters that trigger signature help automatically. - TriggerCharacters []string `json:"triggerCharacters,omitempty"` - - // List of characters that re-trigger signature help. - // These are typically the same as `triggerCharacters`, but may contain additional characters. - // @since 3.2.0 + TriggerCharacters []string `json:"triggerCharacters,omitempty"` RetriggerCharacters []string `json:"retriggerCharacters,omitempty"` } +// WorkDoneProgressOptions indicates if a request supports work-done progress +// reporting. +type WorkDoneProgressOptions struct { + WorkDoneProgress bool `json:"workDoneProgress,omitempty"` +} + +// HoverOptions describes hover support details. +type HoverOptions = WorkDoneProgressOptions + +// DeclarationOptions describes declaration support details. +// +// @since 3.14.0 +type DeclarationOptions = WorkDoneProgressOptions + +// DefinitionOptions describes definition support details. +type DefinitionOptions = WorkDoneProgressOptions + +// TypeDefinitionOptions describes type definition support details. +// +// @since 3.6.0 +type TypeDefinitionOptions = WorkDoneProgressOptions + +// ImplementationOptions describes implementation support details. +// +// @since 3.6.0 +type ImplementationOptions = WorkDoneProgressOptions + +// ReferenceOptions describes references support details. +type ReferenceOptions = WorkDoneProgressOptions + +// DocumentHighlightOptions describes document highlight support details. +type DocumentHighlightOptions = WorkDoneProgressOptions + +// DocumentSymbolOptions describes document symbol support details. +type DocumentSymbolOptions = WorkDoneProgressOptions + +// CodeActionOptions server capability for code actions. +type CodeActionOptions struct { + WorkDoneProgressOptions + + CodeActionKinds []CodeActionKind `json:"codeActionKinds,omitempty"` + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// CodeLensOptions server capability for code lenses. +type CodeLensOptions struct { + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// DocumentLinkOptions server capability for document links. +type DocumentLinkOptions struct { + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// DocumentColorOptions describes document color support details. +// +// @since 3.6.0 +type DocumentColorOptions = WorkDoneProgressOptions + +// DocumentFormattingOptions describes formatting support details. +type DocumentFormattingOptions = WorkDoneProgressOptions + +// DocumentRangeFormattingOptions describes range formatting support details. +type DocumentRangeFormattingOptions = WorkDoneProgressOptions + +// DocumentOnTypeFormattingOptions server capability for on-type formatting. +type DocumentOnTypeFormattingOptions struct { + FirstTriggerCharacter string `json:"firstTriggerCharacter"` + MoreTriggerCharacter []string `json:"moreTriggerCharacter,omitempty"` +} + +// RenameOptions server capability for rename. +type RenameOptions struct { + WorkDoneProgressOptions + PrepareProvider bool `json:"prepareProvider,omitempty"` +} + +// FoldingRangeOptions describes folding range support details. +// +// @since 3.10.0 +type FoldingRangeOptions = WorkDoneProgressOptions + +// ExecuteCommandOptions server capability for execute command. +type ExecuteCommandOptions struct { + WorkDoneProgressOptions + Commands []string `json:"commands"` +} + +// SelectionRangeOptions describes selection range support details. +// +// @since 3.15.0 +type SelectionRangeOptions = WorkDoneProgressOptions + +// LinkedEditingRangeOptions describes linked editing range support details. +// +// @since 3.16.0 +type LinkedEditingRangeOptions = WorkDoneProgressOptions + +// CallHierarchyOptions describes call hierarchy support details. +// +// @since 3.16.0 +type CallHierarchyOptions = WorkDoneProgressOptions + +// SemanticTokensLegend describes token types and token modifiers a server uses. +// +// @since 3.16.0 +type SemanticTokensLegend struct { + TokenTypes []string `json:"tokenTypes"` + TokenModifiers []string `json:"tokenModifiers"` +} + +// SemanticTokensOptionsFull indicates support for full document semantic tokens. +// +// @since 3.16.0 +type SemanticTokensOptionsFull struct { + Delta bool `json:"delta,omitempty"` +} + +// SemanticTokensOptions server capability for semantic tokens. +// +// @since 3.16.0 +type SemanticTokensOptions struct { + WorkDoneProgressOptions + Legend SemanticTokensLegend `json:"legend"` + Range any `json:"range,omitempty"` // bool | map[string]any + Full any `json:"full,omitempty"` // bool | SemanticTokensOptionsFull +} + +// MonikerOptions describes moniker support details. +// +// @since 3.16.0 +type MonikerOptions = WorkDoneProgressOptions + +// TypeHierarchyOptions describes type hierarchy support details. +// +// @since 3.17.0 +type TypeHierarchyOptions = WorkDoneProgressOptions + +// InlineValueOptions describes inline value support details. +// +// @since 3.17.0 +type InlineValueOptions = WorkDoneProgressOptions + +// InlayHintOptions server capability for inlay hints. +// +// @since 3.17.0 +type InlayHintOptions struct { + WorkDoneProgressOptions + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + // DiagnosticOptions registration options to configure pull diagnostics. // // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticOptions @@ -134,22 +391,139 @@ type SignatureHelpOptions struct { type DiagnosticOptions struct { WorkDoneProgressOptions - // An optional identifier under which the diagnostics are - // managed by the client. - Identifier string `json:"identifier,omitempty"` - - // Whether the language has inter file dependencies meaning that - // editing code in one file can result in a different diagnostic - // set in another file. Inter file dependencies are common for - // most programming languages and typically uncommon for linters. - InterFileDependencies bool `json:"interFileDependencies"` - - // The server provides support for workspace diagnostics as well. - WorkspaceDiagnostics bool `json:"workspaceDiagnostics"` + Identifier string `json:"identifier,omitempty"` + InterFileDependencies bool `json:"interFileDependencies"` + WorkspaceDiagnostics bool `json:"workspaceDiagnostics"` } -// WorkDoneProgressOptions indicates if a request supports work-done progress reporting. -type WorkDoneProgressOptions struct { - // WorkDoneProgress is a flag that indicates whether progress reporting is supported. - WorkDoneProgress bool `json:"workDoneProgress,omitempty"` +// WorkspaceSymbolOptions server capability for workspace symbols. +// +// @since 3.17.0 +type WorkspaceSymbolOptions struct { + WorkDoneProgressOptions + ResolveProvider bool `json:"resolveProvider,omitempty"` +} + +// WorkspaceServerCapabilities workspace-level server capabilities. +type WorkspaceServerCapabilities struct { + WorkspaceFolders *WorkspaceFoldersServerCapabilities `json:"workspaceFolders,omitempty"` + FileOperations *FileOperationOptions `json:"fileOperations,omitempty"` +} + +// WorkspaceFoldersServerCapabilities server support for workspace folders. +type WorkspaceFoldersServerCapabilities struct { + Supported bool `json:"supported,omitempty"` + ChangeNotifications any `json:"changeNotifications,omitempty"` // string | bool +} + +// FileOperationOptions server support for file operation requests/notifications. +// +// @since 3.16.0 +type FileOperationOptions struct { + DidCreate *FileOperationRegistrationOptions `json:"didCreate,omitempty"` + WillCreate *FileOperationRegistrationOptions `json:"willCreate,omitempty"` + DidRename *FileOperationRegistrationOptions `json:"didRename,omitempty"` + WillRename *FileOperationRegistrationOptions `json:"willRename,omitempty"` + DidDelete *FileOperationRegistrationOptions `json:"didDelete,omitempty"` + WillDelete *FileOperationRegistrationOptions `json:"willDelete,omitempty"` +} + +// FileOperationRegistrationOptions registration options for file operations. +// +// @since 3.16.0 +type FileOperationRegistrationOptions struct { + Filters []FileOperationFilter `json:"filters"` +} + +// FileOperationFilter describes a filter for file operation events. +// +// @since 3.16.0 +type FileOperationFilter struct { + Scheme string `json:"scheme,omitempty"` + Pattern FileOperationPattern `json:"pattern"` +} + +// FileOperationPatternKind describes whether a file operation pattern applies +// to files or folders. +// +// @since 3.16.0 +type FileOperationPatternKind string + +const ( + FileOperationPatternKindFile FileOperationPatternKind = "file" + FileOperationPatternKindFolder FileOperationPatternKind = "folder" +) + +// FileOperationPatternOptions options for file operation patterns. +// +// @since 3.16.0 +type FileOperationPatternOptions struct { + IgnoreCase bool `json:"ignoreCase,omitempty"` +} + +// FileOperationPattern glob pattern for file operations. +// +// @since 3.16.0 +type FileOperationPattern struct { + Glob string `json:"glob"` + Matches FileOperationPatternKind `json:"matches,omitempty"` + Options *FileOperationPatternOptions `json:"options,omitempty"` +} + +// Registration option aliases with spec names. +type ( + DeclarationRegistrationOptions = TextDocumentRegistrationOptions + TypeDefinitionRegistrationOptions = TextDocumentRegistrationOptions + ImplementationRegistrationOptions = TextDocumentRegistrationOptions + ColorProviderRegistrationOptions = TextDocumentRegistrationOptions + FoldingRangeRegistrationOptions = TextDocumentRegistrationOptions + SelectionRangeRegistrationOptions = TextDocumentRegistrationOptions + LinkedEditingRangeRegistrationOptions = TextDocumentRegistrationOptions + CallHierarchyRegistrationOptions = TextDocumentRegistrationOptions + MonikerRegistrationOptions = TextDocumentRegistrationOptions + TypeHierarchyRegistrationOptions = TextDocumentRegistrationOptions + InlineValueRegistrationOptions = TextDocumentRegistrationOptions + InlayHintRegistrationOptions = TextDocumentRegistrationOptions + SemanticTokensRegistrationOptions = TextDocumentRegistrationOptions + DiagnosticRegistrationOptions = TextDocumentRegistrationOptions + NotebookDocumentSyncRegistrationOptions = TextDocumentRegistrationOptions +) + +// TextDocumentRegistrationOptions registration options for text document scoped +// capabilities. +type TextDocumentRegistrationOptions struct { + DocumentSelector LSPAny `json:"documentSelector,omitempty"` +} + +// NotebookDocumentSyncOptions server options for notebook synchronization. +// +// @since 3.17.0 +type NotebookDocumentSyncOptions struct { + NotebookSelector []NotebookDocumentSyncOptionsNotebookSelector `json:"notebookSelector"` + Save bool `json:"save,omitempty"` +} + +// NotebookDocumentSyncOptionsNotebookSelector selects matching notebooks and +// cell languages. +// +// @since 3.17.0 +type NotebookDocumentSyncOptionsNotebookSelector struct { + Notebook any `json:"notebook,omitempty"` // string | NotebookDocumentFilter + Cells []NotebookDocumentSyncOptionsNotebookSelectorCells `json:"cells,omitempty"` +} + +// NotebookDocumentSyncOptionsNotebookSelectorCells cell language selector. +// +// @since 3.17.0 +type NotebookDocumentSyncOptionsNotebookSelectorCells struct { + Language string `json:"language"` +} + +// NotebookDocumentFilter selects notebooks by type, scheme and pattern. +// +// @since 3.17.0 +type NotebookDocumentFilter struct { + NotebookType string `json:"notebookType,omitempty"` + Scheme string `json:"scheme,omitempty"` + Pattern string `json:"pattern,omitempty"` } diff --git a/capabilities_server_test.go b/capabilities_server_test.go index c345436..7deb521 100644 --- a/capabilities_server_test.go +++ b/capabilities_server_test.go @@ -93,3 +93,229 @@ func Test_CapabilitiesServer_MarshalOmitEmptyFields(t *testing.T) { t.Fatalf("expected empty JSON object from zero-value capabilities, got: %s", string(data)) } } + +func Test_CapabilitiesServer_UnmarshalExtendedFields(t *testing.T) { + data := []byte(`{ + "textDocumentSync": { + "openClose": true, + "change": 2, + "save": {"includeText": true} + }, + "notebookDocumentSync": { + "notebookSelector": [ + { + "notebook": {"notebookType": "jupyter-notebook"}, + "cells": [{"language": "python"}] + } + ], + "save": true + }, + "hoverProvider": {"workDoneProgress": true}, + "declarationProvider": true, + "typeDefinitionProvider": {"workDoneProgress": true}, + "implementationProvider": true, + "referencesProvider": {"workDoneProgress": true}, + "documentHighlightProvider": true, + "documentSymbolProvider": {"workDoneProgress": true}, + "codeActionProvider": {"codeActionKinds": ["quickfix"], "resolveProvider": true}, + "codeLensProvider": {"resolveProvider": true}, + "documentLinkProvider": {"resolveProvider": true}, + "colorProvider": true, + "documentFormattingProvider": true, + "documentRangeFormattingProvider": true, + "documentOnTypeFormattingProvider": {"firstTriggerCharacter": ";", "moreTriggerCharacter": [","]}, + "renameProvider": {"prepareProvider": true}, + "foldingRangeProvider": true, + "executeCommandProvider": {"commands": ["laravel.run"], "workDoneProgress": true}, + "selectionRangeProvider": {"workDoneProgress": true}, + "linkedEditingRangeProvider": true, + "callHierarchyProvider": true, + "semanticTokensProvider": { + "legend": {"tokenTypes": ["class"], "tokenModifiers": ["declaration"]}, + "full": true + }, + "monikerProvider": true, + "typeHierarchyProvider": true, + "inlineValueProvider": true, + "inlayHintProvider": {"resolveProvider": true}, + "workspaceSymbolProvider": {"resolveProvider": true}, + "workspace": { + "workspaceFolders": {"supported": true, "changeNotifications": "workspaceFolders"}, + "fileOperations": { + "didCreate": { + "filters": [ + {"scheme": "file", "pattern": {"glob": "**/*.go"}} + ] + } + } + } + }`) + + var decoded protocol.ServerCapabilities + if err := json.Unmarshal(data, &decoded); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + if decoded.CodeLensProvider == nil || !decoded.CodeLensProvider.ResolveProvider { + t.Fatalf("expected codeLensProvider.resolveProvider=true") + } + + if decoded.DocumentLinkProvider == nil || !decoded.DocumentLinkProvider.ResolveProvider { + t.Fatalf("expected documentLinkProvider.resolveProvider=true") + } + + if decoded.DocumentOnTypeFormattingProvider == nil || decoded.DocumentOnTypeFormattingProvider.FirstTriggerCharacter != ";" { + t.Fatalf("expected documentOnTypeFormattingProvider.firstTriggerCharacter=';' got %#v", decoded.DocumentOnTypeFormattingProvider) + } + + if decoded.ExecuteCommandProvider == nil || len(decoded.ExecuteCommandProvider.Commands) != 1 || decoded.ExecuteCommandProvider.Commands[0] != "laravel.run" { + t.Fatalf("expected executeCommandProvider.commands to contain laravel.run") + } + + if decoded.Workspace == nil || decoded.Workspace.WorkspaceFolders == nil || !decoded.Workspace.WorkspaceFolders.Supported { + t.Fatalf("expected workspace.workspaceFolders.supported=true") + } + + tds, ok := decoded.TextDocumentSync.(map[string]any) + if !ok { + t.Fatalf("expected textDocumentSync object, got %#v", decoded.TextDocumentSync) + } + + if openClose, ok := tds["openClose"].(bool); !ok || !openClose { + t.Fatalf("expected textDocumentSync.openClose=true, got %#v", tds["openClose"]) + } + + hover, ok := decoded.HoverProvider.(map[string]any) + if !ok { + t.Fatalf("expected hoverProvider object, got %#v", decoded.HoverProvider) + } + + if wdp, ok := hover["workDoneProgress"].(bool); !ok || !wdp { + t.Fatalf("expected hoverProvider.workDoneProgress=true, got %#v", hover["workDoneProgress"]) + } + + if decl, ok := decoded.DeclarationProvider.(bool); !ok || !decl { + t.Fatalf("expected declarationProvider=true, got %#v", decoded.DeclarationProvider) + } + + if sem, ok := decoded.SemanticTokensProvider.(map[string]any); !ok || sem["legend"] == nil { + t.Fatalf("expected semanticTokensProvider.legend, got %#v", decoded.SemanticTokensProvider) + } +} + +func Test_CapabilitiesServer_MarshalExtendedFields(t *testing.T) { + resolve := true + original := protocol.ServerCapabilities{ + PositionEncoding: &[]protocol.PositionEncodingKind{protocol.PositionEncodingKindUTF16}[0], + TextDocumentSync: protocol.TextDocumentSyncOptions{ + OpenClose: true, + Change: protocol.TextDocumentSyncKindIncremental, + Save: protocol.SaveOptions{IncludeText: true}, + }, + HoverProvider: protocol.HoverOptions{WorkDoneProgress: true}, + CompletionProvider: &protocol.CompletionOptions{ + ResolveProvider: &resolve, + CompletionItem: &protocol.CompletionOptionsCompletionItem{ + LabelDetailsSupport: &resolve, + }, + }, + DeclarationProvider: protocol.DeclarationOptions{WorkDoneProgress: true}, + DefinitionProvider: true, + CodeActionProvider: protocol.CodeActionOptions{ + CodeActionKinds: []protocol.CodeActionKind{protocol.CodeActionQuickFix}, + ResolveProvider: true, + }, + CodeLensProvider: &protocol.CodeLensOptions{ResolveProvider: true}, + DocumentLinkProvider: &protocol.DocumentLinkOptions{ + ResolveProvider: true, + }, + DocumentOnTypeFormattingProvider: &protocol.DocumentOnTypeFormattingOptions{ + FirstTriggerCharacter: ";", + MoreTriggerCharacter: []string{","}, + }, + RenameProvider: protocol.RenameOptions{PrepareProvider: true}, + ExecuteCommandProvider: &protocol.ExecuteCommandOptions{ + Commands: []string{"laravel.run"}, + }, + SemanticTokensProvider: protocol.SemanticTokensOptions{ + Legend: protocol.SemanticTokensLegend{ + TokenTypes: []string{"class"}, + TokenModifiers: []string{"declaration"}, + }, + Full: true, + }, + DiagnosticProvider: protocol.DiagnosticOptions{ + InterFileDependencies: true, + WorkspaceDiagnostics: true, + }, + WorkspaceSymbolProvider: protocol.WorkspaceSymbolOptions{ResolveProvider: true}, + Workspace: &protocol.WorkspaceServerCapabilities{ + WorkspaceFolders: &protocol.WorkspaceFoldersServerCapabilities{ + Supported: true, + ChangeNotifications: "workspaceFolders", + }, + FileOperations: &protocol.FileOperationOptions{ + DidCreate: &protocol.FileOperationRegistrationOptions{ + Filters: []protocol.FileOperationFilter{{ + Scheme: "file", + Pattern: protocol.FileOperationPattern{ + Glob: "**/*.go", + }, + }}, + }, + }, + }, + } + + data, err := json.Marshal(original) + if err != nil { + t.Fatalf("marshal failed: %v", err) + } + + var payload map[string]any + if err := json.Unmarshal(data, &payload); err != nil { + t.Fatalf("unmarshal failed: %v", err) + } + + if _, ok := payload["textDocumentSync"]; !ok { + t.Fatalf("expected textDocumentSync in payload: %s", string(data)) + } + + if _, ok := payload["hoverProvider"]; !ok { + t.Fatalf("expected hoverProvider in payload: %s", string(data)) + } + + if _, ok := payload["declarationProvider"]; !ok { + t.Fatalf("expected declarationProvider in payload: %s", string(data)) + } + + if _, ok := payload["codeLensProvider"]; !ok { + t.Fatalf("expected codeLensProvider in payload: %s", string(data)) + } + + if _, ok := payload["documentOnTypeFormattingProvider"]; !ok { + t.Fatalf("expected documentOnTypeFormattingProvider in payload: %s", string(data)) + } + + if _, ok := payload["semanticTokensProvider"]; !ok { + t.Fatalf("expected semanticTokensProvider in payload: %s", string(data)) + } + + workspace, ok := payload["workspace"].(map[string]any) + if !ok { + t.Fatalf("expected workspace object, got %#v", payload["workspace"]) + } + + if _, ok := workspace["workspaceFolders"]; !ok { + t.Fatalf("expected workspace.workspaceFolders in payload: %s", string(data)) + } + + fileOps, ok := workspace["fileOperations"].(map[string]any) + if !ok { + t.Fatalf("expected workspace.fileOperations object, got %#v", workspace["fileOperations"]) + } + + if _, ok := fileOps["didCreate"]; !ok { + t.Fatalf("expected workspace.fileOperations.didCreate in payload: %s", string(data)) + } +}