ruby-lsp 0.23.11 → 0.23.12

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 (98) 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_register_with_handler_method.rb +3 -5
  6. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +52 -77
  7. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +61 -144
  8. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +8 -6
  9. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +73 -182
  10. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +48 -181
  11. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  12. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +12 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +21 -44
  14. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +40 -58
  15. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
  16. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
  17. data/lib/ruby_indexer/test/configuration_test.rb +32 -2
  18. data/lib/ruby_indexer/test/method_test.rb +2 -2
  19. data/lib/ruby_lsp/addon.rb +32 -67
  20. data/lib/ruby_lsp/base_server.rb +10 -10
  21. data/lib/ruby_lsp/client_capabilities.rb +4 -6
  22. data/lib/ruby_lsp/document.rb +21 -32
  23. data/lib/ruby_lsp/erb_document.rb +17 -27
  24. data/lib/ruby_lsp/global_state.rb +30 -32
  25. data/lib/ruby_lsp/internal.rb +2 -0
  26. data/lib/ruby_lsp/listeners/code_lens.rb +21 -39
  27. data/lib/ruby_lsp/listeners/completion.rb +34 -53
  28. data/lib/ruby_lsp/listeners/definition.rb +35 -49
  29. data/lib/ruby_lsp/listeners/document_highlight.rb +60 -69
  30. data/lib/ruby_lsp/listeners/document_link.rb +9 -19
  31. data/lib/ruby_lsp/listeners/document_symbol.rb +34 -48
  32. data/lib/ruby_lsp/listeners/folding_ranges.rb +31 -38
  33. data/lib/ruby_lsp/listeners/hover.rb +37 -47
  34. data/lib/ruby_lsp/listeners/inlay_hints.rb +3 -10
  35. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +29 -35
  36. data/lib/ruby_lsp/listeners/signature_help.rb +4 -23
  37. data/lib/ruby_lsp/listeners/spec_style.rb +199 -0
  38. data/lib/ruby_lsp/listeners/test_style.rb +136 -30
  39. data/lib/ruby_lsp/node_context.rb +8 -35
  40. data/lib/ruby_lsp/rbs_document.rb +7 -5
  41. data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
  42. data/lib/ruby_lsp/requests/code_actions.rb +5 -14
  43. data/lib/ruby_lsp/requests/code_lens.rb +4 -13
  44. data/lib/ruby_lsp/requests/completion.rb +4 -15
  45. data/lib/ruby_lsp/requests/completion_resolve.rb +4 -4
  46. data/lib/ruby_lsp/requests/definition.rb +4 -12
  47. data/lib/ruby_lsp/requests/diagnostics.rb +6 -9
  48. data/lib/ruby_lsp/requests/discover_tests.rb +15 -3
  49. data/lib/ruby_lsp/requests/document_highlight.rb +3 -11
  50. data/lib/ruby_lsp/requests/document_link.rb +4 -13
  51. data/lib/ruby_lsp/requests/document_symbol.rb +4 -7
  52. data/lib/ruby_lsp/requests/folding_ranges.rb +4 -7
  53. data/lib/ruby_lsp/requests/formatting.rb +4 -7
  54. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
  55. data/lib/ruby_lsp/requests/hover.rb +6 -16
  56. data/lib/ruby_lsp/requests/inlay_hints.rb +4 -13
  57. data/lib/ruby_lsp/requests/on_type_formatting.rb +17 -24
  58. data/lib/ruby_lsp/requests/prepare_rename.rb +3 -8
  59. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
  60. data/lib/ruby_lsp/requests/range_formatting.rb +3 -4
  61. data/lib/ruby_lsp/requests/references.rb +5 -35
  62. data/lib/ruby_lsp/requests/rename.rb +9 -35
  63. data/lib/ruby_lsp/requests/request.rb +5 -17
  64. data/lib/ruby_lsp/requests/selection_ranges.rb +3 -3
  65. data/lib/ruby_lsp/requests/semantic_highlighting.rb +6 -23
  66. data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -5
  67. data/lib/ruby_lsp/requests/signature_help.rb +6 -24
  68. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  69. data/lib/ruby_lsp/requests/support/common.rb +12 -49
  70. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -14
  71. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +7 -10
  72. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +9 -15
  73. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  74. data/lib/ruby_lsp/requests/support/sorbet.rb +1 -7
  75. data/lib/ruby_lsp/requests/support/source_uri.rb +5 -16
  76. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +7 -10
  77. data/lib/ruby_lsp/requests/support/test_item.rb +14 -13
  78. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +4 -5
  79. data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -3
  80. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +4 -4
  81. data/lib/ruby_lsp/response_builders/document_symbol.rb +8 -11
  82. data/lib/ruby_lsp/response_builders/hover.rb +5 -5
  83. data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
  84. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +18 -40
  85. data/lib/ruby_lsp/response_builders/signature_help.rb +4 -5
  86. data/lib/ruby_lsp/response_builders/test_collection.rb +5 -9
  87. data/lib/ruby_lsp/ruby_document.rb +15 -40
  88. data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +106 -0
  89. data/lib/ruby_lsp/scope.rb +6 -10
  90. data/lib/ruby_lsp/server.rb +125 -74
  91. data/lib/ruby_lsp/setup_bundler.rb +22 -15
  92. data/lib/ruby_lsp/store.rb +12 -28
  93. data/lib/ruby_lsp/test_helper.rb +3 -12
  94. data/lib/ruby_lsp/test_reporter.rb +71 -0
  95. data/lib/ruby_lsp/test_unit_test_runner.rb +96 -0
  96. data/lib/ruby_lsp/type_inferrer.rb +9 -13
  97. data/lib/ruby_lsp/utils.rb +27 -65
  98. metadata +8 -3
@@ -0,0 +1,199 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Listeners
6
+ class SpecStyle
7
+ extend T::Sig
8
+ include Requests::Support::Common
9
+
10
+ DYNAMIC_REFERENCE_MARKER = "<dynamic_reference>"
11
+
12
+ #: (response_builder: ResponseBuilders::TestCollection, global_state: GlobalState, dispatcher: Prism::Dispatcher, uri: URI::Generic) -> void
13
+ def initialize(response_builder, global_state, dispatcher, uri)
14
+ @response_builder = response_builder
15
+ @uri = uri
16
+ @index = T.let(global_state.index, RubyIndexer::Index)
17
+ @visibility_stack = T.let([:public], T::Array[Symbol])
18
+ @nesting = T.let([], T::Array[String])
19
+ @describe_block_nesting = T.let([], T::Array[String])
20
+ @spec_class_stack = T.let([], T::Array[T::Boolean])
21
+
22
+ dispatcher.register(
23
+ self,
24
+ :on_class_node_enter,
25
+ :on_class_node_leave,
26
+ :on_module_node_enter,
27
+ :on_module_node_leave,
28
+ :on_call_node_enter, # e.g. `describe` or `it`
29
+ :on_call_node_leave,
30
+ )
31
+ end
32
+
33
+ #: (node: Prism::ClassNode) -> void
34
+ def on_class_node_enter(node)
35
+ @visibility_stack << :public
36
+ name = constant_name(node.constant_path)
37
+ name ||= name_with_dynamic_reference(node.constant_path)
38
+
39
+ fully_qualified_name = RubyIndexer::Index.actual_nesting(@nesting, name).join("::")
40
+
41
+ attached_ancestors = begin
42
+ @index.linearized_ancestors_of(fully_qualified_name)
43
+ rescue RubyIndexer::Index::NonExistingNamespaceError
44
+ # When there are dynamic parts in the constant path, we will not have indexed the namespace. We can still
45
+ # provide test functionality if the class inherits directly from Test::Unit::TestCase or Minitest::Test
46
+ [node.superclass&.slice].compact
47
+ end
48
+
49
+ is_spec = attached_ancestors.include?("Minitest::Spec")
50
+ @spec_class_stack.push(is_spec)
51
+
52
+ @nesting << name
53
+ end
54
+
55
+ #: (node: Prism::ModuleNode) -> void
56
+ def on_module_node_enter(node)
57
+ @visibility_stack << :public
58
+
59
+ name = constant_name(node.constant_path)
60
+ name ||= name_with_dynamic_reference(node.constant_path)
61
+
62
+ @nesting << name
63
+ end
64
+
65
+ #: (node: Prism::ModuleNode) -> void
66
+ def on_module_node_leave(node)
67
+ @visibility_stack.pop
68
+ @nesting.pop
69
+ end
70
+
71
+ #: (node: Prism::ClassNode) -> void
72
+ def on_class_node_leave(node)
73
+ @visibility_stack.pop
74
+ @nesting.pop
75
+ @spec_class_stack.pop
76
+ end
77
+
78
+ #: (node: Prism::CallNode) -> void
79
+ def on_call_node_enter(node)
80
+ case node.name
81
+ when :describe
82
+ handle_describe(node)
83
+ when :it, :specify
84
+ handle_example(node)
85
+ end
86
+ end
87
+
88
+ #: (node: Prism::CallNode) -> void
89
+ def on_call_node_leave(node)
90
+ return unless node.name == :describe && !node.receiver
91
+
92
+ @describe_block_nesting.pop
93
+ end
94
+
95
+ private
96
+
97
+ #: (node: Prism::CallNode) -> void
98
+ def handle_describe(node)
99
+ return if node.block.nil?
100
+
101
+ description = extract_description(node)
102
+ return unless description
103
+
104
+ return unless in_spec_context?
105
+
106
+ if @nesting.empty? && @describe_block_nesting.empty?
107
+ test_item = Requests::Support::TestItem.new(
108
+ description,
109
+ description,
110
+ @uri,
111
+ range_from_node(node),
112
+ tags: [:minitest],
113
+ )
114
+ @response_builder.add(test_item)
115
+ else
116
+ add_to_parent_test_group(description, node)
117
+ end
118
+
119
+ @describe_block_nesting << description
120
+ end
121
+
122
+ #: (node: Prism::CallNode) -> void
123
+ def handle_example(node)
124
+ return unless in_spec_context?
125
+
126
+ return if @describe_block_nesting.empty? && @nesting.empty?
127
+
128
+ description = extract_description(node)
129
+ return unless description
130
+
131
+ add_to_parent_test_group(description, node)
132
+ end
133
+
134
+ #: (description: String, node: Prism::CallNode) -> void
135
+ def add_to_parent_test_group(description, node)
136
+ parent_test_group = find_parent_test_group
137
+ return unless parent_test_group
138
+
139
+ test_item = Requests::Support::TestItem.new(
140
+ description,
141
+ description,
142
+ @uri,
143
+ range_from_node(node),
144
+ tags: [:minitest],
145
+ )
146
+ parent_test_group.add(test_item)
147
+ end
148
+
149
+ #: -> Requests::Support::TestItem?
150
+ def find_parent_test_group
151
+ root_group_name, nested_describe_groups = if @nesting.empty?
152
+ [@describe_block_nesting.first, @describe_block_nesting[1..]]
153
+ else
154
+ [RubyIndexer::Index.actual_nesting(@nesting, nil).join("::"), @describe_block_nesting]
155
+ end
156
+ return unless root_group_name
157
+
158
+ test_group = T.let(@response_builder[root_group_name], T.nilable(Requests::Support::TestItem))
159
+ return unless test_group
160
+
161
+ return test_group unless nested_describe_groups
162
+
163
+ nested_describe_groups.each do |description|
164
+ test_group = test_group[description]
165
+ end
166
+
167
+ test_group
168
+ end
169
+
170
+ #: (node: Prism::CallNode) -> String?
171
+ def extract_description(node)
172
+ first_argument = node.arguments&.arguments&.first
173
+ return unless first_argument
174
+
175
+ case first_argument
176
+ when Prism::StringNode
177
+ first_argument.content
178
+ when Prism::ConstantReadNode, Prism::ConstantPathNode
179
+ constant_name(first_argument)
180
+ else
181
+ first_argument.slice
182
+ end
183
+ end
184
+
185
+ #: -> bool
186
+ def in_spec_context?
187
+ return true if @nesting.empty?
188
+
189
+ T.must(@spec_class_stack.last)
190
+ end
191
+
192
+ #: (node: Prism::ConstantPathNode | Prism::ConstantReadNode | Prism::ConstantPathTargetNode | Prism::CallNode | Prism::MissingNode) -> String
193
+ def name_with_dynamic_reference(node)
194
+ slice = node.slice
195
+ slice.gsub(/((?<=::)|^)[a-z]\w*/, DYNAMIC_REFERENCE_MARKER)
196
+ end
197
+ end
198
+ end
199
+ end
@@ -4,26 +4,140 @@
4
4
  module RubyLsp
5
5
  module Listeners
6
6
  class TestStyle
7
- extend T::Sig
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
+
28
+ children = item[:children]
29
+ uri = URI(item[:uri])
30
+ path = uri.full_path
31
+ next unless path
32
+
33
+ if tags.include?("test_dir")
34
+ full_files << "#{path}/**/*" if children.empty?
35
+ elsif tags.include?("test_file")
36
+ full_files << path if children.empty?
37
+ elsif tags.include?("test_group")
38
+ # If all of the children of the current test group are other groups, then there's no need to add it to the
39
+ # aggregated examples
40
+ unless children.any? && children.all? { |child| child[:tags].include?("test_group") }
41
+ aggregated_tests[path][item[:label]] = { tags: tags, examples: [] }
42
+ end
43
+ elsif tags.include?("minitest") || tags.include?("test_unit")
44
+ class_name, method_name = item[:id].split("#")
45
+ aggregated_tests[path][class_name][:examples] << method_name
46
+ aggregated_tests[path][class_name][:tags].merge(tags)
47
+ end
48
+
49
+ queue.concat(children) unless children.empty?
50
+ end
51
+
52
+ commands = []
53
+
54
+ aggregated_tests.each do |file_path, groups_and_examples|
55
+ # Separate groups into Minitest and Test Unit. You can have both frameworks in the same file, but you cannot
56
+ # have a group belongs to both at the same time
57
+ minitest_groups, test_unit_groups = groups_and_examples.partition do |_, info|
58
+ info[:tags].include?("minitest")
59
+ end
60
+
61
+ if minitest_groups.any?
62
+ commands << handle_minitest_groups(file_path, minitest_groups)
63
+ end
64
+
65
+ if test_unit_groups.any?
66
+ commands.concat(handle_test_unit_groups(file_path, test_unit_groups))
67
+ end
68
+ end
69
+
70
+ commands << "#{BASE_COMMAND} -Itest #{full_files.join(" ")}" unless full_files.empty?
71
+ commands
72
+ end
73
+
74
+ private
75
+
76
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> String
77
+ def handle_minitest_groups(file_path, groups_and_examples)
78
+ regexes = groups_and_examples.flat_map do |group, info|
79
+ examples = info[:examples]
80
+ group_regex = Shellwords.escape(group).gsub(Shellwords.escape(DYNAMIC_REFERENCE_MARKER), ".*")
81
+ if examples.empty?
82
+ "^#{group_regex}(#|::)"
83
+ elsif examples.length == 1
84
+ "^#{group_regex}##{examples[0]}$"
85
+ else
86
+ "^#{group_regex}#(#{examples.join("|")})$"
87
+ end
88
+ end
89
+
90
+ regex = if regexes.length == 1
91
+ regexes[0]
92
+ else
93
+ "(#{regexes.join("|")})"
94
+ end
95
+
96
+ "#{BASE_COMMAND} -Itest #{file_path} --name \"/#{regex}/\""
97
+ end
98
+
99
+ #: (String, Hash[String, Hash[Symbol, untyped]]) -> Array[String]
100
+ def handle_test_unit_groups(file_path, groups_and_examples)
101
+ groups_and_examples.map do |group, info|
102
+ examples = info[:examples]
103
+ group_regex = Shellwords.escape(group).gsub(Shellwords.escape(DYNAMIC_REFERENCE_MARKER), ".*")
104
+ command = +"#{BASE_COMMAND} -Itest #{file_path} --testcase \"/^#{group_regex}$/\""
105
+
106
+ unless examples.empty?
107
+ command << if examples.length == 1
108
+ " --name \"/#{examples[0]}$/\""
109
+ else
110
+ " --name \"/(#{examples.join("|")})$/\""
111
+ end
112
+ end
113
+
114
+ command
115
+ end
116
+ end
117
+ end
118
+
8
119
  include Requests::Support::Common
9
120
 
10
121
  ACCESS_MODIFIERS = [:public, :private, :protected].freeze
11
122
  DYNAMIC_REFERENCE_MARKER = "<dynamic_reference>"
123
+ BASE_COMMAND = T.let(
124
+ begin
125
+ Bundler.with_original_env { Bundler.default_lockfile }
126
+ "bundle exec ruby"
127
+ rescue Bundler::GemfileNotFound
128
+ "ruby"
129
+ end,
130
+ String,
131
+ )
12
132
 
13
- sig do
14
- params(
15
- response_builder: ResponseBuilders::TestCollection,
16
- global_state: GlobalState,
17
- dispatcher: Prism::Dispatcher,
18
- uri: URI::Generic,
19
- ).void
20
- end
133
+ #: (ResponseBuilders::TestCollection response_builder, GlobalState global_state, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
21
134
  def initialize(response_builder, global_state, dispatcher, uri)
22
135
  @response_builder = response_builder
23
136
  @uri = uri
24
137
  @index = T.let(global_state.index, RubyIndexer::Index)
25
138
  @visibility_stack = T.let([:public], T::Array[Symbol])
26
139
  @nesting = T.let([], T::Array[String])
140
+ @framework_tag = T.let(:minitest, Symbol)
27
141
 
28
142
  dispatcher.register(
29
143
  self,
@@ -37,7 +151,7 @@ module RubyLsp
37
151
  )
38
152
  end
39
153
 
40
- sig { params(node: Prism::ClassNode).void }
154
+ #: (Prism::ClassNode node) -> void
41
155
  def on_class_node_enter(node)
42
156
  @visibility_stack << :public
43
157
  name = constant_name(node.constant_path)
@@ -53,21 +167,22 @@ module RubyLsp
53
167
  [node.superclass&.slice].compact
54
168
  end
55
169
 
56
- if attached_ancestors.include?("Test::Unit::TestCase") ||
57
- non_declarative_minitest?(attached_ancestors, fully_qualified_name)
170
+ @framework_tag = :test_unit if attached_ancestors.include?("Test::Unit::TestCase")
58
171
 
172
+ if @framework_tag == :test_unit || non_declarative_minitest?(attached_ancestors, fully_qualified_name)
59
173
  @response_builder.add(Requests::Support::TestItem.new(
60
174
  fully_qualified_name,
61
175
  fully_qualified_name,
62
176
  @uri,
63
177
  range_from_node(node),
178
+ tags: [@framework_tag],
64
179
  ))
65
180
  end
66
181
 
67
182
  @nesting << name
68
183
  end
69
184
 
70
- sig { params(node: Prism::ModuleNode).void }
185
+ #: (Prism::ModuleNode node) -> void
71
186
  def on_module_node_enter(node)
72
187
  @visibility_stack << :public
73
188
 
@@ -77,19 +192,19 @@ module RubyLsp
77
192
  @nesting << name
78
193
  end
79
194
 
80
- sig { params(node: Prism::ModuleNode).void }
195
+ #: (Prism::ModuleNode node) -> void
81
196
  def on_module_node_leave(node)
82
197
  @visibility_stack.pop
83
198
  @nesting.pop
84
199
  end
85
200
 
86
- sig { params(node: Prism::ClassNode).void }
201
+ #: (Prism::ClassNode node) -> void
87
202
  def on_class_node_leave(node)
88
203
  @visibility_stack.pop
89
204
  @nesting.pop
90
205
  end
91
206
 
92
- sig { params(node: Prism::DefNode).void }
207
+ #: (Prism::DefNode node) -> void
93
208
  def on_def_node_enter(node)
94
209
  return if @visibility_stack.last != :public
95
210
 
@@ -109,10 +224,11 @@ module RubyLsp
109
224
  name,
110
225
  @uri,
111
226
  range_from_node(node),
227
+ tags: [@framework_tag],
112
228
  ))
113
229
  end
114
230
 
115
- sig { params(node: Prism::CallNode).void }
231
+ #: (Prism::CallNode node) -> void
116
232
  def on_call_node_enter(node)
117
233
  name = node.name
118
234
  return unless ACCESS_MODIFIERS.include?(name)
@@ -120,7 +236,7 @@ module RubyLsp
120
236
  @visibility_stack << name
121
237
  end
122
238
 
123
- sig { params(node: Prism::CallNode).void }
239
+ #: (Prism::CallNode node) -> void
124
240
  def on_call_node_leave(node)
125
241
  name = node.name
126
242
  return unless ACCESS_MODIFIERS.include?(name)
@@ -131,7 +247,7 @@ module RubyLsp
131
247
 
132
248
  private
133
249
 
134
- sig { params(attached_ancestors: T::Array[String], fully_qualified_name: String).returns(T::Boolean) }
250
+ #: (Array[String] attached_ancestors, String fully_qualified_name) -> bool
135
251
  def non_declarative_minitest?(attached_ancestors, fully_qualified_name)
136
252
  return false unless attached_ancestors.include?("Minitest::Test")
137
253
 
@@ -144,17 +260,7 @@ module RubyLsp
144
260
  true
145
261
  end
146
262
 
147
- sig do
148
- params(
149
- node: T.any(
150
- Prism::ConstantPathNode,
151
- Prism::ConstantReadNode,
152
- Prism::ConstantPathTargetNode,
153
- Prism::CallNode,
154
- Prism::MissingNode,
155
- ),
156
- ).returns(String)
157
- end
263
+ #: ((Prism::ConstantPathNode | Prism::ConstantReadNode | Prism::ConstantPathTargetNode | Prism::CallNode | Prism::MissingNode) node) -> String
158
264
  def name_with_dynamic_reference(node)
159
265
  slice = node.slice
160
266
  slice.gsub(/((?<=::)|^)[a-z]\w*/, DYNAMIC_REFERENCE_MARKER)
@@ -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
@@ -46,12 +29,12 @@ module RubyLsp
46
29
  @surrounding_method = T.let(surrounding_method, T.nilable(String))
47
30
  end
48
31
 
49
- sig { returns(String) }
32
+ #: -> String
50
33
  def fully_qualified_name
51
34
  @fully_qualified_name ||= T.let(@nesting.join("::"), T.nilable(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,17 +52,7 @@ 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
58
  surrounding_method = T.let(nil, T.nilable(String))
@@ -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
12
  @syntax_error = T.let(false, T::Boolean)
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