From 5c9d9bd76dab48888dc8ac5877afe52f36e895d0 Mon Sep 17 00:00:00 2001 From: Stan Lo Date: Mon, 18 Dec 2023 18:30:33 +0000 Subject: [PATCH] Move provider definition to individual requests Some provider definitions require the request's data like constants. Instead of exposing all those to the executor, it's better to define the providers inside the request classes. --- lib/ruby_lsp/executor.rb | 87 +++---------------- lib/ruby_lsp/requests/code_actions.rb | 9 ++ lib/ruby_lsp/requests/code_lens.rb | 9 ++ lib/ruby_lsp/requests/completion.rb | 15 ++++ lib/ruby_lsp/requests/diagnostics.rb | 12 +++ lib/ruby_lsp/requests/document_link.rb | 9 ++ lib/ruby_lsp/requests/document_symbol.rb | 14 +++ lib/ruby_lsp/requests/folding_ranges.rb | 9 ++ lib/ruby_lsp/requests/hover.rb | 9 ++ lib/ruby_lsp/requests/inlay_hints.rb | 9 ++ lib/ruby_lsp/requests/on_type_formatting.rb | 12 +++ .../requests/semantic_highlighting.rb | 17 ++++ lib/ruby_lsp/requests/signature_help.rb | 12 +++ 13 files changed, 148 insertions(+), 75 deletions(-) diff --git a/lib/ruby_lsp/executor.rb b/lib/ruby_lsp/executor.rb index ac112c9aa..5c2a80a68 100644 --- a/lib/ruby_lsp/executor.rb +++ b/lib/ruby_lsp/executor.rb @@ -663,81 +663,18 @@ def initialize_request(options) Hash.new(true) end - document_symbol_provider = if enabled_features["documentSymbols"] - Interface::DocumentSymbolClientCapabilities.new( - hierarchical_document_symbol_support: true, - symbol_kind: { - value_set: (Constant::SymbolKind::FILE..Constant::SymbolKind::TYPE_PARAMETER).to_a, - }, - ) - end - - document_link_provider = if enabled_features["documentLink"] - Interface::DocumentLinkOptions.new(resolve_provider: false) - end - - code_lens_provider = if enabled_features["codeLens"] - Interface::CodeLensOptions.new(resolve_provider: false) - end - - hover_provider = if enabled_features["hover"] - Interface::HoverClientCapabilities.new(dynamic_registration: false) - end - - folding_ranges_provider = if enabled_features["foldingRanges"] - Interface::FoldingRangeClientCapabilities.new(line_folding_only: true) - end - - semantic_tokens_provider = if enabled_features["semanticHighlighting"] - Interface::SemanticTokensRegistrationOptions.new( - document_selector: { scheme: "file", language: "ruby" }, - legend: Interface::SemanticTokensLegend.new( - token_types: Requests::SemanticHighlighting::TOKEN_TYPES.keys, - token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys, - ), - range: true, - full: { delta: false }, - ) - end - - diagnostics_provider = if enabled_features["diagnostics"] - { - interFileDependencies: false, - workspaceDiagnostics: false, - } - end - - on_type_formatting_provider = if enabled_features["onTypeFormatting"] - Interface::DocumentOnTypeFormattingOptions.new( - first_trigger_character: "{", - more_trigger_character: ["\n", "|", "d"], - ) - end - - code_action_provider = if enabled_features["codeActions"] - Interface::CodeActionOptions.new(resolve_provider: true) - end - - inlay_hint_provider = if enabled_features["inlayHint"] - Interface::InlayHintOptions.new(resolve_provider: false) - end - - completion_provider = if enabled_features["completion"] - Interface::CompletionOptions.new( - resolve_provider: false, - trigger_characters: ["/"], - completion_item: { - labelDetailsSupport: true, - }, - ) - end - - signature_help_provider = if enabled_features["signatureHelp"] - # Identifier characters are automatically included, such as A-Z, a-z, 0-9, _, * or : - Interface::SignatureHelpOptions.new( - trigger_characters: ["(", " ", ","], - ) - end + document_symbol_provider = Requests::DocumentSymbol.provider if enabled_features["documentSymbols"] + document_link_provider = Requests::DocumentLink.provider if enabled_features["documentLink"] + code_lens_provider = Requests::CodeLens.provider if enabled_features["codeLens"] + hover_provider = Requests::Hover.provider if enabled_features["hover"] + folding_ranges_provider = Requests::FoldingRanges.provider if enabled_features["foldingRanges"] + semantic_tokens_provider = Requests::SemanticHighlighting.provider if enabled_features["semanticHighlighting"] + diagnostics_provider = Requests::Diagnostics.provider if enabled_features["diagnostics"] + on_type_formatting_provider = Requests::OnTypeFormatting.provider if enabled_features["onTypeFormatting"] + code_action_provider = Requests::CodeActions.provider if enabled_features["codeActions"] + inlay_hint_provider = Requests::InlayHints.provider if enabled_features["inlayHint"] + completion_provider = Requests::Completion.provider if enabled_features["completion"] + signature_help_provider = Requests::SignatureHelp.provider if enabled_features["signatureHelp"] # Dynamically registered capabilities file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles) diff --git a/lib/ruby_lsp/requests/code_actions.rb b/lib/ruby_lsp/requests/code_actions.rb index 282c8183e..b82880ba3 100644 --- a/lib/ruby_lsp/requests/code_actions.rb +++ b/lib/ruby_lsp/requests/code_actions.rb @@ -19,6 +19,15 @@ module Requests class CodeActions extend T::Sig + class << self + extend T::Sig + + sig { returns(Interface::CodeActionOptions) } + def provider + Interface::CodeActionOptions.new(resolve_provider: true) + end + end + sig do params( document: Document, diff --git a/lib/ruby_lsp/requests/code_lens.rb b/lib/ruby_lsp/requests/code_lens.rb index cd2aaa87b..ca1557fdd 100644 --- a/lib/ruby_lsp/requests/code_lens.rb +++ b/lib/ruby_lsp/requests/code_lens.rb @@ -26,6 +26,15 @@ class CodeLens < ExtensibleListener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::CodeLensOptions) } + def provider + Interface::CodeLensOptions.new(resolve_provider: false) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::CodeLens] } } BASE_COMMAND = T.let( diff --git a/lib/ruby_lsp/requests/completion.rb b/lib/ruby_lsp/requests/completion.rb index 7acd50896..019e3295d 100644 --- a/lib/ruby_lsp/requests/completion.rb +++ b/lib/ruby_lsp/requests/completion.rb @@ -26,6 +26,21 @@ class Completion < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::CompletionOptions) } + def provider + Interface::CompletionOptions.new( + resolve_provider: false, + trigger_characters: ["/"], + completion_item: { + labelDetailsSupport: true, + }, + ) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::CompletionItem] } } sig { override.returns(ResponseType) } diff --git a/lib/ruby_lsp/requests/diagnostics.rb b/lib/ruby_lsp/requests/diagnostics.rb index 8268d79bf..eb1e4ddc8 100644 --- a/lib/ruby_lsp/requests/diagnostics.rb +++ b/lib/ruby_lsp/requests/diagnostics.rb @@ -21,6 +21,18 @@ module Requests class Diagnostics extend T::Sig + class << self + extend T::Sig + + sig { returns(T::Hash[Symbol, T::Boolean]) } + def provider + { + interFileDependencies: false, + workspaceDiagnostics: false, + } + end + end + sig { params(document: Document).void } def initialize(document) @document = document diff --git a/lib/ruby_lsp/requests/document_link.rb b/lib/ruby_lsp/requests/document_link.rb index 52d0bed1c..4928ebee1 100644 --- a/lib/ruby_lsp/requests/document_link.rb +++ b/lib/ruby_lsp/requests/document_link.rb @@ -22,6 +22,15 @@ class DocumentLink < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::DocumentLinkOptions) } + def provider + Interface::DocumentLinkOptions.new(resolve_provider: false) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::DocumentLink] } } GEM_TO_VERSION_MAP = T.let( diff --git a/lib/ruby_lsp/requests/document_symbol.rb b/lib/ruby_lsp/requests/document_symbol.rb index be78b1466..77faee853 100644 --- a/lib/ruby_lsp/requests/document_symbol.rb +++ b/lib/ruby_lsp/requests/document_symbol.rb @@ -30,6 +30,20 @@ class DocumentSymbol < ExtensibleListener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::DocumentSymbolClientCapabilities) } + def provider + Interface::DocumentSymbolClientCapabilities.new( + hierarchical_document_symbol_support: true, + symbol_kind: { + value_set: (Constant::SymbolKind::FILE..Constant::SymbolKind::TYPE_PARAMETER).to_a, + }, + ) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::DocumentSymbol] } } ATTR_ACCESSORS = T.let([:attr_reader, :attr_writer, :attr_accessor].freeze, T::Array[Symbol]) diff --git a/lib/ruby_lsp/requests/folding_ranges.rb b/lib/ruby_lsp/requests/folding_ranges.rb index 0bdd65951..02ab560ea 100644 --- a/lib/ruby_lsp/requests/folding_ranges.rb +++ b/lib/ruby_lsp/requests/folding_ranges.rb @@ -19,6 +19,15 @@ class FoldingRanges < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::FoldingRangeClientCapabilities) } + def provider + Interface::FoldingRangeClientCapabilities.new(line_folding_only: true) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::FoldingRange] } } sig { params(comments: T::Array[Prism::Comment], dispatcher: Prism::Dispatcher).void } diff --git a/lib/ruby_lsp/requests/hover.rb b/lib/ruby_lsp/requests/hover.rb index 6f4cf5161..4cf969159 100644 --- a/lib/ruby_lsp/requests/hover.rb +++ b/lib/ruby_lsp/requests/hover.rb @@ -17,6 +17,15 @@ class Hover < ExtensibleListener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::HoverClientCapabilities) } + def provider + Interface::HoverClientCapabilities.new(dynamic_registration: false) + end + end + ResponseType = type_member { { fixed: T.nilable(Interface::Hover) } } ALLOWED_TARGETS = T.let( diff --git a/lib/ruby_lsp/requests/inlay_hints.rb b/lib/ruby_lsp/requests/inlay_hints.rb index 9bca78a71..f43fcd4a3 100644 --- a/lib/ruby_lsp/requests/inlay_hints.rb +++ b/lib/ruby_lsp/requests/inlay_hints.rb @@ -40,6 +40,15 @@ class InlayHints < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::InlayHintOptions) } + def provider + Interface::InlayHintOptions.new(resolve_provider: false) + end + end + ResponseType = type_member { { fixed: T::Array[Interface::InlayHint] } } RESCUE_STRING_LENGTH = T.let("rescue".length, Integer) diff --git a/lib/ruby_lsp/requests/on_type_formatting.rb b/lib/ruby_lsp/requests/on_type_formatting.rb index f74e82611..0e3c7c18c 100644 --- a/lib/ruby_lsp/requests/on_type_formatting.rb +++ b/lib/ruby_lsp/requests/on_type_formatting.rb @@ -18,6 +18,18 @@ module Requests class OnTypeFormatting extend T::Sig + class << self + extend T::Sig + + sig { returns(Interface::DocumentOnTypeFormattingOptions) } + def provider + Interface::DocumentOnTypeFormattingOptions.new( + first_trigger_character: "{", + more_trigger_character: ["\n", "|", "d"], + ) + end + end + END_REGEXES = T.let( [ /\b(if|unless|for|while|class|module|until|def|case)\b.*/, diff --git a/lib/ruby_lsp/requests/semantic_highlighting.rb b/lib/ruby_lsp/requests/semantic_highlighting.rb index 13547cfd7..300c6f141 100644 --- a/lib/ruby_lsp/requests/semantic_highlighting.rb +++ b/lib/ruby_lsp/requests/semantic_highlighting.rb @@ -22,6 +22,23 @@ class SemanticHighlighting < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::SemanticTokensRegistrationOptions) } + def provider + Interface::SemanticTokensRegistrationOptions.new( + document_selector: { scheme: "file", language: "ruby" }, + legend: Interface::SemanticTokensLegend.new( + token_types: Requests::SemanticHighlighting::TOKEN_TYPES.keys, + token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys, + ), + range: true, + full: { delta: false }, + ) + end + end + ResponseType = type_member { { fixed: T::Array[SemanticToken] } } TOKEN_TYPES = T.let( diff --git a/lib/ruby_lsp/requests/signature_help.rb b/lib/ruby_lsp/requests/signature_help.rb index 7ee379ce7..809b66c45 100644 --- a/lib/ruby_lsp/requests/signature_help.rb +++ b/lib/ruby_lsp/requests/signature_help.rb @@ -26,6 +26,18 @@ class SignatureHelp < Listener extend T::Sig extend T::Generic + class << self + extend T::Sig + + sig { returns(Interface::SignatureHelpOptions) } + def provider + # Identifier characters are automatically included, such as A-Z, a-z, 0-9, _, * or : + Interface::SignatureHelpOptions.new( + trigger_characters: ["(", " ", ","], + ) + end + end + ResponseType = type_member { { fixed: T.nilable(T.any(Interface::SignatureHelp, T::Hash[Symbol, T.untyped])) } } sig { override.returns(ResponseType) }