From 6a4bdedc80337e3dcb39eb321d34faaa48e8c25c 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 1de878af3..31f6e8609 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 9cd74c96e..f337c1ac4 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 < BaseRequest 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 5a3144be7..8aa27869d 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 21d6e7d4b..5e206f0eb 100644 --- a/lib/ruby_lsp/requests/diagnostics.rb +++ b/lib/ruby_lsp/requests/diagnostics.rb @@ -21,6 +21,18 @@ module Requests class Diagnostics < BaseRequest 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) super(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 1f4cb9d63..d0a23e74b 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 < BaseRequest 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) }