ruby-lsp 0.23.10 → 0.23.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp-launcher +12 -11
  5. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -1
  6. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
  7. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
  8. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
  9. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
  10. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +89 -201
  11. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +63 -192
  12. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  13. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
  14. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
  15. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
  16. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
  17. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
  18. data/lib/ruby_indexer/test/classes_and_modules_test.rb +75 -0
  19. data/lib/ruby_indexer/test/configuration_test.rb +42 -3
  20. data/lib/ruby_indexer/test/index_test.rb +21 -0
  21. data/lib/ruby_indexer/test/method_test.rb +28 -2
  22. data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
  23. data/lib/ruby_lsp/addon.rb +44 -71
  24. data/lib/ruby_lsp/base_server.rb +31 -33
  25. data/lib/ruby_lsp/client_capabilities.rb +10 -12
  26. data/lib/ruby_lsp/document.rb +34 -45
  27. data/lib/ruby_lsp/erb_document.rb +24 -36
  28. data/lib/ruby_lsp/global_state.rb +51 -56
  29. data/lib/ruby_lsp/internal.rb +6 -0
  30. data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
  31. data/lib/ruby_lsp/listeners/completion.rb +36 -55
  32. data/lib/ruby_lsp/listeners/definition.rb +37 -51
  33. data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
  34. data/lib/ruby_lsp/listeners/document_link.rb +43 -62
  35. data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
  36. data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
  37. data/lib/ruby_lsp/listeners/hover.rb +81 -100
  38. data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
  39. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
  40. data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
  41. data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
  42. data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
  43. data/lib/ruby_lsp/listeners/test_style.rb +236 -0
  44. data/lib/ruby_lsp/node_context.rb +12 -39
  45. data/lib/ruby_lsp/rbs_document.rb +8 -6
  46. data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
  47. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  48. data/lib/ruby_lsp/requests/code_lens.rb +6 -17
  49. data/lib/ruby_lsp/requests/completion.rb +7 -20
  50. data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
  51. data/lib/ruby_lsp/requests/definition.rb +8 -17
  52. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  53. data/lib/ruby_lsp/requests/discover_tests.rb +75 -0
  54. data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
  55. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  56. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  57. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  58. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  59. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
  60. data/lib/ruby_lsp/requests/hover.rb +8 -18
  61. data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
  62. data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
  63. data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
  64. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
  65. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  66. data/lib/ruby_lsp/requests/references.rb +6 -36
  67. data/lib/ruby_lsp/requests/rename.rb +11 -37
  68. data/lib/ruby_lsp/requests/request.rb +7 -19
  69. data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
  70. data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
  71. data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
  72. data/lib/ruby_lsp/requests/signature_help.rb +8 -26
  73. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  74. data/lib/ruby_lsp/requests/support/common.rb +13 -48
  75. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  76. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
  77. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
  78. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  79. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  80. data/lib/ruby_lsp/requests/support/source_uri.rb +16 -30
  81. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  82. data/lib/ruby_lsp/requests/support/test_item.rb +55 -0
  83. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  84. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  85. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
  86. data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
  87. data/lib/ruby_lsp/response_builders/hover.rb +10 -13
  88. data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
  89. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
  90. data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
  91. data/lib/ruby_lsp/response_builders/test_collection.rb +34 -0
  92. data/lib/ruby_lsp/ruby_document.rb +22 -60
  93. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
  94. data/lib/ruby_lsp/scope.rb +7 -11
  95. data/lib/ruby_lsp/server.rb +177 -72
  96. data/lib/ruby_lsp/setup_bundler.rb +61 -59
  97. data/lib/ruby_lsp/static_docs.rb +4 -7
  98. data/lib/ruby_lsp/store.rb +21 -40
  99. data/lib/ruby_lsp/test_helper.rb +3 -12
  100. data/lib/ruby_lsp/test_reporter.rb +207 -0
  101. data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
  102. data/lib/ruby_lsp/type_inferrer.rb +9 -13
  103. data/lib/ruby_lsp/utils.rb +37 -81
  104. metadata +13 -3
@@ -0,0 +1,236 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Listeners
6
+ class TestStyle < TestDiscovery
7
+ class << self
8
+ # Resolves the minimal set of commands required to execute the requested tests
9
+ #: (Array[Hash[Symbol, untyped]]) -> Array[String]
10
+ def resolve_test_commands(items)
11
+ # A nested hash of file_path => test_group => { tags: [], examples: [test_example] } to ensure we build the
12
+ # minimum amount of commands needed to execute the requested tests. This is only used for specific examples
13
+ # where we will need more complex regexes to execute it all at the same time
14
+ aggregated_tests = Hash.new do |hash, key|
15
+ hash[key] = Hash.new do |inner_h, inner_k|
16
+ inner_h[inner_k] = { tags: Set.new, examples: [] }
17
+ end
18
+ end
19
+
20
+ # Full files are paths that should be executed as a whole e.g.: an entire test file or directory
21
+ full_files = []
22
+ queue = items.dup
23
+
24
+ until queue.empty?
25
+ item = T.must(queue.shift)
26
+ tags = Set.new(item[:tags])
27
+ next unless tags.include?("framework:minitest") || tags.include?("framework:test_unit")
28
+
29
+ children = item[:children]
30
+ uri = URI(item[:uri])
31
+ path = uri.full_path
32
+ next unless path
33
+
34
+ if tags.include?("test_dir")
35
+ if children.empty?
36
+ full_files.concat(Dir.glob(
37
+ "#{path}/**/{*_test,test_*}.rb",
38
+ File::Constants::FNM_EXTGLOB | File::Constants::FNM_PATHNAME,
39
+ ))
40
+ end
41
+ elsif tags.include?("test_file")
42
+ full_files << path if children.empty?
43
+ elsif tags.include?("test_group")
44
+ # If all of the children of the current test group are other groups, then there's no need to add it to the
45
+ # aggregated examples
46
+ unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
47
+ aggregated_tests[path][item[:label]] = { tags: tags, examples: [] }
48
+ end
49
+ else
50
+ class_name, method_name = item[:id].split("#")
51
+ aggregated_tests[path][class_name][:examples] << method_name
52
+ aggregated_tests[path][class_name][:tags].merge(tags)
53
+ end
54
+
55
+ queue.concat(children) unless children.empty?
56
+ end
57
+
58
+ commands = []
59
+
60
+ aggregated_tests.each do |file_path, groups_and_examples|
61
+ # Separate groups into Minitest and Test Unit. You can have both frameworks in the same file, but you cannot
62
+ # have a group belongs to both at the same time
63
+ minitest_groups, test_unit_groups = groups_and_examples.partition do |_, info|
64
+ info[:tags].include?("framework:minitest")
65
+ end
66
+
67
+ if minitest_groups.any?
68
+ commands << handle_minitest_groups(file_path, minitest_groups)
69
+ end
70
+
71
+ if test_unit_groups.any?
72
+ commands.concat(handle_test_unit_groups(file_path, test_unit_groups))
73
+ end
74
+ end
75
+
76
+ unless full_files.empty?
77
+ commands << "#{BASE_COMMAND} -Itest -e \"ARGV.each { |f| require f }\" #{full_files.join(" ")}"
78
+ end
79
+
80
+ commands
81
+ end
82
+
83
+ private
84
+
85
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> String
86
+ def handle_minitest_groups(file_path, groups_and_examples)
87
+ regexes = groups_and_examples.flat_map do |group, info|
88
+ examples = info[:examples]
89
+ group_regex = Shellwords.escape(group).gsub(
90
+ Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
91
+ ".*",
92
+ )
93
+ if examples.empty?
94
+ "^#{group_regex}(#|::)"
95
+ elsif examples.length == 1
96
+ "^#{group_regex}##{examples[0]}$"
97
+ else
98
+ "^#{group_regex}#(#{examples.join("|")})$"
99
+ end
100
+ end
101
+
102
+ regex = if regexes.length == 1
103
+ regexes[0]
104
+ else
105
+ "(#{regexes.join("|")})"
106
+ end
107
+
108
+ "#{BASE_COMMAND} -Itest #{file_path} --name \"/#{regex}/\""
109
+ end
110
+
111
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
112
+ def handle_test_unit_groups(file_path, groups_and_examples)
113
+ groups_and_examples.map do |group, info|
114
+ examples = info[:examples]
115
+ group_regex = Shellwords.escape(group).gsub(
116
+ Shellwords.escape(TestDiscovery::DYNAMIC_REFERENCE_MARKER),
117
+ ".*",
118
+ )
119
+ command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}$/\""
120
+
121
+ unless examples.empty?
122
+ command << if examples.length == 1
123
+ " --name \"/#{examples[0]}$/\""
124
+ else
125
+ " --name \"/(#{examples.join("|")})$/\""
126
+ end
127
+ end
128
+
129
+ command
130
+ end
131
+ end
132
+ end
133
+
134
+ include Requests::Support::Common
135
+
136
+ MINITEST_REPORTER_PATH = File.expand_path("../ruby_lsp_reporter_plugin.rb", __dir__) #: String
137
+ TEST_UNIT_REPORTER_PATH = File.expand_path("../test_unit_test_runner.rb", __dir__) #: String
138
+ ACCESS_MODIFIERS = [:public, :private, :protected].freeze
139
+ BASE_COMMAND = begin
140
+ Bundler.with_original_env { Bundler.default_lockfile }
141
+ "bundle exec ruby"
142
+ rescue Bundler::GemfileNotFound
143
+ "ruby"
144
+ end #: String
145
+
146
+ #: (ResponseBuilders::TestCollection response_builder, GlobalState global_state, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
147
+ def initialize(response_builder, global_state, dispatcher, uri)
148
+ super
149
+
150
+ @framework = :minitest #: Symbol
151
+
152
+ dispatcher.register(
153
+ self,
154
+ # Common handlers registered in parent class
155
+ :on_class_node_enter,
156
+ :on_def_node_enter,
157
+ :on_call_node_enter,
158
+ :on_call_node_leave,
159
+ )
160
+ end
161
+
162
+ #: (Prism::ClassNode node) -> void
163
+ def on_class_node_enter(node)
164
+ with_test_ancestor_tracking(node) do |name, ancestors|
165
+ @framework = :test_unit if ancestors.include?("Test::Unit::TestCase")
166
+
167
+ if @framework == :test_unit || non_declarative_minitest?(ancestors, name)
168
+ @response_builder.add(Requests::Support::TestItem.new(
169
+ name,
170
+ name,
171
+ @uri,
172
+ range_from_node(node),
173
+ framework: @framework,
174
+ ))
175
+ end
176
+ end
177
+ end
178
+
179
+ #: (Prism::DefNode node) -> void
180
+ def on_def_node_enter(node)
181
+ return if @visibility_stack.last != :public
182
+
183
+ name = node.name.to_s
184
+ return unless name.start_with?("test_")
185
+
186
+ current_group_name = RubyIndexer::Index.actual_nesting(@nesting, nil).join("::")
187
+
188
+ # If we're finding a test method, but for the wrong framework, then the group test item will not have been
189
+ # previously pushed and thus we return early and avoid adding items for a framework this listener is not
190
+ # interested in
191
+ test_item = @response_builder[current_group_name]
192
+ return unless test_item
193
+
194
+ test_item.add(Requests::Support::TestItem.new(
195
+ "#{current_group_name}##{name}",
196
+ name,
197
+ @uri,
198
+ range_from_node(node),
199
+ framework: @framework,
200
+ ))
201
+ end
202
+
203
+ #: (Prism::CallNode node) -> void
204
+ def on_call_node_enter(node)
205
+ name = node.name
206
+ return unless ACCESS_MODIFIERS.include?(name)
207
+
208
+ @visibility_stack << name
209
+ end
210
+
211
+ #: (Prism::CallNode node) -> void
212
+ def on_call_node_leave(node)
213
+ name = node.name
214
+ return unless ACCESS_MODIFIERS.include?(name)
215
+ return unless node.arguments&.arguments
216
+
217
+ @visibility_stack.pop
218
+ end
219
+
220
+ private
221
+
222
+ #: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
223
+ def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
224
+ return false unless attached_ancestors.include?("Minitest::Test")
225
+
226
+ # We only support regular Minitest tests. The declarative syntax provided by ActiveSupport is handled by the
227
+ # Rails add-on
228
+ name_parts = fully_qualified_name.split("::")
229
+ singleton_name = "#{name_parts.join("::")}::<Class:#{name_parts.last}>"
230
+ !@index.linearized_ancestors_of(singleton_name).include?("ActiveSupport::Testing::Declarative")
231
+ rescue RubyIndexer::Index::NonExistingNamespaceError
232
+ true
233
+ end
234
+ end
235
+ end
236
+ end
@@ -5,36 +5,19 @@ module RubyLsp
5
5
  # This class allows listeners to access contextual information about a node in the AST, such as its parent,
6
6
  # its namespace nesting, and the surrounding CallNode (e.g. a method call).
7
7
  class NodeContext
8
- extend T::Sig
9
-
10
- sig { returns(T.nilable(Prism::Node)) }
8
+ #: Prism::Node?
11
9
  attr_reader :node, :parent
12
10
 
13
- sig { returns(T::Array[String]) }
11
+ #: Array[String]
14
12
  attr_reader :nesting
15
13
 
16
- sig { returns(T.nilable(Prism::CallNode)) }
14
+ #: Prism::CallNode?
17
15
  attr_reader :call_node
18
16
 
19
- sig { returns(T.nilable(String)) }
17
+ #: String?
20
18
  attr_reader :surrounding_method
21
19
 
22
- sig do
23
- params(
24
- node: T.nilable(Prism::Node),
25
- parent: T.nilable(Prism::Node),
26
- nesting_nodes: T::Array[T.any(
27
- Prism::ClassNode,
28
- Prism::ModuleNode,
29
- Prism::SingletonClassNode,
30
- Prism::DefNode,
31
- Prism::BlockNode,
32
- Prism::LambdaNode,
33
- Prism::ProgramNode,
34
- )],
35
- call_node: T.nilable(Prism::CallNode),
36
- ).void
37
- end
20
+ #: (Prism::Node? node, Prism::Node? parent, Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nesting_nodes, Prism::CallNode? call_node) -> void
38
21
  def initialize(node, parent, nesting_nodes, call_node)
39
22
  @node = node
40
23
  @parent = parent
@@ -42,16 +25,16 @@ module RubyLsp
42
25
  @call_node = call_node
43
26
 
44
27
  nesting, surrounding_method = handle_nesting_nodes(nesting_nodes)
45
- @nesting = T.let(nesting, T::Array[String])
46
- @surrounding_method = T.let(surrounding_method, T.nilable(String))
28
+ @nesting = nesting #: Array[String]
29
+ @surrounding_method = surrounding_method #: String?
47
30
  end
48
31
 
49
- sig { returns(String) }
32
+ #: -> String
50
33
  def fully_qualified_name
51
- @fully_qualified_name ||= T.let(@nesting.join("::"), T.nilable(String))
34
+ @fully_qualified_name ||= @nesting.join("::") #: String?
52
35
  end
53
36
 
54
- sig { returns(T::Array[Symbol]) }
37
+ #: -> Array[Symbol]
55
38
  def locals_for_scope
56
39
  locals = []
57
40
 
@@ -69,20 +52,10 @@ module RubyLsp
69
52
 
70
53
  private
71
54
 
72
- sig do
73
- params(nodes: T::Array[T.any(
74
- Prism::ClassNode,
75
- Prism::ModuleNode,
76
- Prism::SingletonClassNode,
77
- Prism::DefNode,
78
- Prism::BlockNode,
79
- Prism::LambdaNode,
80
- Prism::ProgramNode,
81
- )]).returns([T::Array[String], T.nilable(String)])
82
- end
55
+ #: (Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] nodes) -> [Array[String], String?]
83
56
  def handle_nesting_nodes(nodes)
84
57
  nesting = []
85
- surrounding_method = T.let(nil, T.nilable(String))
58
+ surrounding_method = nil #: String?
86
59
 
87
60
  @nesting_nodes.each do |node|
88
61
  case node
@@ -3,18 +3,18 @@
3
3
 
4
4
  module RubyLsp
5
5
  class RBSDocument < Document
6
- extend T::Sig
7
6
  extend T::Generic
8
7
 
9
8
  ParseResultType = type_member { { fixed: T::Array[RBS::AST::Declarations::Base] } }
10
9
 
11
- sig { params(source: String, version: Integer, uri: URI::Generic, global_state: GlobalState).void }
10
+ #: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
12
11
  def initialize(source:, version:, uri:, global_state:)
13
- @syntax_error = T.let(false, T::Boolean)
12
+ @syntax_error = false #: bool
14
13
  super
15
14
  end
16
15
 
17
- sig { override.returns(T::Boolean) }
16
+ # @override
17
+ #: -> bool
18
18
  def parse!
19
19
  return false unless @needs_parsing
20
20
 
@@ -29,12 +29,14 @@ module RubyLsp
29
29
  true
30
30
  end
31
31
 
32
- sig { override.returns(T::Boolean) }
32
+ # @override
33
+ #: -> bool
33
34
  def syntax_error?
34
35
  @syntax_error
35
36
  end
36
37
 
37
- sig { override.returns(LanguageId) }
38
+ # @override
39
+ #: -> LanguageId
38
40
  def language_id
39
41
  LanguageId::RBS
40
42
  end
@@ -7,7 +7,6 @@ module RubyLsp
7
7
  # request is used to to resolve the edit field for a given code action, if it is not already provided in the
8
8
  # textDocument/codeAction response. We can use it for scenarios that require more computation such as refactoring.
9
9
  class CodeActionResolve < Request
10
- extend T::Sig
11
10
  include Support::Common
12
11
 
13
12
  NEW_VARIABLE_NAME = "new_variable"
@@ -23,7 +22,7 @@ module RubyLsp
23
22
  end
24
23
  end
25
24
 
26
- sig { params(document: RubyDocument, global_state: GlobalState, code_action: T::Hash[Symbol, T.untyped]).void }
25
+ #: (RubyDocument document, GlobalState global_state, Hash[Symbol, untyped] code_action) -> void
27
26
  def initialize(document, global_state, code_action)
28
27
  super()
29
28
  @document = document
@@ -31,7 +30,8 @@ module RubyLsp
31
30
  @code_action = code_action
32
31
  end
33
32
 
34
- sig { override.returns(T.any(Interface::CodeAction, Error)) }
33
+ # @override
34
+ #: -> (Interface::CodeAction | Error)
35
35
  def perform
36
36
  return Error::EmptySelection if @document.source.empty?
37
37
 
@@ -53,7 +53,7 @@ module RubyLsp
53
53
 
54
54
  private
55
55
 
56
- sig { returns(T.any(Interface::CodeAction, Error)) }
56
+ #: -> (Interface::CodeAction | Error)
57
57
  def switch_block_style
58
58
  source_range = @code_action.dig(:data, :range)
59
59
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -91,7 +91,7 @@ module RubyLsp
91
91
  )
92
92
  end
93
93
 
94
- sig { returns(T.any(Interface::CodeAction, Error)) }
94
+ #: -> (Interface::CodeAction | Error)
95
95
  def refactor_variable
96
96
  source_range = @code_action.dig(:data, :range)
97
97
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -189,7 +189,7 @@ module RubyLsp
189
189
  )
190
190
  end
191
191
 
192
- sig { returns(T.any(Interface::CodeAction, Error)) }
192
+ #: -> (Interface::CodeAction | Error)
193
193
  def refactor_method
194
194
  source_range = @code_action.dig(:data, :range)
195
195
  return Error::EmptySelection if source_range[:start] == source_range[:end]
@@ -261,7 +261,7 @@ module RubyLsp
261
261
  )
262
262
  end
263
263
 
264
- sig { params(range: T::Hash[Symbol, T.untyped], new_text: String).returns(Interface::TextEdit) }
264
+ #: (Hash[Symbol, untyped] range, String new_text) -> Interface::TextEdit
265
265
  def create_text_edit(range, new_text)
266
266
  Interface::TextEdit.new(
267
267
  range: Interface::Range.new(
@@ -272,7 +272,7 @@ module RubyLsp
272
272
  )
273
273
  end
274
274
 
275
- sig { params(node: Prism::BlockNode, indentation: T.nilable(String)).returns(String) }
275
+ #: (Prism::BlockNode node, String? indentation) -> String
276
276
  def recursively_switch_nested_block_styles(node, indentation)
277
277
  parameters = node.parameters
278
278
  body = node.body
@@ -301,7 +301,7 @@ module RubyLsp
301
301
  source
302
302
  end
303
303
 
304
- sig { params(body: Prism::Node, indentation: T.nilable(String)).returns(String) }
304
+ #: (Prism::Node body, String? indentation) -> String
305
305
  def switch_block_body(body, indentation)
306
306
  # Check if there are any nested blocks inside of the current block
307
307
  body_loc = body.location
@@ -330,7 +330,7 @@ module RubyLsp
330
330
  indentation ? body_content.gsub(";", "\n") : "#{body_content.gsub("\n", ";")} "
331
331
  end
332
332
 
333
- sig { returns(T.any(Interface::CodeAction, Error)) }
333
+ #: -> (Interface::CodeAction | Error)
334
334
  def create_attribute_accessor
335
335
  source_range = @code_action.dig(:data, :range)
336
336
 
@@ -7,8 +7,6 @@ module RubyLsp
7
7
  # request informs the editor of RuboCop quick fixes that can be applied. These are accessible by hovering over a
8
8
  # specific diagnostic.
9
9
  class CodeActions < Request
10
- extend T::Sig
11
-
12
10
  EXTRACT_TO_VARIABLE_TITLE = "Refactor: Extract Variable"
13
11
  EXTRACT_TO_METHOD_TITLE = "Refactor: Extract Method"
14
12
  TOGGLE_BLOCK_STYLE_TITLE = "Refactor: Toggle block style"
@@ -16,22 +14,17 @@ module RubyLsp
16
14
  CREATE_ATTRIBUTE_WRITER = "Create Attribute Writer"
17
15
  CREATE_ATTRIBUTE_ACCESSOR = "Create Attribute Accessor"
18
16
 
19
- INSTANCE_VARIABLE_NODES = T.let(
20
- [
21
- Prism::InstanceVariableAndWriteNode,
22
- Prism::InstanceVariableOperatorWriteNode,
23
- Prism::InstanceVariableOrWriteNode,
24
- Prism::InstanceVariableReadNode,
25
- Prism::InstanceVariableTargetNode,
26
- Prism::InstanceVariableWriteNode,
27
- ],
28
- T::Array[T.class_of(Prism::Node)],
29
- )
17
+ INSTANCE_VARIABLE_NODES = [
18
+ Prism::InstanceVariableAndWriteNode,
19
+ Prism::InstanceVariableOperatorWriteNode,
20
+ Prism::InstanceVariableOrWriteNode,
21
+ Prism::InstanceVariableReadNode,
22
+ Prism::InstanceVariableTargetNode,
23
+ Prism::InstanceVariableWriteNode,
24
+ ] #: Array[singleton(Prism::Node)]
30
25
 
31
26
  class << self
32
- extend T::Sig
33
-
34
- sig { returns(Interface::CodeActionRegistrationOptions) }
27
+ #: -> Interface::CodeActionRegistrationOptions
35
28
  def provider
36
29
  Interface::CodeActionRegistrationOptions.new(
37
30
  document_selector: nil,
@@ -40,22 +33,17 @@ module RubyLsp
40
33
  end
41
34
  end
42
35
 
43
- sig do
44
- params(
45
- document: T.any(RubyDocument, ERBDocument),
46
- range: T::Hash[Symbol, T.untyped],
47
- context: T::Hash[Symbol, T.untyped],
48
- ).void
49
- end
36
+ #: ((RubyDocument | ERBDocument) document, Hash[Symbol, untyped] range, Hash[Symbol, untyped] context) -> void
50
37
  def initialize(document, range, context)
51
38
  super()
52
39
  @document = document
53
- @uri = T.let(document.uri, URI::Generic)
40
+ @uri = document.uri #: URI::Generic
54
41
  @range = range
55
42
  @context = context
56
43
  end
57
44
 
58
- sig { override.returns(T.nilable(T.all(T::Array[Interface::CodeAction], Object))) }
45
+ # @override
46
+ #: -> (Array[Interface::CodeAction] & Object)?
59
47
  def perform
60
48
  diagnostics = @context[:diagnostics]
61
49
 
@@ -88,7 +76,7 @@ module RubyLsp
88
76
 
89
77
  private
90
78
 
91
- sig { returns(T::Array[Interface::CodeAction]) }
79
+ #: -> Array[Interface::CodeAction]
92
80
  def attribute_actions
93
81
  return [] unless @document.is_a?(RubyDocument)
94
82
 
@@ -11,29 +11,17 @@ module RubyLsp
11
11
  # [code lens](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens)
12
12
  # request informs the editor of runnable commands such as testing and debugging.
13
13
  class CodeLens < Request
14
- extend T::Sig
15
-
16
14
  class << self
17
- extend T::Sig
18
-
19
- sig { returns(Interface::CodeLensOptions) }
15
+ #: -> Interface::CodeLensOptions
20
16
  def provider
21
17
  Interface::CodeLensOptions.new(resolve_provider: false)
22
18
  end
23
19
  end
24
20
 
25
- sig do
26
- params(
27
- global_state: GlobalState,
28
- uri: URI::Generic,
29
- dispatcher: Prism::Dispatcher,
30
- ).void
31
- end
21
+ #: (GlobalState global_state, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
32
22
  def initialize(global_state, uri, dispatcher)
33
- @response_builder = T.let(
34
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens].new,
35
- ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
36
- )
23
+ @response_builder = ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
24
+ .new #: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens]
37
25
  super()
38
26
  Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
39
27
 
@@ -42,7 +30,8 @@ module RubyLsp
42
30
  end
43
31
  end
44
32
 
45
- sig { override.returns(T::Array[Interface::CodeLens]) }
33
+ # @override
34
+ #: -> Array[Interface::CodeLens]
46
35
  def perform
47
36
  @response_builder.response
48
37
  end
@@ -8,12 +8,8 @@ module RubyLsp
8
8
  # The [completion](https://microsoft.github.io/language-server-protocol/specification#textDocument_completion)
9
9
  # suggests possible completions according to what the developer is typing.
10
10
  class Completion < Request
11
- extend T::Sig
12
-
13
11
  class << self
14
- extend T::Sig
15
-
16
- sig { returns(Interface::CompletionOptions) }
12
+ #: -> Interface::CompletionOptions
17
13
  def provider
18
14
  Interface::CompletionOptions.new(
19
15
  resolve_provider: true,
@@ -25,18 +21,10 @@ module RubyLsp
25
21
  end
26
22
  end
27
23
 
28
- sig do
29
- params(
30
- document: T.any(RubyDocument, ERBDocument),
31
- global_state: GlobalState,
32
- params: T::Hash[Symbol, T.untyped],
33
- sorbet_level: RubyDocument::SorbetLevel,
34
- dispatcher: Prism::Dispatcher,
35
- ).void
36
- end
24
+ #: ((RubyDocument | ERBDocument) document, GlobalState global_state, Hash[Symbol, untyped] params, RubyDocument::SorbetLevel sorbet_level, Prism::Dispatcher dispatcher) -> void
37
25
  def initialize(document, global_state, params, sorbet_level, dispatcher)
38
26
  super()
39
- @target = T.let(nil, T.nilable(Prism::Node))
27
+ @target = nil #: Prism::Node?
40
28
  @dispatcher = dispatcher
41
29
  # Completion always receives the position immediately after the character that was just typed. Here we adjust it
42
30
  # back by 1, so that we find the right node
@@ -72,10 +60,8 @@ module RubyLsp
72
60
  ],
73
61
  code_units_cache: document.code_units_cache,
74
62
  )
75
- @response_builder = T.let(
76
- ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem].new,
77
- ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
78
- )
63
+ @response_builder = ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem]
64
+ .new #: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem]
79
65
 
80
66
  Listeners::Completion.new(
81
67
  @response_builder,
@@ -102,7 +88,8 @@ module RubyLsp
102
88
  end
103
89
  end
104
90
 
105
- sig { override.returns(T::Array[Interface::CompletionItem]) }
91
+ # @override
92
+ #: -> Array[Interface::CompletionItem]
106
93
  def perform
107
94
  return [] unless @target
108
95
 
@@ -14,21 +14,21 @@ module RubyLsp
14
14
  # At most 10 definitions are included, to ensure low latency during request processing and rendering the completion
15
15
  # item.
16
16
  class CompletionResolve < Request
17
- extend T::Sig
18
17
  include Requests::Support::Common
19
18
 
20
19
  # set a limit on the number of documentation entries returned, to avoid rendering performance issues
21
20
  # https://github.com/Shopify/ruby-lsp/pull/1798
22
21
  MAX_DOCUMENTATION_ENTRIES = 10
23
22
 
24
- sig { params(global_state: GlobalState, item: T::Hash[Symbol, T.untyped]).void }
23
+ #: (GlobalState global_state, Hash[Symbol, untyped] item) -> void
25
24
  def initialize(global_state, item)
26
25
  super()
27
- @index = T.let(global_state.index, RubyIndexer::Index)
26
+ @index = global_state.index #: RubyIndexer::Index
28
27
  @item = item
29
28
  end
30
29
 
31
- sig { override.returns(T::Hash[Symbol, T.untyped]) }
30
+ # @override
31
+ #: -> Hash[Symbol, untyped]
32
32
  def perform
33
33
  return @item if @item.dig(:data, :skip_resolve)
34
34
 
@@ -78,7 +78,7 @@ module RubyLsp
78
78
 
79
79
  private
80
80
 
81
- sig { params(item: T::Hash[Symbol, T.untyped]).returns(T::Hash[Symbol, T.untyped]) }
81
+ #: (Hash[Symbol, untyped] item) -> Hash[Symbol, untyped]
82
82
  def keyword_resolve(item)
83
83
  keyword = item[:label]
84
84
  content = KEYWORD_DOCS[keyword]