diff --git a/.rubocop.yml b/.rubocop.yml index 4e5efdd6..938ee4ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -36,3 +36,9 @@ Sorbet/StrictSigil: - "**/*.rake" - "test/**/*.rb" - "lib/ruby_lsp/ruby_lsp_rails/server.rb" # we can't assume sorbet-runtime is available + +Layout/LeadingCommentSpace: + AllowRBSInlineAnnotation: true + +Layout/LineLength: + AllowedPatterns: ['\A\s*#:'] # for inline RBS signaturs diff --git a/Gemfile.lock b/Gemfile.lock index 8ec80099..a049e252 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,8 +100,9 @@ GEM irb (1.14.1) rdoc (>= 4.0.0) reline (>= 0.4.2) - json (2.7.6) - language_server-protocol (3.17.0.3) + json (2.10.1) + language_server-protocol (3.17.0.4) + lint_roller (1.1.0) logger (1.6.5) loofah (2.23.1) crass (~> 1.0.2) @@ -142,7 +143,7 @@ GEM nokogiri (1.18.1-x86_64-linux-musl) racc (~> 1.4) parallel (1.26.3) - parser (3.3.6.0) + parser (3.3.7.1) ast (~> 2.4.1) racc prism (1.3.0) @@ -196,20 +197,21 @@ GEM logger rdoc (6.7.0) psych (>= 4.0.0) - regexp_parser (2.9.2) + regexp_parser (2.10.0) reline (0.5.11) io-console (~> 0.5) - rubocop (1.68.0) + rubocop (1.73.1) json (~> 2.3) - language_server-protocol (>= 3.17.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) parallel (~> 1.10) parser (>= 3.3.0.2) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.4, < 3.0) - rubocop-ast (>= 1.32.2, < 2.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.38.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.34.0) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.38.1) parser (>= 3.3.1.0) rubocop-minitest (0.36.0) rubocop (>= 1.61, < 2.0) @@ -218,7 +220,7 @@ GEM rubocop (~> 1.0) rubocop-shopify (2.15.1) rubocop (~> 1.51) - rubocop-sorbet (0.8.7) + rubocop-sorbet (0.8.9) rubocop (>= 1) ruby-lsp (0.23.6) language_server-protocol (~> 3.17.0) @@ -228,18 +230,19 @@ GEM ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) securerandom (0.3.1) - sorbet (0.5.11761) - sorbet-static (= 0.5.11761) - sorbet-runtime (0.5.11761) - sorbet-static (0.5.11761-aarch64-linux) - sorbet-static (0.5.11761-universal-darwin) - sorbet-static (0.5.11761-x86_64-linux) - sorbet-static-and-runtime (0.5.11761) - sorbet (= 0.5.11761) - sorbet-runtime (= 0.5.11761) - spoom (1.5.1) + sorbet (0.5.11865) + sorbet-static (= 0.5.11865) + sorbet-runtime (0.5.11865) + sorbet-static (0.5.11865-aarch64-linux) + sorbet-static (0.5.11865-universal-darwin) + sorbet-static (0.5.11865-x86_64-linux) + sorbet-static-and-runtime (0.5.11865) + sorbet (= 0.5.11865) + sorbet-runtime (= 0.5.11865) + spoom (1.5.4) erubi (>= 1.10.0) prism (>= 0.28.0) + rbi (>= 0.2.3) sorbet-static-and-runtime (>= 0.5.10187) thor (>= 0.19.2) sqlite3 (2.5.0-aarch64-linux-gnu) @@ -264,9 +267,11 @@ GEM timeout (0.4.2) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2024.2) + tzinfo-data (1.2025.1) tzinfo (>= 1.0.0) - unicode-display_width (2.6.0) + unicode-display_width (3.1.4) + unicode-emoji (~> 4.0, >= 4.0.4) + unicode-emoji (4.0.4) uri (1.0.1) useragent (0.16.10) websocket-driver (0.7.6) diff --git a/lib/ruby_lsp/ruby_lsp_rails/addon.rb b/lib/ruby_lsp/ruby_lsp_rails/addon.rb index 0a31d353..048c692f 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/addon.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/addon.rb @@ -23,7 +23,7 @@ class Addon < ::RubyLsp::Addon RUN_MIGRATIONS_TITLE = "Run Migrations" - sig { void } + #: -> void def initialize super @@ -53,12 +53,13 @@ def initialize end end - sig { returns(RunnerClient) } + #: -> RunnerClient def rails_runner_client @addon_mutex.synchronize { @rails_runner_client } end - sig { override.params(global_state: GlobalState, outgoing_queue: Thread::Queue).void } + # @override + #: (GlobalState global_state, Thread::Queue outgoing_queue) -> void def activate(global_state, outgoing_queue) @global_state = global_state @outgoing_queue = outgoing_queue @@ -73,82 +74,56 @@ def activate(global_state, outgoing_queue) @client_mutex.unlock end - sig { override.void } + # @override + #: -> void def deactivate @rails_runner_client.shutdown end - sig { override.returns(String) } + # @override + #: -> String def version VERSION end # Creates a new CodeLens listener. This method is invoked on every CodeLens request - sig do - override.params( - response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens], - uri: URI::Generic, - dispatcher: Prism::Dispatcher, - ).void - end + # @override + #: (ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens] response_builder, URI::Generic uri, Prism::Dispatcher dispatcher) -> void def create_code_lens_listener(response_builder, uri, dispatcher) return unless @global_state CodeLens.new(@rails_runner_client, @global_state, response_builder, uri, dispatcher) end - sig do - override.params( - response_builder: ResponseBuilders::Hover, - node_context: NodeContext, - dispatcher: Prism::Dispatcher, - ).void - end + # @override + #: (ResponseBuilders::Hover response_builder, NodeContext node_context, Prism::Dispatcher dispatcher) -> void def create_hover_listener(response_builder, node_context, dispatcher) return unless @global_state Hover.new(@rails_runner_client, response_builder, node_context, @global_state, dispatcher) end - sig do - override.params( - response_builder: ResponseBuilders::DocumentSymbol, - dispatcher: Prism::Dispatcher, - ).returns(Object) - end + # @override + #: (ResponseBuilders::DocumentSymbol response_builder, Prism::Dispatcher dispatcher) -> Object def create_document_symbol_listener(response_builder, dispatcher) DocumentSymbol.new(response_builder, dispatcher) end - sig do - override.params( - response_builder: ResponseBuilders::CollectionResponseBuilder[T.any( - Interface::Location, Interface::LocationLink - )], - uri: URI::Generic, - node_context: NodeContext, - dispatcher: Prism::Dispatcher, - ).void - end + # @override + #: (ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)] response_builder, URI::Generic uri, NodeContext node_context, Prism::Dispatcher dispatcher) -> void def create_definition_listener(response_builder, uri, node_context, dispatcher) return unless @global_state Definition.new(@rails_runner_client, response_builder, node_context, @global_state.index, dispatcher) end - sig do - override.params( - response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem], - node_context: NodeContext, - dispatcher: Prism::Dispatcher, - uri: URI::Generic, - ).void - end + # @override + #: (ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, NodeContext node_context, Prism::Dispatcher dispatcher, URI::Generic uri) -> void def create_completion_listener(response_builder, node_context, dispatcher, uri) Completion.new(@rails_runner_client, response_builder, node_context, dispatcher, uri) end - sig { params(changes: T::Array[{ uri: String, type: Integer }]).void } + #: (Array[{uri: String, type: Integer}] changes) -> void def workspace_did_change_watched_files(changes) if changes.any? { |c| c[:uri].end_with?("db/schema.rb") || c[:uri].end_with?("structure.sql") } @rails_runner_client.trigger_reload @@ -162,12 +137,14 @@ def workspace_did_change_watched_files(changes) end end - sig { override.returns(String) } + # @override + #: -> String def name "Ruby LSP Rails" end - sig { override.params(title: String).void } + # @override + #: (String title) -> void def handle_window_show_message_response(title) if title == RUN_MIGRATIONS_TITLE @@ -194,7 +171,7 @@ def handle_window_show_message_response(title) private - sig { params(id: String, title: String, percentage: T.nilable(Integer), message: T.nilable(String)).void } + #: (String id, String title, ?percentage: Integer?, ?message: String?) -> void def begin_progress(id, title, percentage: nil, message: nil) return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue @@ -212,21 +189,21 @@ def begin_progress(id, title, percentage: nil, message: nil) ) end - sig { params(id: String, percentage: T.nilable(Integer), message: T.nilable(String)).void } - def report_progress(id, percentage: nil, message: nil) + #: (String id, ?percentage: Integer?, ?message: String?) -> void + def report_progress(id, percentage: nil, message: nil) return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue @outgoing_queue << Notification.progress_report(id, percentage: percentage, message: message) end - sig { params(id: String).void } + #: (String id) -> void def end_progress(id) return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue @outgoing_queue << Notification.progress_end(id) end - sig { params(global_state: GlobalState, outgoing_queue: Thread::Queue).void } + #: (global_state: GlobalState, outgoing_queue: Thread::Queue) -> void def register_additional_file_watchers(global_state:, outgoing_queue:) return unless global_state.client_capabilities.supports_watching_files @@ -247,7 +224,7 @@ def register_additional_file_watchers(global_state:, outgoing_queue:) ) end - sig { returns(Interface::FileSystemWatcher) } + #: -> Interface::FileSystemWatcher def structure_sql_file_watcher Interface::FileSystemWatcher.new( glob_pattern: "**/*structure.sql", @@ -255,7 +232,7 @@ def structure_sql_file_watcher ) end - sig { returns(Interface::FileSystemWatcher) } + #: -> Interface::FileSystemWatcher def fixture_file_watcher Interface::FileSystemWatcher.new( glob_pattern: "**/fixtures/**/*.{yml,yaml,yml.erb,yaml.erb}", @@ -263,7 +240,7 @@ def fixture_file_watcher ) end - sig { void } + #: -> void def offer_to_run_pending_migrations return unless @outgoing_queue return unless @global_state&.client_capabilities&.window_show_message_supports_extra_properties diff --git a/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb b/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb index 89599dee..4403d721 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb @@ -76,15 +76,7 @@ class CodeLens include Requests::Support::Common include ActiveSupportTestCaseHelper - sig do - params( - client: RunnerClient, - global_state: GlobalState, - response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens], - uri: URI::Generic, - dispatcher: Prism::Dispatcher, - ).void - end + #: (RunnerClient client, GlobalState global_state, ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens] response_builder, URI::Generic uri, Prism::Dispatcher dispatcher) -> void def initialize(client, global_state, response_builder, uri, dispatcher) @client = client @global_state = global_state @@ -105,7 +97,7 @@ def initialize(client, global_state, response_builder, uri, dispatcher) ) end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def on_call_node_enter(node) content = extract_test_case_name(node) @@ -117,7 +109,7 @@ def on_call_node_enter(node) end # Although uncommon, Rails tests can be written with the classic "def test_name" syntax. - sig { params(node: Prism::DefNode).void } + #: (Prism::DefNode node) -> void def on_def_node_enter(node) method_name = node.name.to_s @@ -133,7 +125,7 @@ def on_def_node_enter(node) end end - sig { params(node: Prism::ClassNode).void } + #: (Prism::ClassNode node) -> void def on_class_node_enter(node) class_name = node.constant_path.slice superclass_name = node.superclass&.slice @@ -157,7 +149,7 @@ def on_class_node_enter(node) end end - sig { params(node: Prism::ClassNode).void } + #: (Prism::ClassNode node) -> void def on_class_node_leave(node) class_name = node.constant_path.slice @@ -168,19 +160,19 @@ def on_class_node_leave(node) @constant_name_stack.pop end - sig { params(node: Prism::ModuleNode).void } + #: (Prism::ModuleNode node) -> void def on_module_node_enter(node) @constant_name_stack << [node.constant_path.slice, nil] end - sig { params(node: Prism::ModuleNode).void } + #: (Prism::ModuleNode node) -> void def on_module_node_leave(node) @constant_name_stack.pop end private - sig { returns(T.nilable(T::Boolean)) } + #: -> bool? def controller? class_name, superclass_name = @constant_name_stack.last return false unless class_name && superclass_name @@ -188,7 +180,7 @@ def controller? class_name.end_with?("Controller") && superclass_name.end_with?("Controller") end - sig { params(node: Prism::DefNode).void } + #: (Prism::DefNode node) -> void def add_jump_to_view(node) class_name = @constant_name_stack.map(&:first).join("::") action_name = node.name @@ -216,7 +208,7 @@ def add_jump_to_view(node) ) end - sig { params(node: Prism::DefNode).void } + #: (Prism::DefNode node) -> void def add_route_code_lens_to_action(node) class_name, _ = T.must(@constant_name_stack.last) route = @client.route(controller: class_name, action: node.name.to_s) @@ -233,22 +225,22 @@ def add_route_code_lens_to_action(node) ) end - sig { returns(String) } + #: -> String def test_command "#{RbConfig.ruby} bin/rails test" end - sig { returns(String) } + #: -> String def migrate_command "#{RbConfig.ruby} bin/rails db:migrate" end - sig { returns(T.nilable(String)) } + #: -> String? def migration_version File.basename(T.must(@path)).split("_").first end - sig { params(node: Prism::Node, name: String, command: String).void } + #: (Prism::Node node, name: String, command: String) -> void def add_migrate_code_lens(node, name:, command:) return unless @path @@ -261,7 +253,7 @@ def add_migrate_code_lens(node, name:, command:) ) end - sig { params(node: Prism::Node, name: String, command: String, kind: Symbol).void } + #: (Prism::Node node, name: String, command: String, kind: Symbol) -> void def add_test_code_lens(node, name:, command:, kind:) return unless @path return unless @global_state.test_library == "rails" diff --git a/lib/ruby_lsp/ruby_lsp_rails/completion.rb b/lib/ruby_lsp/ruby_lsp_rails/completion.rb index 9b3c4032..72ff4e83 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/completion.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/completion.rb @@ -7,15 +7,8 @@ class Completion extend T::Sig include Requests::Support::Common - sig do - override.params( - client: RunnerClient, - response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem], - node_context: NodeContext, - dispatcher: Prism::Dispatcher, - uri: URI::Generic, - ).void - end + # @override + #: (RunnerClient client, ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, NodeContext node_context, Prism::Dispatcher dispatcher, URI::Generic uri) -> void def initialize(client, response_builder, node_context, dispatcher, uri) @response_builder = response_builder @client = client @@ -26,7 +19,7 @@ def initialize(client, response_builder, node_context, dispatcher, uri) ) end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def on_call_node_enter(node) call_node = @node_context.call_node return unless call_node @@ -39,7 +32,7 @@ def on_call_node_enter(node) private - sig { params(node: Prism::CallNode, receiver: Prism::ConstantReadNode).void } + #: (node: Prism::CallNode, receiver: Prism::ConstantReadNode) -> void def handle_active_record_where_completions(node:, receiver:) resolved_class = @client.model(receiver.name.to_s) return if resolved_class.nil? @@ -70,7 +63,7 @@ def handle_active_record_where_completions(node:, receiver:) end end - sig { params(arguments: T::Array[Prism::Node]).returns(T::Hash[String, Prism::Node]) } + #: (arguments: Array[Prism::Node]) -> Hash[String, Prism::Node] def index_call_node_args(arguments:) indexed_call_node_args = {} arguments.each do |argument| diff --git a/lib/ruby_lsp/ruby_lsp_rails/definition.rb b/lib/ruby_lsp/ruby_lsp_rails/definition.rb index 8bc2a7b4..31143b5f 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/definition.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/definition.rb @@ -31,17 +31,7 @@ class Definition extend T::Sig include Requests::Support::Common - sig do - params( - client: RunnerClient, - response_builder: RubyLsp::ResponseBuilders::CollectionResponseBuilder[T.any( - Interface::Location, Interface::LocationLink - )], - node_context: NodeContext, - index: RubyIndexer::Index, - dispatcher: Prism::Dispatcher, - ).void - end + #: (RunnerClient client, RubyLsp::ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)] response_builder, NodeContext node_context, RubyIndexer::Index index, Prism::Dispatcher dispatcher) -> void def initialize(client, response_builder, node_context, index, dispatcher) @client = client @response_builder = response_builder @@ -52,17 +42,17 @@ def initialize(client, response_builder, node_context, index, dispatcher) dispatcher.register(self, :on_call_node_enter, :on_symbol_node_enter, :on_string_node_enter) end - sig { params(node: Prism::SymbolNode).void } + #: (Prism::SymbolNode node) -> void def on_symbol_node_enter(node) handle_possible_dsl(node) end - sig { params(node: Prism::StringNode).void } + #: (Prism::StringNode node) -> void def on_string_node_enter(node) handle_possible_dsl(node) end - sig { params(node: T.any(Prism::SymbolNode, Prism::StringNode)).void } + #: ((Prism::SymbolNode | Prism::StringNode) node) -> void def handle_possible_dsl(node) node = @node_context.call_node return unless node @@ -79,7 +69,7 @@ def handle_possible_dsl(node) end end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def on_call_node_enter(node) return unless self_receiver?(node) @@ -94,7 +84,7 @@ def on_call_node_enter(node) private - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def handle_callback(node) arguments = node.arguments&.arguments return unless arguments&.any? @@ -113,7 +103,7 @@ def handle_callback(node) end end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def handle_association(node) first_argument = node.arguments&.arguments&.first return unless first_argument.is_a?(Prism::SymbolNode) @@ -130,7 +120,7 @@ def handle_association(node) @response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location)) end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def handle_route(node) result = @client.route_location(T.must(node.message)) return unless result @@ -138,7 +128,7 @@ def handle_route(node) @response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location)) end - sig { params(name: String).void } + #: (String name) -> void def collect_definitions(name) methods = @index.resolve_method(name, @nesting.join("::")) return unless methods diff --git a/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb b/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb index 8fe58eae..ee606d4c 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb @@ -13,12 +13,7 @@ class DocumentSymbol include Requests::Support::Common include ActiveSupportTestCaseHelper - sig do - params( - response_builder: ResponseBuilders::DocumentSymbol, - dispatcher: Prism::Dispatcher, - ).void - end + #: (ResponseBuilders::DocumentSymbol response_builder, Prism::Dispatcher dispatcher) -> void def initialize(response_builder, dispatcher) @response_builder = response_builder @namespace_stack = T.let([], T::Array[String]) @@ -33,7 +28,7 @@ def initialize(response_builder, dispatcher) ) end - sig { params(node: Prism::CallNode).void } + #: (Prism::CallNode node) -> void def on_call_node_enter(node) return if @namespace_stack.empty? @@ -62,39 +57,39 @@ def on_call_node_enter(node) end end - sig { params(node: Prism::ClassNode).void } + #: (Prism::ClassNode node) -> void def on_class_node_enter(node) add_to_namespace_stack(node) end - sig { params(node: Prism::ClassNode).void } + #: (Prism::ClassNode node) -> void def on_class_node_leave(node) remove_from_namespace_stack(node) end - sig { params(node: Prism::ModuleNode).void } + #: (Prism::ModuleNode node) -> void def on_module_node_enter(node) add_to_namespace_stack(node) end - sig { params(node: Prism::ModuleNode).void } + #: (Prism::ModuleNode node) -> void def on_module_node_leave(node) remove_from_namespace_stack(node) end private - sig { params(node: T.any(Prism::ClassNode, Prism::ModuleNode)).void } + #: ((Prism::ClassNode | Prism::ModuleNode) node) -> void def add_to_namespace_stack(node) @namespace_stack << node.constant_path.slice end - sig { params(node: T.any(Prism::ClassNode, Prism::ModuleNode)).void } + #: ((Prism::ClassNode | Prism::ModuleNode) node) -> void def remove_from_namespace_stack(node) @namespace_stack.delete(node.constant_path.slice) end - sig { params(node: Prism::CallNode, message: String).void } + #: (Prism::CallNode node, String message) -> void def handle_all_arg_types(node, message) block = node.block @@ -164,7 +159,7 @@ def handle_all_arg_types(node, message) end end - sig { params(node: Prism::CallNode, message: String).void } + #: (Prism::CallNode node, String message) -> void def handle_symbol_and_string_arg_types(node, message) arguments = node.arguments&.arguments return unless arguments&.any? @@ -193,7 +188,7 @@ def handle_symbol_and_string_arg_types(node, message) end end - sig { params(node: Prism::CallNode, message: String).void } + #: (Prism::CallNode node, String message) -> void def handle_class_arg_types(node, message) arguments = node.arguments&.arguments return unless arguments&.any? @@ -213,13 +208,7 @@ def handle_class_arg_types(node, message) end end - sig do - params( - name: String, - range: RubyLsp::Interface::Range, - selection_range: RubyLsp::Interface::Range, - ).void - end + #: (name: String, range: RubyLsp::Interface::Range, selection_range: RubyLsp::Interface::Range) -> void def append_document_symbol(name:, range:, selection_range:) @response_builder.last.children << RubyLsp::Interface::DocumentSymbol.new( name: name, diff --git a/lib/ruby_lsp/ruby_lsp_rails/hover.rb b/lib/ruby_lsp/ruby_lsp_rails/hover.rb index ce8e828e..6655d4c7 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/hover.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/hover.rb @@ -18,15 +18,7 @@ class Hover extend T::Sig include Requests::Support::Common - sig do - params( - client: RunnerClient, - response_builder: ResponseBuilders::Hover, - node_context: NodeContext, - global_state: GlobalState, - dispatcher: Prism::Dispatcher, - ).void - end + #: (RunnerClient client, ResponseBuilders::Hover response_builder, NodeContext node_context, GlobalState global_state, Prism::Dispatcher dispatcher) -> void def initialize(client, response_builder, node_context, global_state, dispatcher) @client = client @response_builder = response_builder @@ -35,7 +27,7 @@ def initialize(client, response_builder, node_context, global_state, dispatcher) dispatcher.register(self, :on_constant_path_node_enter, :on_constant_read_node_enter) end - sig { params(node: Prism::ConstantPathNode).void } + #: (Prism::ConstantPathNode node) -> void def on_constant_path_node_enter(node) entries = @index.resolve(node.slice, @nesting) return unless entries @@ -44,7 +36,7 @@ def on_constant_path_node_enter(node) generate_column_content(name) end - sig { params(node: Prism::ConstantReadNode).void } + #: (Prism::ConstantReadNode node) -> void def on_constant_read_node_enter(node) entries = @index.resolve(node.name.to_s, @nesting) return unless entries @@ -54,7 +46,7 @@ def on_constant_read_node_enter(node) private - sig { params(name: String).void } + #: (String name) -> void def generate_column_content(name) model = @client.model(name) return if model.nil? @@ -79,7 +71,7 @@ def generate_column_content(name) ) end - sig { params(default_value: String, type: String).returns(String) } + #: (String default_value, String type) -> String def format_default(default_value, type) case type when "boolean" diff --git a/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb b/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb index 865b0e32..b60b31fd 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb @@ -6,11 +6,8 @@ module Rails class IndexingEnhancement < RubyIndexer::Enhancement extend T::Sig - sig do - override.params( - call_node: Prism::CallNode, - ).void - end + # @override + #: (Prism::CallNode call_node) -> void def on_call_node_enter(call_node) owner = @listener.current_owner return unless owner @@ -26,11 +23,8 @@ def on_call_node_enter(call_node) end end - sig do - override.params( - call_node: Prism::CallNode, - ).void - end + # @override + #: (Prism::CallNode call_node) -> void def on_call_node_leave(call_node) if call_node.name == :class_methods && call_node.block @listener.pop_namespace_stack @@ -39,12 +33,7 @@ def on_call_node_leave(call_node) private - sig do - params( - owner: RubyIndexer::Entry::Namespace, - call_node: Prism::CallNode, - ).void - end + #: (RubyIndexer::Entry::Namespace owner, Prism::CallNode call_node) -> void def handle_association(owner, call_node) arguments = call_node.arguments&.arguments return unless arguments @@ -73,7 +62,7 @@ def handle_association(owner, call_node) @listener.add_method("#{name}=", loc, writer_signatures) end - sig { params(owner: RubyIndexer::Entry::Namespace, call_node: Prism::CallNode).void } + #: (RubyIndexer::Entry::Namespace owner, Prism::CallNode call_node) -> void def handle_concern_extend(owner, call_node) arguments = call_node.arguments&.arguments return unless arguments @@ -98,7 +87,7 @@ def handle_concern_extend(owner, call_node) end end - sig { params(owner: RubyIndexer::Entry::Namespace, call_node: Prism::CallNode).void } + #: (RubyIndexer::Entry::Namespace owner, Prism::CallNode call_node) -> void def handle_class_methods(owner, call_node) return unless call_node.block diff --git a/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb b/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb index 953905ba..c7358c49 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb @@ -10,7 +10,7 @@ class RunnerClient class << self extend T::Sig - sig { params(outgoing_queue: Thread::Queue, global_state: RubyLsp::GlobalState).returns(RunnerClient) } + #: (Thread::Queue outgoing_queue, RubyLsp::GlobalState global_state) -> RunnerClient def create_client(outgoing_queue, global_state) if File.exist?("bin/rails") new(outgoing_queue, global_state) @@ -48,10 +48,10 @@ class EmptyMessageError < MessageError; end extend T::Sig - sig { returns(String) } + #: String attr_reader :rails_root - sig { params(outgoing_queue: Thread::Queue, global_state: RubyLsp::GlobalState).void } + #: (Thread::Queue outgoing_queue, RubyLsp::GlobalState global_state) -> void def initialize(outgoing_queue, global_state) @outgoing_queue = T.let(outgoing_queue, Thread::Queue) @mutex = T.let(Mutex.new, Mutex) @@ -128,7 +128,7 @@ def initialize(outgoing_queue, global_state) raise InitializationError, @stderr.read end - sig { params(server_addon_path: String).void } + #: (String server_addon_path) -> void def register_server_addon(server_addon_path) send_notification("server_addon/register", server_addon_path: server_addon_path) rescue MessageError @@ -139,7 +139,7 @@ def register_server_addon(server_addon_path) nil end - sig { params(name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) } + #: (String name) -> Hash[Symbol, untyped]? def model(name) make_request("model", name: name) rescue MessageError @@ -150,12 +150,7 @@ def model(name) nil end - sig do - params( - model_name: String, - association_name: String, - ).returns(T.nilable(T::Hash[Symbol, T.untyped])) - end + #: (model_name: String, association_name: String) -> Hash[Symbol, untyped]? def association_target_location(model_name:, association_name:) make_request( "association_target_location", @@ -170,7 +165,7 @@ def association_target_location(model_name:, association_name:) nil end - sig { params(name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) } + #: (String name) -> Hash[Symbol, untyped]? def route_location(name) make_request("route_location", name: name) rescue MessageError @@ -181,7 +176,7 @@ def route_location(name) nil end - sig { params(controller: String, action: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) } + #: (controller: String, action: String) -> Hash[Symbol, untyped]? def route(controller:, action:) make_request("route_info", controller: controller, action: action) rescue MessageError @@ -193,7 +188,7 @@ def route(controller:, action:) end # Delegates a notification to a server add-on - sig { params(server_addon_name: String, request_name: String, params: T.untyped).void } + #: (server_addon_name: String, request_name: String, **untyped params) -> void def delegate_notification(server_addon_name:, request_name:, **params) send_notification( "server_addon/delegate", @@ -203,7 +198,7 @@ def delegate_notification(server_addon_name:, request_name:, **params) ) end - sig { returns(T.nilable(String)) } + #: -> String? def pending_migrations_message response = make_request("pending_migrations_message") response[:pending_migrations_message] if response @@ -215,7 +210,7 @@ def pending_migrations_message nil end - sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) } + #: -> Hash[Symbol, untyped]? def run_migrations make_request("run_migrations") rescue MessageError @@ -227,13 +222,7 @@ def run_migrations end # Delegates a request to a server add-on - sig do - params( - server_addon_name: String, - request_name: String, - params: T.untyped, - ).returns(T.nilable(T::Hash[Symbol, T.untyped])) - end + #: (server_addon_name: String, request_name: String, **untyped params) -> Hash[Symbol, untyped]? def delegate_request(server_addon_name:, request_name:, **params) make_request( "server_addon/delegate", @@ -245,7 +234,7 @@ def delegate_request(server_addon_name:, request_name:, **params) nil end - sig { void } + #: -> void def trigger_reload log_message("Reloading Rails application") send_notification("reload") @@ -257,7 +246,7 @@ def trigger_reload nil end - sig { void } + #: -> void def shutdown log_message("Ruby LSP Rails shutting down server") send_message("shutdown") @@ -268,34 +257,30 @@ def shutdown force_kill end - sig { returns(T::Boolean) } + #: -> bool def stopped? [@stdin, @stdout, @stderr].all?(&:closed?) && !@wait_thread.alive? end - sig { returns(T::Boolean) } + #: -> bool def connected? true end private - sig do - params( - request: String, - params: T.untyped, - ).returns(T.nilable(T::Hash[Symbol, T.untyped])) - end + #: (String request, **untyped params) -> Hash[Symbol, untyped]? def make_request(request, **params) send_message(request, **params) read_response end # Notifications are like messages, but one-way, with no response sent back. - sig { params(request: String, params: T.untyped).void } + #: (String request, **untyped params) -> void def send_notification(request, **params) = send_message(request, **params) - sig { overridable.params(request: String, params: T.untyped).void } + # @overridable + #: (String request, **untyped params) -> void def send_message(request, **params) message = { method: request } message[:params] = params @@ -308,7 +293,8 @@ def send_message(request, **params) # The server connection died end - sig { overridable.returns(T.nilable(T::Hash[Symbol, T.untyped])) } + # @overridable + #: -> Hash[Symbol, untyped]? def read_response raw_response = @mutex.synchronize do content_length = read_content_length @@ -334,20 +320,20 @@ def read_response nil end - sig { void } + #: -> void def force_kill # Windows does not support the `TERM` signal, so we're forced to use `KILL` here Process.kill(T.must(Signal.list["KILL"]), @wait_thread.pid) end - sig { params(message: ::String, type: ::Integer).void } + #: (::String message, ?type: ::Integer) -> void def log_message(message, type: RubyLsp::Constant::MessageType::LOG) return if @outgoing_queue.closed? @outgoing_queue << RubyLsp::Notification.window_log_message(message, type: type) end - sig { returns(T.nilable(Integer)) } + #: -> Integer? def read_content_length headers = @stdout.gets("\r\n\r\n") return unless headers @@ -359,7 +345,7 @@ def read_content_length end # Read a server notification from stderr. Only intended to be used by notifier thread - sig { returns(T.nilable(T::Hash[Symbol, T.untyped])) } + #: -> Hash[Symbol, untyped]? def read_notification headers = @stderr.gets("\r\n\r\n") return unless headers @@ -373,7 +359,7 @@ def read_notification JSON.parse(raw_content, symbolize_names: true) end - sig { params(global_state: GlobalState).returns(String) } + #: (GlobalState global_state) -> String def server_relevant_capabilities(global_state) { supports_progress: global_state.client_capabilities.supports_progress, @@ -384,43 +370,48 @@ def server_relevant_capabilities(global_state) class NullClient < RunnerClient extend T::Sig - sig { void } + #: -> void def initialize # rubocop:disable Lint/MissingSuper end - sig { override.void } + # @override + #: -> void def shutdown # no-op end - sig { override.returns(T::Boolean) } + # @override + #: -> bool def stopped? true end - sig { override.returns(String) } + # @override + #: -> String def rails_root Dir.pwd end - sig { returns(T::Boolean) } + #: -> bool def connected? false end private - sig { params(message: ::String, type: ::Integer).void } + #: (::String message, ?type: ::Integer) -> void def log_message(message, type: RubyLsp::Constant::MessageType::LOG) # no-op end - sig { override.params(request: String, params: T.untyped).void } + # @override + #: (String request, **untyped params) -> void def send_message(request, **params) # no-op end - sig { override.returns(T.nilable(T::Hash[Symbol, T.untyped])) } + # @override + #: -> Hash[Symbol, untyped]? def read_response # no-op end diff --git a/lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb b/lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb index ebb316e1..670508af 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb @@ -6,7 +6,7 @@ module Rails module ActiveSupportTestCaseHelper extend T::Sig - sig { params(node: Prism::CallNode).returns(T.nilable(String)) } + #: (Prism::CallNode node) -> String? def extract_test_case_name(node) message_value = node.message return unless message_value == "test" || message_value == "it" diff --git a/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb b/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb index d7fa2a99..ef27077d 100644 --- a/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb +++ b/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb @@ -8,7 +8,7 @@ class LocationBuilder class << self extend T::Sig - sig { params(location_string: String).returns(Interface::Location) } + #: (String location_string) -> Interface::Location def line_location_from_s(location_string) *file_parts, line = location_string.split(":") raise ArgumentError, "Invalid location string given" if file_parts.empty? diff --git a/sorbet/config b/sorbet/config index 4b7609ff..fdd32388 100644 --- a/sorbet/config +++ b/sorbet/config @@ -3,3 +3,4 @@ --ignore=tmp/ --ignore=vendor/ --ignore=test/dummy +--enable-experimental-rbs-signatures