ruby-lsp 0.14.6 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/exe/ruby-lsp +1 -16
  4. data/exe/ruby-lsp-check +13 -22
  5. data/exe/ruby-lsp-doctor +9 -0
  6. data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +14 -1
  7. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +11 -23
  8. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +4 -0
  9. data/lib/ruby_indexer/test/classes_and_modules_test.rb +46 -0
  10. data/lib/ruby_indexer/test/configuration_test.rb +2 -11
  11. data/lib/ruby_lsp/addon.rb +18 -9
  12. data/lib/ruby_lsp/base_server.rb +147 -0
  13. data/lib/ruby_lsp/document.rb +0 -5
  14. data/lib/ruby_lsp/{requests/support/dependency_detector.rb → global_state.rb} +41 -9
  15. data/lib/ruby_lsp/internal.rb +4 -1
  16. data/lib/ruby_lsp/listeners/code_lens.rb +13 -9
  17. data/lib/ruby_lsp/listeners/completion.rb +13 -14
  18. data/lib/ruby_lsp/listeners/definition.rb +4 -3
  19. data/lib/ruby_lsp/listeners/document_symbol.rb +91 -3
  20. data/lib/ruby_lsp/listeners/hover.rb +6 -5
  21. data/lib/ruby_lsp/listeners/signature_help.rb +7 -4
  22. data/lib/ruby_lsp/load_sorbet.rb +62 -0
  23. data/lib/ruby_lsp/requests/code_lens.rb +3 -2
  24. data/lib/ruby_lsp/requests/completion.rb +15 -4
  25. data/lib/ruby_lsp/requests/completion_resolve.rb +56 -0
  26. data/lib/ruby_lsp/requests/definition.rb +11 -4
  27. data/lib/ruby_lsp/requests/diagnostics.rb +6 -12
  28. data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
  29. data/lib/ruby_lsp/requests/formatting.rb +7 -43
  30. data/lib/ruby_lsp/requests/hover.rb +4 -4
  31. data/lib/ruby_lsp/requests/request.rb +2 -0
  32. data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
  33. data/lib/ruby_lsp/requests/signature_help.rb +4 -3
  34. data/lib/ruby_lsp/requests/support/common.rb +16 -5
  35. data/lib/ruby_lsp/requests/support/formatter.rb +26 -0
  36. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +50 -0
  37. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
  38. data/lib/ruby_lsp/requests/support/{syntax_tree_formatting_runner.rb → syntax_tree_formatter.rb} +13 -3
  39. data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
  40. data/lib/ruby_lsp/requests.rb +3 -1
  41. data/lib/ruby_lsp/server.rb +770 -142
  42. data/lib/ruby_lsp/store.rb +0 -8
  43. data/lib/ruby_lsp/test_helper.rb +52 -0
  44. data/lib/ruby_lsp/utils.rb +68 -33
  45. metadata +11 -9
  46. data/lib/ruby_lsp/executor.rb +0 -614
  47. data/lib/ruby_lsp/requests/support/formatter_runner.rb +0 -18
  48. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +0 -34
  49. data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +0 -35
@@ -27,12 +27,14 @@ module RubyLsp
27
27
  sig do
28
28
  params(
29
29
  response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
30
+ global_state: GlobalState,
30
31
  uri: URI::Generic,
31
32
  dispatcher: Prism::Dispatcher,
32
33
  ).void
33
34
  end
34
- def initialize(response_builder, uri, dispatcher)
35
+ def initialize(response_builder, global_state, uri, dispatcher)
35
36
  @response_builder = response_builder
37
+ @global_state = global_state
36
38
  @uri = T.let(uri, URI::Generic)
37
39
  @path = T.let(uri.to_standardized_path, T.nilable(String))
38
40
  # visibility_stack is a stack of [current_visibility, previous_visibility]
@@ -156,7 +158,7 @@ module RubyLsp
156
158
  sig { params(node: Prism::Node, name: String, command: String, kind: Symbol).void }
157
159
  def add_test_code_lens(node, name:, command:, kind:)
158
160
  # don't add code lenses if the test library is not supported or unknown
159
- return unless SUPPORTED_TEST_LIBRARIES.include?(DependencyDetector.instance.detected_test_library) && @path
161
+ return unless SUPPORTED_TEST_LIBRARIES.include?(@global_state.test_library) && @path
160
162
 
161
163
  arguments = [
162
164
  @path,
@@ -208,7 +210,7 @@ module RubyLsp
208
210
  def generate_test_command(group_stack: [], spec_name: nil, method_name: nil)
209
211
  command = BASE_COMMAND + T.must(@path)
210
212
 
211
- case DependencyDetector.instance.detected_test_library
213
+ case @global_state.test_library
212
214
  when "minitest"
213
215
  last_dynamic_reference_index = group_stack.rindex(DYNAMIC_REFERENCE_MARKER)
214
216
  command += if last_dynamic_reference_index
@@ -264,12 +266,14 @@ module RubyLsp
264
266
 
265
267
  return unless name
266
268
 
267
- add_test_code_lens(
268
- node,
269
- name: name,
270
- command: generate_test_command(spec_name: name),
271
- kind: kind,
272
- )
269
+ if @path
270
+ add_test_code_lens(
271
+ node,
272
+ name: name,
273
+ command: generate_test_command(spec_name: name),
274
+ kind: kind,
275
+ )
276
+ end
273
277
  end
274
278
  end
275
279
  end
@@ -10,16 +10,17 @@ module RubyLsp
10
10
  sig do
11
11
  params(
12
12
  response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
13
- index: RubyIndexer::Index,
13
+ global_state: GlobalState,
14
14
  nesting: T::Array[String],
15
15
  typechecker_enabled: T::Boolean,
16
16
  dispatcher: Prism::Dispatcher,
17
17
  uri: URI::Generic,
18
18
  ).void
19
19
  end
20
- def initialize(response_builder, index, nesting, typechecker_enabled, dispatcher, uri) # rubocop:disable Metrics/ParameterLists
20
+ def initialize(response_builder, global_state, nesting, typechecker_enabled, dispatcher, uri) # rubocop:disable Metrics/ParameterLists
21
21
  @response_builder = response_builder
22
- @index = index
22
+ @global_state = global_state
23
+ @index = T.let(global_state.index, RubyIndexer::Index)
23
24
  @nesting = nesting
24
25
  @typechecker_enabled = typechecker_enabled
25
26
  @uri = uri
@@ -35,7 +36,7 @@ module RubyLsp
35
36
  # Handle completion on regular constant references (e.g. `Bar`)
36
37
  sig { params(node: Prism::ConstantReadNode).void }
37
38
  def on_constant_read_node_enter(node)
38
- return if DependencyDetector.instance.typechecker
39
+ return if @global_state.typechecker
39
40
 
40
41
  name = constant_name(node)
41
42
  return if name.nil?
@@ -56,7 +57,7 @@ module RubyLsp
56
57
  # Handle completion on namespaced constant references (e.g. `Foo::Bar`)
57
58
  sig { params(node: Prism::ConstantPathNode).void }
58
59
  def on_constant_path_node_enter(node)
59
- return if DependencyDetector.instance.typechecker
60
+ return if @global_state.typechecker
60
61
 
61
62
  name = constant_name(node)
62
63
  return if name.nil?
@@ -77,7 +78,10 @@ module RubyLsp
77
78
 
78
79
  real_namespace = @index.follow_aliased_namespace(T.must(namespace_entries.first).name)
79
80
 
80
- candidates = @index.prefix_search("#{real_namespace}::#{incomplete_name}", top_level_reference ? [] : @nesting)
81
+ candidates = @index.prefix_search(
82
+ "#{real_namespace}::#{incomplete_name}",
83
+ top_level_reference ? [] : @nesting,
84
+ )
81
85
  candidates.each do |entries|
82
86
  # The only time we may have a private constant reference from outside of the namespace is if we're dealing
83
87
  # with ConstantPath and the entry name doesn't start with the current nesting
@@ -124,7 +128,9 @@ module RubyLsp
124
128
 
125
129
  return unless path_node_to_complete.is_a?(Prism::StringNode)
126
130
 
127
- @index.search_require_paths(path_node_to_complete.content).map!(&:require_path).sort!.each do |path|
131
+ matched_indexable_paths = @index.search_require_paths(path_node_to_complete.content)
132
+
133
+ matched_indexable_paths.map!(&:require_path).sort!.each do |path|
128
134
  @response_builder << build_completion(T.must(path), path_node_to_complete)
129
135
  end
130
136
  end
@@ -284,13 +290,6 @@ module RubyLsp
284
290
  new_text: insertion_text,
285
291
  ),
286
292
  kind: kind,
287
- label_details: Interface::CompletionItemLabelDetails.new(
288
- description: entries.map(&:file_name).join(","),
289
- ),
290
- documentation: Interface::MarkupContent.new(
291
- kind: "markdown",
292
- value: markdown_from_index_entries(real_name, entries),
293
- ),
294
293
  )
295
294
  end
296
295
 
@@ -10,18 +10,19 @@ module RubyLsp
10
10
  sig do
11
11
  params(
12
12
  response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::Location],
13
+ global_state: GlobalState,
13
14
  uri: URI::Generic,
14
15
  nesting: T::Array[String],
15
- index: RubyIndexer::Index,
16
16
  dispatcher: Prism::Dispatcher,
17
17
  typechecker_enabled: T::Boolean,
18
18
  ).void
19
19
  end
20
- def initialize(response_builder, uri, nesting, index, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
20
+ def initialize(response_builder, global_state, uri, nesting, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
21
21
  @response_builder = response_builder
22
+ @global_state = global_state
23
+ @index = T.let(global_state.index, RubyIndexer::Index)
22
24
  @uri = uri
23
25
  @nesting = nesting
24
- @index = index
25
26
  @typechecker_enabled = typechecker_enabled
26
27
 
27
28
  dispatcher.register(
@@ -12,17 +12,20 @@ module RubyLsp
12
12
  sig do
13
13
  params(
14
14
  response_builder: ResponseBuilders::DocumentSymbol,
15
+ uri: URI::Generic,
15
16
  dispatcher: Prism::Dispatcher,
16
17
  ).void
17
18
  end
18
- def initialize(response_builder, dispatcher)
19
+ def initialize(response_builder, uri, dispatcher)
19
20
  @response_builder = response_builder
21
+ @uri = uri
20
22
 
21
23
  dispatcher.register(
22
24
  self,
23
25
  :on_class_node_enter,
24
26
  :on_class_node_leave,
25
27
  :on_call_node_enter,
28
+ :on_call_node_leave,
26
29
  :on_constant_path_write_node_enter,
27
30
  :on_constant_write_node_enter,
28
31
  :on_constant_path_or_write_node_enter,
@@ -79,10 +82,24 @@ module RubyLsp
79
82
 
80
83
  sig { params(node: Prism::CallNode).void }
81
84
  def on_call_node_enter(node)
82
- if ATTR_ACCESSORS.include?(node.name)
85
+ node_name = node.name
86
+ if ATTR_ACCESSORS.include?(node_name)
83
87
  handle_attr_accessor(node)
84
- elsif node.name == :alias_method
88
+ elsif node_name == :alias_method
85
89
  handle_alias_method(node)
90
+ elsif node_name == :namespace
91
+ handle_rake_namespace(node)
92
+ elsif node_name == :task
93
+ handle_rake_task(node)
94
+ end
95
+ end
96
+
97
+ sig { params(node: Prism::CallNode).void }
98
+ def on_call_node_leave(node)
99
+ return unless rake?
100
+
101
+ if node.name == :namespace && !node.receiver
102
+ @response_builder.pop
86
103
  end
87
104
  end
88
105
 
@@ -279,6 +296,7 @@ module RubyLsp
279
296
  ).returns(Interface::DocumentSymbol)
280
297
  end
281
298
  def create_document_symbol(name:, kind:, range_location:, selection_range_location:)
299
+ name = "<blank>" if name.empty?
282
300
  symbol = Interface::DocumentSymbol.new(
283
301
  name: name,
284
302
  kind: kind,
@@ -357,6 +375,76 @@ module RubyLsp
357
375
  )
358
376
  end
359
377
  end
378
+
379
+ sig { params(node: Prism::CallNode).void }
380
+ def handle_rake_namespace(node)
381
+ return unless rake?
382
+ return if node.receiver
383
+
384
+ arguments = node.arguments
385
+ return unless arguments
386
+
387
+ name_argument = arguments.arguments.first
388
+ return unless name_argument
389
+
390
+ name = case name_argument
391
+ when Prism::StringNode then name_argument.content
392
+ when Prism::SymbolNode then name_argument.value
393
+ end
394
+
395
+ return if name.nil? || name.empty?
396
+
397
+ @response_builder << create_document_symbol(
398
+ name: name,
399
+ kind: Constant::SymbolKind::MODULE,
400
+ range_location: name_argument.location,
401
+ selection_range_location: name_argument.location,
402
+ )
403
+ end
404
+
405
+ sig { params(node: Prism::CallNode).void }
406
+ def handle_rake_task(node)
407
+ return unless rake?
408
+ return if node.receiver
409
+
410
+ arguments = node.arguments
411
+ return unless arguments
412
+
413
+ name_argument = arguments.arguments.first
414
+ return unless name_argument
415
+
416
+ name = case name_argument
417
+ when Prism::StringNode then name_argument.content
418
+ when Prism::SymbolNode then name_argument.value
419
+ when Prism::KeywordHashNode
420
+ first_element = name_argument.elements.first
421
+ if first_element.is_a?(Prism::AssocNode)
422
+ key = first_element.key
423
+ case key
424
+ when Prism::StringNode then key.content
425
+ when Prism::SymbolNode then key.value
426
+ end
427
+ end
428
+ end
429
+
430
+ return if name.nil? || name.empty?
431
+
432
+ create_document_symbol(
433
+ name: name,
434
+ kind: Constant::SymbolKind::METHOD,
435
+ range_location: name_argument.location,
436
+ selection_range_location: name_argument.location,
437
+ )
438
+ end
439
+
440
+ sig { returns(T::Boolean) }
441
+ def rake?
442
+ if (path = @uri.to_standardized_path)
443
+ path.match?(/(Rakefile|\.rake)$/)
444
+ else
445
+ false
446
+ end
447
+ end
360
448
  end
361
449
  end
362
450
  end
@@ -28,18 +28,19 @@ module RubyLsp
28
28
  sig do
29
29
  params(
30
30
  response_builder: ResponseBuilders::Hover,
31
+ global_state: GlobalState,
31
32
  uri: URI::Generic,
32
33
  nesting: T::Array[String],
33
- index: RubyIndexer::Index,
34
34
  dispatcher: Prism::Dispatcher,
35
35
  typechecker_enabled: T::Boolean,
36
36
  ).void
37
37
  end
38
- def initialize(response_builder, uri, nesting, index, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
38
+ def initialize(response_builder, global_state, uri, nesting, dispatcher, typechecker_enabled) # rubocop:disable Metrics/ParameterLists
39
39
  @response_builder = response_builder
40
+ @global_state = global_state
41
+ @index = T.let(global_state.index, RubyIndexer::Index)
40
42
  @path = T.let(uri.to_standardized_path, T.nilable(String))
41
43
  @nesting = nesting
42
- @index = index
43
44
  @typechecker_enabled = typechecker_enabled
44
45
 
45
46
  dispatcher.register(
@@ -63,14 +64,14 @@ module RubyLsp
63
64
 
64
65
  sig { params(node: Prism::ConstantWriteNode).void }
65
66
  def on_constant_write_node_enter(node)
66
- return if DependencyDetector.instance.typechecker
67
+ return if @global_state.typechecker
67
68
 
68
69
  generate_hover(node.name.to_s, node.name_loc)
69
70
  end
70
71
 
71
72
  sig { params(node: Prism::ConstantPathNode).void }
72
73
  def on_constant_path_node_enter(node)
73
- return if DependencyDetector.instance.typechecker
74
+ return if @global_state.typechecker
74
75
 
75
76
  name = constant_name(node)
76
77
  return if name.nil?
@@ -10,21 +10,24 @@ module RubyLsp
10
10
  sig do
11
11
  params(
12
12
  response_builder: ResponseBuilders::SignatureHelp,
13
+ global_state: GlobalState,
13
14
  nesting: T::Array[String],
14
- index: RubyIndexer::Index,
15
15
  dispatcher: Prism::Dispatcher,
16
+ typechecker_enabled: T::Boolean,
16
17
  ).void
17
18
  end
18
- def initialize(response_builder, nesting, index, dispatcher)
19
+ def initialize(response_builder, global_state, nesting, dispatcher, typechecker_enabled)
20
+ @typechecker_enabled = typechecker_enabled
19
21
  @response_builder = response_builder
22
+ @global_state = global_state
23
+ @index = T.let(global_state.index, RubyIndexer::Index)
20
24
  @nesting = nesting
21
- @index = index
22
25
  dispatcher.register(self, :on_call_node_enter)
23
26
  end
24
27
 
25
28
  sig { params(node: Prism::CallNode).void }
26
29
  def on_call_node_enter(node)
27
- return if DependencyDetector.instance.typechecker
30
+ return if @typechecker_enabled
28
31
  return unless self_receiver?(node)
29
32
 
30
33
  message = node.message
@@ -0,0 +1,62 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require "sorbet-runtime"
5
+
6
+ begin
7
+ T::Configuration.default_checked_level = :never
8
+ # Suppresses call validation errors
9
+ T::Configuration.call_validation_error_handler = ->(*) {}
10
+ # Suppresses errors caused by T.cast, T.let, T.must, etc.
11
+ T::Configuration.inline_type_error_handler = ->(*) {}
12
+ # Suppresses errors caused by incorrect parameter ordering
13
+ T::Configuration.sig_validation_error_handler = ->(*) {}
14
+ rescue
15
+ # Need this rescue so that if another gem has
16
+ # already set the checked level by the time we
17
+ # get to it, we don't fail outright.
18
+ nil
19
+ end
20
+
21
+ module RubyLsp
22
+ # No-op all inline type assertions defined in T
23
+ module InlineTypeAssertions
24
+ def absurd(value)
25
+ value
26
+ end
27
+
28
+ def any(type_a, type_b, *types)
29
+ T::Types::Union.new([type_a, type_b, *types])
30
+ end
31
+
32
+ def assert_type!(value, type, checked: true)
33
+ value
34
+ end
35
+
36
+ def bind(value, type, checked: true)
37
+ value
38
+ end
39
+
40
+ def cast(value, type, checked: true)
41
+ value
42
+ end
43
+
44
+ def let(value, type, checked: true)
45
+ value
46
+ end
47
+
48
+ def must(arg)
49
+ arg
50
+ end
51
+
52
+ def nilable(type)
53
+ T::Types::Union.new([type, T::Utils::Nilable::NIL_TYPE])
54
+ end
55
+
56
+ def unsafe(value)
57
+ value
58
+ end
59
+
60
+ T.singleton_class.prepend(self)
61
+ end
62
+ end
@@ -34,17 +34,18 @@ module RubyLsp
34
34
 
35
35
  sig do
36
36
  params(
37
+ global_state: GlobalState,
37
38
  uri: URI::Generic,
38
39
  dispatcher: Prism::Dispatcher,
39
40
  ).void
40
41
  end
41
- def initialize(uri, dispatcher)
42
+ def initialize(global_state, uri, dispatcher)
42
43
  @response_builder = T.let(
43
44
  ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens].new,
44
45
  ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
45
46
  )
46
47
  super()
47
- Listeners::CodeLens.new(@response_builder, uri, dispatcher)
48
+ Listeners::CodeLens.new(@response_builder, global_state, uri, dispatcher)
48
49
 
49
50
  Addon.addons.each do |addon|
50
51
  addon.create_code_lens_listener(@response_builder, uri, dispatcher)
@@ -33,7 +33,7 @@ module RubyLsp
33
33
  sig { returns(Interface::CompletionOptions) }
34
34
  def provider
35
35
  Interface::CompletionOptions.new(
36
- resolve_provider: false,
36
+ resolve_provider: true,
37
37
  trigger_characters: ["/", "\"", "'"],
38
38
  completion_item: {
39
39
  labelDetailsSupport: true,
@@ -45,13 +45,13 @@ module RubyLsp
45
45
  sig do
46
46
  params(
47
47
  document: Document,
48
- index: RubyIndexer::Index,
48
+ global_state: GlobalState,
49
49
  position: T::Hash[Symbol, T.untyped],
50
50
  typechecker_enabled: T::Boolean,
51
51
  dispatcher: Prism::Dispatcher,
52
52
  ).void
53
53
  end
54
- def initialize(document, index, position, typechecker_enabled, dispatcher)
54
+ def initialize(document, global_state, position, typechecker_enabled, dispatcher)
55
55
  super()
56
56
  @target = T.let(nil, T.nilable(Prism::Node))
57
57
  @dispatcher = dispatcher
@@ -68,7 +68,18 @@ module RubyLsp
68
68
  ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
69
69
  )
70
70
 
71
- Listeners::Completion.new(@response_builder, index, nesting, typechecker_enabled, dispatcher, document.uri)
71
+ Listeners::Completion.new(
72
+ @response_builder,
73
+ global_state,
74
+ nesting,
75
+ typechecker_enabled,
76
+ dispatcher,
77
+ document.uri,
78
+ )
79
+
80
+ Addon.addons.each do |addon|
81
+ addon.create_completion_listener(@response_builder, nesting, dispatcher, document.uri)
82
+ end
72
83
 
73
84
  return unless matched && parent
74
85
 
@@ -0,0 +1,56 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module Requests
6
+ # ![Completion resolve demo](../../completion_resolve.gif)
7
+ #
8
+ # The [completionItem/resolve](https://microsoft.github.io/language-server-protocol/specification#completionItem_resolve)
9
+ # request provides additional information about the currently selected completion. Specifically, the `labelDetails`
10
+ # and `documentation` fields are provided, which are omitted from the completion items returned by
11
+ # `textDocument/completion`.
12
+ #
13
+ # The `labelDetails` field lists the files where the completion item is defined, and the `documentation` field
14
+ # includes any available documentation for those definitions.
15
+ #
16
+ # At most 10 definitions are included, to ensure low latency during request processing and rendering the completion
17
+ # item.
18
+ #
19
+ # # Example
20
+ #
21
+ # ```ruby
22
+ # A # -> as the user cycles through completion items, the documentation will be resolved and displayed
23
+ # ```
24
+ class CompletionResolve < Request
25
+ extend T::Sig
26
+ include Requests::Support::Common
27
+
28
+ # set a limit on the number of documentation entries returned, to avoid rendering performance issues
29
+ # https://github.com/Shopify/ruby-lsp/pull/1798
30
+ MAX_DOCUMENTATION_ENTRIES = 10
31
+
32
+ sig { params(global_state: GlobalState, item: T::Hash[Symbol, T.untyped]).void }
33
+ def initialize(global_state, item)
34
+ super()
35
+ @index = T.let(global_state.index, RubyIndexer::Index)
36
+ @item = item
37
+ end
38
+
39
+ sig { override.returns(Interface::CompletionItem) }
40
+ def perform
41
+ label = @item[:label]
42
+ entries = @index[label] || []
43
+ Interface::CompletionItem.new(
44
+ label: label,
45
+ label_details: Interface::CompletionItemLabelDetails.new(
46
+ description: entries.take(MAX_DOCUMENTATION_ENTRIES).map(&:file_name).join(","),
47
+ ),
48
+ documentation: Interface::MarkupContent.new(
49
+ kind: "markdown",
50
+ value: markdown_from_index_entries(label, entries, MAX_DOCUMENTATION_ENTRIES),
51
+ ),
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
@@ -31,13 +31,13 @@ module RubyLsp
31
31
  sig do
32
32
  params(
33
33
  document: Document,
34
- index: RubyIndexer::Index,
34
+ global_state: GlobalState,
35
35
  position: T::Hash[Symbol, T.untyped],
36
36
  dispatcher: Prism::Dispatcher,
37
37
  typechecker_enabled: T::Boolean,
38
38
  ).void
39
39
  end
40
- def initialize(document, index, position, dispatcher, typechecker_enabled)
40
+ def initialize(document, global_state, position, dispatcher, typechecker_enabled)
41
41
  super()
42
42
  @response_builder = T.let(
43
43
  ResponseBuilders::CollectionResponseBuilder[Interface::Location].new,
@@ -57,10 +57,17 @@ module RubyLsp
57
57
  )
58
58
  end
59
59
 
60
- Listeners::Definition.new(@response_builder, document.uri, nesting, index, dispatcher, typechecker_enabled)
60
+ Listeners::Definition.new(
61
+ @response_builder,
62
+ global_state,
63
+ document.uri,
64
+ nesting,
65
+ dispatcher,
66
+ typechecker_enabled,
67
+ )
61
68
 
62
69
  Addon.addons.each do |addon|
63
- addon.create_definition_listener(@response_builder, document.uri, nesting, index, dispatcher)
70
+ addon.create_definition_listener(@response_builder, document.uri, nesting, dispatcher)
64
71
  end
65
72
 
66
73
  @target = T.let(target, T.nilable(Prism::Node))
@@ -1,8 +1,6 @@
1
1
  # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
- require "ruby_lsp/requests/support/rubocop_diagnostics_runner"
5
-
6
4
  module RubyLsp
7
5
  module Requests
8
6
  # ![Diagnostics demo](../../diagnostics.gif)
@@ -33,9 +31,10 @@ module RubyLsp
33
31
  end
34
32
  end
35
33
 
36
- sig { params(document: Document).void }
37
- def initialize(document)
34
+ sig { params(global_state: GlobalState, document: Document).void }
35
+ def initialize(global_state, document)
38
36
  super()
37
+ @active_formatter = T.let(global_state.active_formatter, T.nilable(Support::Formatter))
39
38
  @document = document
40
39
  @uri = T.let(document.uri, URI::Generic)
41
40
  end
@@ -46,15 +45,10 @@ module RubyLsp
46
45
  diagnostics.concat(syntax_error_diagnostics, syntax_warning_diagnostics)
47
46
 
48
47
  # Running RuboCop is slow, so to avoid excessive runs we only do so if the file is syntactically valid
49
- return diagnostics if @document.syntax_error?
50
-
51
- diagnostics.concat(
52
- Support::RuboCopDiagnosticsRunner.instance.run(
53
- @uri,
54
- @document,
55
- ).map!(&:to_lsp_diagnostic),
56
- ) if defined?(Support::RuboCopDiagnosticsRunner)
48
+ return diagnostics if @document.syntax_error? || !@active_formatter
57
49
 
50
+ formatter_diagnostics = @active_formatter.run_diagnostic(@uri, @document)
51
+ diagnostics.concat(formatter_diagnostics) if formatter_diagnostics
58
52
  diagnostics
59
53
  end
60
54
 
@@ -45,11 +45,11 @@ module RubyLsp
45
45
  end
46
46
  end
47
47
 
48
- sig { params(dispatcher: Prism::Dispatcher).void }
49
- def initialize(dispatcher)
48
+ sig { params(uri: URI::Generic, dispatcher: Prism::Dispatcher).void }
49
+ def initialize(uri, dispatcher)
50
50
  super()
51
51
  @response_builder = T.let(ResponseBuilders::DocumentSymbol.new, ResponseBuilders::DocumentSymbol)
52
- Listeners::DocumentSymbol.new(@response_builder, dispatcher)
52
+ Listeners::DocumentSymbol.new(@response_builder, uri, dispatcher)
53
53
 
54
54
  Addon.addons.each do |addon|
55
55
  addon.create_document_symbol_listener(@response_builder, dispatcher)