ruby-lsp 0.12.5 → 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/exe/ruby-lsp-check +20 -4
  4. data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +36 -2
  5. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +1 -1
  6. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +132 -13
  7. data/lib/ruby_indexer/test/configuration_test.rb +10 -0
  8. data/lib/ruby_indexer/test/index_test.rb +11 -0
  9. data/lib/ruby_indexer/test/method_test.rb +202 -0
  10. data/lib/ruby_lsp/addon.rb +9 -13
  11. data/lib/ruby_lsp/document.rb +3 -0
  12. data/lib/ruby_lsp/executor.rb +33 -28
  13. data/lib/ruby_lsp/listener.rb +4 -5
  14. data/lib/ruby_lsp/requests/code_actions.rb +2 -16
  15. data/lib/ruby_lsp/requests/code_lens.rb +29 -7
  16. data/lib/ruby_lsp/requests/completion.rb +11 -8
  17. data/lib/ruby_lsp/requests/definition.rb +3 -4
  18. data/lib/ruby_lsp/requests/diagnostics.rb +0 -5
  19. data/lib/ruby_lsp/requests/document_highlight.rb +2 -3
  20. data/lib/ruby_lsp/requests/document_link.rb +2 -3
  21. data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
  22. data/lib/ruby_lsp/requests/folding_ranges.rb +12 -15
  23. data/lib/ruby_lsp/requests/formatting.rb +0 -5
  24. data/lib/ruby_lsp/requests/hover.rb +3 -4
  25. data/lib/ruby_lsp/requests/inlay_hints.rb +20 -3
  26. data/lib/ruby_lsp/requests/on_type_formatting.rb +31 -4
  27. data/lib/ruby_lsp/requests/semantic_highlighting.rb +28 -11
  28. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +92 -21
  29. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +1 -1
  30. data/lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb +3 -8
  31. data/lib/ruby_lsp/requests/workspace_symbol.rb +2 -0
  32. data/lib/ruby_lsp/store.rb +21 -0
  33. data/lib/ruby_lsp/utils.rb +18 -4
  34. metadata +7 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2cb6c373890a19400025a75be13971ff5e5e33772bd74a178784a035ba94c168
4
- data.tar.gz: d52ad65673ea9f1dfde13cfa6beec0f8c860a75b7f08453238597d584227b56f
3
+ metadata.gz: 78df9c8d35fc18cea6fc06a0f679b48b69e3daaaf504d762d2f5ae4df9d99ad0
4
+ data.tar.gz: 3c251eed7939e81c5aa115d303b2876d3769c509ef0487b0faa26d1a2de79c50
5
5
  SHA512:
6
- metadata.gz: ba64686636c26776797fc6e7e70156f4c7f304dbe27e98c73c2a60a7255ae7260159838d68c0364e98bc58d26c404118ad9e3d1cfe13766a2221cbc4d2ac6a7c
7
- data.tar.gz: fcf587173133668739ddc639d913ce34877cc1c0d3451b2ddc49254940ef8ba49815cae57dce2c6de423d3d3fb0db1059f1b8d2d19cd9d1de3af72fb26819759
6
+ metadata.gz: af33b81309429318e7fe61dc4a2bd989328b8e9127097ab621eab162e61e1b2d93f1be1b192307d3b48f47659489343e093d92125e9c68895c40517803dba5ed
7
+ data.tar.gz: 6373eb77209eb865e29026fba603f4db8d3249949bcff7c0aee3f550569a7225c84b76d5872fd61a8798c0ef04da2d538b50b4d3045697ef40cc85336a2c715b
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.12.5
1
+ 0.13.1
data/exe/ruby-lsp-check CHANGED
@@ -17,8 +17,6 @@ end
17
17
  $LOAD_PATH.unshift(File.expand_path("../lib", __dir__))
18
18
  require "ruby_lsp/internal"
19
19
 
20
- RubyLsp::Addon.load_addons
21
-
22
20
  T::Utils.run_all_sig_blocks
23
21
 
24
22
  files = Dir.glob("#{Dir.pwd}/**/*.rb")
@@ -28,6 +26,7 @@ puts "Verifying that all automatic LSP requests execute successfully. This may t
28
26
  errors = {}
29
27
  store = RubyLsp::Store.new
30
28
  message_queue = Thread::Queue.new
29
+ RubyLsp::Addon.load_addons(message_queue)
31
30
  executor = RubyLsp::Executor.new(store, message_queue)
32
31
 
33
32
  files.each_with_index do |file, index|
@@ -50,13 +49,30 @@ end
50
49
  puts "\n"
51
50
  message_queue.close
52
51
 
52
+ # Indexing
53
+ puts "Verifying that indexing executes successfully. This may take a while..."
54
+
55
+ index = RubyIndexer::Index.new
56
+ indexables = RubyIndexer.configuration.indexables
57
+
58
+ indexables.each_with_index do |indexable, i|
59
+ result = Prism.parse(File.read(indexable.full_path))
60
+ collector = RubyIndexer::Collector.new(index, result, indexable.full_path)
61
+ collector.collect(result.value)
62
+ rescue => e
63
+ errors[indexable.full_path] = e
64
+ ensure
65
+ print("\033[M\033[0KIndexed #{i + 1}/#{indexables.length}") unless ENV["CI"]
66
+ end
67
+ puts "\n"
68
+
53
69
  if errors.empty?
54
- puts "All automatic LSP requests executed successfully"
70
+ puts "All operations completed successfully!"
55
71
  exit
56
72
  end
57
73
 
58
74
  puts <<~ERRORS
59
- Errors while executing requests:
75
+ Errors while executing:
60
76
 
61
77
  #{errors.map { |file, error| "#{file}: #{error.message}" }.join("\n")}
62
78
  ERRORS
@@ -141,8 +141,18 @@ module RubyIndexer
141
141
 
142
142
  sig { params(node: Prism::CallNode).void }
143
143
  def handle_call_node(node)
144
- message = node.message
145
- handle_private_constant(node) if message == "private_constant"
144
+ message = node.name
145
+
146
+ case message
147
+ when :private_constant
148
+ handle_private_constant(node)
149
+ when :attr_reader
150
+ handle_attribute(node, reader: true, writer: false)
151
+ when :attr_writer
152
+ handle_attribute(node, reader: false, writer: true)
153
+ when :attr_accessor
154
+ handle_attribute(node, reader: true, writer: true)
155
+ end
146
156
  end
147
157
 
148
158
  sig { params(node: Prism::DefNode).void }
@@ -312,5 +322,29 @@ module RubyIndexer
312
322
  "#{@stack.join("::")}::#{name}"
313
323
  end.delete_prefix("::")
314
324
  end
325
+
326
+ sig { params(node: Prism::CallNode, reader: T::Boolean, writer: T::Boolean).void }
327
+ def handle_attribute(node, reader:, writer:)
328
+ arguments = node.arguments&.arguments
329
+ return unless arguments
330
+
331
+ receiver = node.receiver
332
+ return unless receiver.nil? || receiver.is_a?(Prism::SelfNode)
333
+
334
+ comments = collect_comments(node)
335
+ arguments.each do |argument|
336
+ name, loc = case argument
337
+ when Prism::SymbolNode
338
+ [argument.value, argument.value_loc]
339
+ when Prism::StringNode
340
+ [argument.content, argument.content_loc]
341
+ end
342
+
343
+ next unless name && loc
344
+
345
+ @index << Entry::Accessor.new(name, @file_path, loc, comments, @current_owner) if reader
346
+ @index << Entry::Accessor.new("#{name}=", @file_path, loc, comments, @current_owner) if writer
347
+ end
348
+ end
315
349
  end
316
350
  end
@@ -120,7 +120,7 @@ module RubyIndexer
120
120
  IndexablePath.new(RbConfig::CONFIG["rubylibdir"], path)
121
121
  end,
122
122
  )
123
- else
123
+ elsif pathname.extname == ".rb"
124
124
  # If the default_path is a Ruby file, we index it
125
125
  indexables << IndexablePath.new(RbConfig::CONFIG["rubylibdir"], default_path)
126
126
  end
@@ -90,20 +90,84 @@ module RubyIndexer
90
90
  end
91
91
  end
92
92
 
93
+ # A required method parameter, e.g. `def foo(a)`
93
94
  class RequiredParameter < Parameter
94
95
  end
95
96
 
96
- class Method < Entry
97
+ # An optional method parameter, e.g. `def foo(a = 123)`
98
+ class OptionalParameter < Parameter
99
+ end
100
+
101
+ # An required keyword method parameter, e.g. `def foo(a:)`
102
+ class KeywordParameter < Parameter
103
+ end
104
+
105
+ # An optional keyword method parameter, e.g. `def foo(a: 123)`
106
+ class OptionalKeywordParameter < Parameter
107
+ end
108
+
109
+ # A rest method parameter, e.g. `def foo(*a)`
110
+ class RestParameter < Parameter
111
+ DEFAULT_NAME = T.let(:"<anonymous splat>", Symbol)
112
+ end
113
+
114
+ # A keyword rest method parameter, e.g. `def foo(**a)`
115
+ class KeywordRestParameter < Parameter
116
+ DEFAULT_NAME = T.let(:"<anonymous keyword splat>", Symbol)
117
+ end
118
+
119
+ # A block method parameter, e.g. `def foo(&block)`
120
+ class BlockParameter < Parameter
121
+ DEFAULT_NAME = T.let(:"<anonymous block>", Symbol)
122
+ end
123
+
124
+ class Member < Entry
97
125
  extend T::Sig
98
126
  extend T::Helpers
99
- abstract!
100
127
 
101
- sig { returns(T::Array[Parameter]) }
102
- attr_reader :parameters
128
+ abstract!
103
129
 
104
130
  sig { returns(T.nilable(Entry::Namespace)) }
105
131
  attr_reader :owner
106
132
 
133
+ sig do
134
+ params(
135
+ name: String,
136
+ file_path: String,
137
+ location: Prism::Location,
138
+ comments: T::Array[String],
139
+ owner: T.nilable(Entry::Namespace),
140
+ ).void
141
+ end
142
+ def initialize(name, file_path, location, comments, owner)
143
+ super(name, file_path, location, comments)
144
+ @owner = owner
145
+ end
146
+
147
+ sig { abstract.returns(T::Array[Parameter]) }
148
+ def parameters; end
149
+ end
150
+
151
+ class Accessor < Member
152
+ extend T::Sig
153
+
154
+ sig { override.returns(T::Array[Parameter]) }
155
+ def parameters
156
+ params = []
157
+ params << RequiredParameter.new(name: name.delete_suffix("=").to_sym) if name.end_with?("=")
158
+ params
159
+ end
160
+ end
161
+
162
+ class Method < Member
163
+ extend T::Sig
164
+ extend T::Helpers
165
+
166
+ abstract!
167
+
168
+ sig { override.returns(T::Array[Parameter]) }
169
+ attr_reader :parameters
170
+
107
171
  sig do
108
172
  params(
109
173
  name: String,
@@ -115,9 +179,9 @@ module RubyIndexer
115
179
  ).void
116
180
  end
117
181
  def initialize(name, file_path, location, comments, parameters_node, owner) # rubocop:disable Metrics/ParameterLists
118
- super(name, file_path, location, comments)
182
+ super(name, file_path, location, comments, owner)
183
+
119
184
  @parameters = T.let(list_params(parameters_node), T::Array[Parameter])
120
- @owner = owner
121
185
  end
122
186
 
123
187
  private
@@ -126,23 +190,78 @@ module RubyIndexer
126
190
  def list_params(parameters_node)
127
191
  return [] unless parameters_node
128
192
 
129
- parameters_node.requireds.filter_map do |required|
193
+ parameters = []
194
+
195
+ parameters_node.requireds.each do |required|
130
196
  name = parameter_name(required)
131
197
  next unless name
132
198
 
133
- RequiredParameter.new(name: name)
199
+ parameters << RequiredParameter.new(name: name)
134
200
  end
135
- end
136
201
 
137
- sig do
138
- params(node: Prism::Node).returns(T.nilable(Symbol))
202
+ parameters_node.optionals.each do |optional|
203
+ name = parameter_name(optional)
204
+ next unless name
205
+
206
+ parameters << OptionalParameter.new(name: name)
207
+ end
208
+
209
+ parameters_node.keywords.each do |keyword|
210
+ name = parameter_name(keyword)
211
+ next unless name
212
+
213
+ case keyword
214
+ when Prism::RequiredKeywordParameterNode
215
+ parameters << KeywordParameter.new(name: name)
216
+ when Prism::OptionalKeywordParameterNode
217
+ parameters << OptionalKeywordParameter.new(name: name)
218
+ end
219
+ end
220
+
221
+ rest = parameters_node.rest
222
+
223
+ if rest
224
+ rest_name = rest.name || RestParameter::DEFAULT_NAME
225
+ parameters << RestParameter.new(name: rest_name)
226
+ end
227
+
228
+ keyword_rest = parameters_node.keyword_rest
229
+
230
+ if keyword_rest.is_a?(Prism::KeywordRestParameterNode)
231
+ keyword_rest_name = parameter_name(keyword_rest) || KeywordRestParameter::DEFAULT_NAME
232
+ parameters << KeywordRestParameter.new(name: keyword_rest_name)
233
+ end
234
+
235
+ parameters_node.posts.each do |post|
236
+ name = parameter_name(post)
237
+ next unless name
238
+
239
+ parameters << RequiredParameter.new(name: name)
240
+ end
241
+
242
+ block = parameters_node.block
243
+ parameters << BlockParameter.new(name: block.name || BlockParameter::DEFAULT_NAME) if block
244
+
245
+ parameters
139
246
  end
247
+
248
+ sig { params(node: T.nilable(Prism::Node)).returns(T.nilable(Symbol)) }
140
249
  def parameter_name(node)
141
250
  case node
142
- when Prism::RequiredParameterNode
251
+ when Prism::RequiredParameterNode, Prism::OptionalParameterNode,
252
+ Prism::RequiredKeywordParameterNode, Prism::OptionalKeywordParameterNode,
253
+ Prism::RestParameterNode, Prism::KeywordRestParameterNode
143
254
  node.name
144
255
  when Prism::MultiTargetNode
145
- names = [*node.lefts, *node.rest, *node.rights].map { |parameter_node| parameter_name(parameter_node) }
256
+ names = node.lefts.map { |parameter_node| parameter_name(parameter_node) }
257
+
258
+ rest = node.rest
259
+ if rest.is_a?(Prism::SplatNode)
260
+ name = rest.expression&.slice
261
+ names << (rest.operator == "*" ? "*#{name}".to_sym : name&.to_sym)
262
+ end
263
+
264
+ names.concat(node.rights.map { |parameter_node| parameter_name(parameter_node) })
146
265
 
147
266
  names_with_commas = names.join(", ")
148
267
  :"(#{names_with_commas})"
@@ -84,6 +84,16 @@ module RubyIndexer
84
84
  )
85
85
  end
86
86
 
87
+ def test_indexables_does_not_include_non_ruby_files_inside_rubylibdir
88
+ path = Pathname.new(RbConfig::CONFIG["rubylibdir"]).join("extra_file.txt").to_s
89
+ FileUtils.touch(path)
90
+ indexables = @config.indexables
91
+
92
+ assert(indexables.none? { |indexable| indexable.full_path == path })
93
+ ensure
94
+ FileUtils.rm(T.must(path))
95
+ end
96
+
87
97
  def test_paths_are_unique
88
98
  @config.load_config
89
99
  indexables = @config.indexables
@@ -246,5 +246,16 @@ module RubyIndexer
246
246
  entry = T.must(entries.first).first
247
247
  assert_equal("baz", entry.name)
248
248
  end
249
+
250
+ def test_indexing_prism_fixtures_succeeds
251
+ fixtures = Dir.glob("test/fixtures/prism/test/prism/fixtures/**/*.txt")
252
+
253
+ fixtures.each do |fixture|
254
+ indexable_path = IndexablePath.new("", fixture)
255
+ @index.index_single(indexable_path)
256
+ end
257
+
258
+ refute_empty(@index.instance_variable_get(:@entries))
259
+ end
249
260
  end
250
261
  end
@@ -70,6 +70,178 @@ module RubyIndexer
70
70
  assert_instance_of(Entry::RequiredParameter, parameter)
71
71
  end
72
72
 
73
+ def test_method_with_optional_parameters
74
+ index(<<~RUBY)
75
+ class Foo
76
+ def bar(a = 123)
77
+ end
78
+ end
79
+ RUBY
80
+
81
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
82
+ entry = T.must(@index["bar"].first)
83
+ assert_equal(1, entry.parameters.length)
84
+ parameter = entry.parameters.first
85
+ assert_equal(:a, parameter.name)
86
+ assert_instance_of(Entry::OptionalParameter, parameter)
87
+ end
88
+
89
+ def test_method_with_keyword_parameters
90
+ index(<<~RUBY)
91
+ class Foo
92
+ def bar(a:, b: 123)
93
+ end
94
+ end
95
+ RUBY
96
+
97
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
98
+ entry = T.must(@index["bar"].first)
99
+ assert_equal(2, entry.parameters.length)
100
+ a, b = entry.parameters
101
+
102
+ assert_equal(:a, a.name)
103
+ assert_instance_of(Entry::KeywordParameter, a)
104
+
105
+ assert_equal(:b, b.name)
106
+ assert_instance_of(Entry::OptionalKeywordParameter, b)
107
+ end
108
+
109
+ def test_method_with_rest_and_keyword_rest_parameters
110
+ index(<<~RUBY)
111
+ class Foo
112
+ def bar(*a, **b)
113
+ end
114
+ end
115
+ RUBY
116
+
117
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
118
+ entry = T.must(@index["bar"].first)
119
+ assert_equal(2, entry.parameters.length)
120
+ a, b = entry.parameters
121
+
122
+ assert_equal(:a, a.name)
123
+ assert_instance_of(Entry::RestParameter, a)
124
+
125
+ assert_equal(:b, b.name)
126
+ assert_instance_of(Entry::KeywordRestParameter, b)
127
+ end
128
+
129
+ def test_method_with_post_parameters
130
+ index(<<~RUBY)
131
+ class Foo
132
+ def bar(*a, b)
133
+ end
134
+
135
+ def baz(**a, b)
136
+ end
137
+
138
+ def qux(*a, (b, c))
139
+ end
140
+ RUBY
141
+
142
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
143
+ entry = T.must(@index["bar"].first)
144
+ assert_equal(2, entry.parameters.length)
145
+ a, b = entry.parameters
146
+
147
+ assert_equal(:a, a.name)
148
+ assert_instance_of(Entry::RestParameter, a)
149
+
150
+ assert_equal(:b, b.name)
151
+ assert_instance_of(Entry::RequiredParameter, b)
152
+
153
+ entry = T.must(@index["baz"].first)
154
+ assert_equal(2, entry.parameters.length)
155
+ a, b = entry.parameters
156
+
157
+ assert_equal(:a, a.name)
158
+ assert_instance_of(Entry::KeywordRestParameter, a)
159
+
160
+ assert_equal(:b, b.name)
161
+ assert_instance_of(Entry::RequiredParameter, b)
162
+
163
+ entry = T.must(@index["qux"].first)
164
+ assert_equal(2, entry.parameters.length)
165
+ _a, second = entry.parameters
166
+
167
+ assert_equal(:"(b, c)", second.name)
168
+ assert_instance_of(Entry::RequiredParameter, second)
169
+ end
170
+
171
+ def test_method_with_destructured_rest_parameters
172
+ index(<<~RUBY)
173
+ class Foo
174
+ def bar((a, *b))
175
+ end
176
+ end
177
+ RUBY
178
+
179
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
180
+ entry = T.must(@index["bar"].first)
181
+ assert_equal(1, entry.parameters.length)
182
+ param = entry.parameters.first
183
+
184
+ assert_equal(:"(a, *b)", param.name)
185
+ assert_instance_of(Entry::RequiredParameter, param)
186
+ end
187
+
188
+ def test_method_with_block_parameters
189
+ index(<<~RUBY)
190
+ class Foo
191
+ def bar(&block)
192
+ end
193
+
194
+ def baz(&)
195
+ end
196
+ end
197
+ RUBY
198
+
199
+ entry = T.must(@index["bar"].first)
200
+ param = entry.parameters.first
201
+ assert_equal(:block, param.name)
202
+ assert_instance_of(Entry::BlockParameter, param)
203
+
204
+ entry = T.must(@index["baz"].first)
205
+ assert_equal(1, entry.parameters.length)
206
+
207
+ param = entry.parameters.first
208
+ assert_equal(Entry::BlockParameter::DEFAULT_NAME, param.name)
209
+ assert_instance_of(Entry::BlockParameter, param)
210
+ end
211
+
212
+ def test_method_with_anonymous_rest_parameters
213
+ index(<<~RUBY)
214
+ class Foo
215
+ def bar(*, **)
216
+ end
217
+ end
218
+ RUBY
219
+
220
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
221
+ entry = T.must(@index["bar"].first)
222
+ assert_equal(2, entry.parameters.length)
223
+ first, second = entry.parameters
224
+
225
+ assert_equal(Entry::RestParameter::DEFAULT_NAME, first.name)
226
+ assert_instance_of(Entry::RestParameter, first)
227
+
228
+ assert_equal(Entry::KeywordRestParameter::DEFAULT_NAME, second.name)
229
+ assert_instance_of(Entry::KeywordRestParameter, second)
230
+ end
231
+
232
+ def test_method_with_forbidden_keyword_splat_parameter
233
+ index(<<~RUBY)
234
+ class Foo
235
+ def bar(**nil)
236
+ end
237
+ end
238
+ RUBY
239
+
240
+ assert_entry("bar", Entry::InstanceMethod, "/fake/path/foo.rb:1-2:2-5")
241
+ entry = T.must(@index["bar"].first)
242
+ assert_empty(entry.parameters)
243
+ end
244
+
73
245
  def test_keeps_track_of_method_owner
74
246
  index(<<~RUBY)
75
247
  class Foo
@@ -83,5 +255,35 @@ module RubyIndexer
83
255
 
84
256
  assert_equal("Foo", owner_name)
85
257
  end
258
+
259
+ def test_keeps_track_of_attributes
260
+ index(<<~RUBY)
261
+ class Foo
262
+ # Hello there
263
+ attr_reader :bar, :other
264
+ attr_writer :baz
265
+ attr_accessor :qux
266
+ end
267
+ RUBY
268
+
269
+ assert_entry("bar", Entry::Accessor, "/fake/path/foo.rb:2-15:2-18")
270
+ assert_equal("Hello there", @index["bar"].first.comments.join("\n"))
271
+ assert_entry("other", Entry::Accessor, "/fake/path/foo.rb:2-21:2-26")
272
+ assert_equal("Hello there", @index["other"].first.comments.join("\n"))
273
+ assert_entry("baz=", Entry::Accessor, "/fake/path/foo.rb:3-15:3-18")
274
+ assert_entry("qux", Entry::Accessor, "/fake/path/foo.rb:4-17:4-20")
275
+ assert_entry("qux=", Entry::Accessor, "/fake/path/foo.rb:4-17:4-20")
276
+ end
277
+
278
+ def test_ignores_attributes_invoked_on_constant
279
+ index(<<~RUBY)
280
+ class Foo
281
+ end
282
+
283
+ Foo.attr_reader :bar
284
+ RUBY
285
+
286
+ assert_no_entry("bar")
287
+ end
86
288
  end
87
289
  end
@@ -41,8 +41,8 @@ module RubyLsp
41
41
  end
42
42
 
43
43
  # Discovers and loads all addons. Returns the list of activated addons
44
- sig { returns(T::Array[Addon]) }
45
- def load_addons
44
+ sig { params(message_queue: Thread::Queue).returns(T::Array[Addon]) }
45
+ def load_addons(message_queue)
46
46
  # Require all addons entry points, which should be placed under
47
47
  # `some_gem/lib/ruby_lsp/your_gem_name/addon.rb`
48
48
  Gem.find_files("ruby_lsp/**/addon.rb").each do |addon|
@@ -55,7 +55,7 @@ module RubyLsp
55
55
  # Activate each one of the discovered addons. If any problems occur in the addons, we don't want to
56
56
  # fail to boot the server
57
57
  addons.each do |addon|
58
- addon.activate
58
+ addon.activate(message_queue)
59
59
  nil
60
60
  rescue => e
61
61
  addon.add_error(e)
@@ -94,8 +94,8 @@ module RubyLsp
94
94
 
95
95
  # Each addon should implement `MyAddon#activate` and use to perform any sort of initialization, such as
96
96
  # reading information into memory or even spawning a separate process
97
- sig { abstract.void }
98
- def activate; end
97
+ sig { abstract.params(message_queue: Thread::Queue).void }
98
+ def activate(message_queue); end
99
99
 
100
100
  # Each addon should implement `MyAddon#deactivate` and use to perform any clean up, like shutting down a
101
101
  # child process
@@ -111,10 +111,9 @@ module RubyLsp
111
111
  overridable.params(
112
112
  uri: URI::Generic,
113
113
  dispatcher: Prism::Dispatcher,
114
- message_queue: Thread::Queue,
115
114
  ).returns(T.nilable(Listener[T::Array[Interface::CodeLens]]))
116
115
  end
117
- def create_code_lens_listener(uri, dispatcher, message_queue); end
116
+ def create_code_lens_listener(uri, dispatcher); end
118
117
 
119
118
  # Creates a new Hover listener. This method is invoked on every Hover request
120
119
  sig do
@@ -122,19 +121,17 @@ module RubyLsp
122
121
  nesting: T::Array[String],
123
122
  index: RubyIndexer::Index,
124
123
  dispatcher: Prism::Dispatcher,
125
- message_queue: Thread::Queue,
126
124
  ).returns(T.nilable(Listener[T.nilable(Interface::Hover)]))
127
125
  end
128
- def create_hover_listener(nesting, index, dispatcher, message_queue); end
126
+ def create_hover_listener(nesting, index, dispatcher); end
129
127
 
130
128
  # Creates a new DocumentSymbol listener. This method is invoked on every DocumentSymbol request
131
129
  sig do
132
130
  overridable.params(
133
131
  dispatcher: Prism::Dispatcher,
134
- message_queue: Thread::Queue,
135
132
  ).returns(T.nilable(Listener[T::Array[Interface::DocumentSymbol]]))
136
133
  end
137
- def create_document_symbol_listener(dispatcher, message_queue); end
134
+ def create_document_symbol_listener(dispatcher); end
138
135
 
139
136
  # Creates a new Definition listener. This method is invoked on every Definition request
140
137
  sig do
@@ -143,9 +140,8 @@ module RubyLsp
143
140
  nesting: T::Array[String],
144
141
  index: RubyIndexer::Index,
145
142
  dispatcher: Prism::Dispatcher,
146
- message_queue: Thread::Queue,
147
143
  ).returns(T.nilable(Listener[T.nilable(T.any(T::Array[Interface::Location], Interface::Location))]))
148
144
  end
149
- def create_definition_listener(uri, nesting, index, dispatcher, message_queue); end
145
+ def create_definition_listener(uri, nesting, index, dispatcher); end
150
146
  end
151
147
  end
@@ -24,6 +24,9 @@ module RubyLsp
24
24
  sig { returns(URI::Generic) }
25
25
  attr_reader :uri
26
26
 
27
+ sig { returns(String) }
28
+ attr_reader :encoding
29
+
27
30
  sig { params(source: String, version: Integer, uri: URI::Generic, encoding: String).void }
28
31
  def initialize(source:, version:, uri:, encoding: Constant::PositionEncodingKind::UTF8)
29
32
  @cache = T.let({}, T::Hash[String, T.untyped])