ruby-lsp 0.14.6 → 0.16.4

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +1 -16
  5. data/exe/ruby-lsp-check +13 -22
  6. data/exe/ruby-lsp-doctor +9 -0
  7. data/lib/ruby_indexer/lib/ruby_indexer/collector.rb +14 -1
  8. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +11 -23
  9. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +4 -0
  10. data/lib/ruby_indexer/test/classes_and_modules_test.rb +46 -0
  11. data/lib/ruby_indexer/test/configuration_test.rb +2 -11
  12. data/lib/ruby_lsp/addon.rb +18 -9
  13. data/lib/ruby_lsp/base_server.rb +149 -0
  14. data/lib/ruby_lsp/document.rb +6 -11
  15. data/lib/ruby_lsp/global_state.rb +169 -0
  16. data/lib/ruby_lsp/internal.rb +4 -1
  17. data/lib/ruby_lsp/listeners/code_lens.rb +22 -13
  18. data/lib/ruby_lsp/listeners/completion.rb +13 -14
  19. data/lib/ruby_lsp/listeners/definition.rb +4 -3
  20. data/lib/ruby_lsp/listeners/document_symbol.rb +91 -3
  21. data/lib/ruby_lsp/listeners/hover.rb +6 -5
  22. data/lib/ruby_lsp/listeners/signature_help.rb +7 -4
  23. data/lib/ruby_lsp/load_sorbet.rb +62 -0
  24. data/lib/ruby_lsp/requests/code_lens.rb +3 -2
  25. data/lib/ruby_lsp/requests/completion.rb +15 -4
  26. data/lib/ruby_lsp/requests/completion_resolve.rb +56 -0
  27. data/lib/ruby_lsp/requests/definition.rb +11 -4
  28. data/lib/ruby_lsp/requests/diagnostics.rb +6 -12
  29. data/lib/ruby_lsp/requests/document_symbol.rb +3 -3
  30. data/lib/ruby_lsp/requests/formatting.rb +7 -43
  31. data/lib/ruby_lsp/requests/hover.rb +4 -4
  32. data/lib/ruby_lsp/requests/request.rb +2 -0
  33. data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
  34. data/lib/ruby_lsp/requests/signature_help.rb +4 -3
  35. data/lib/ruby_lsp/requests/support/common.rb +16 -5
  36. data/lib/ruby_lsp/requests/support/formatter.rb +26 -0
  37. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +1 -1
  38. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +47 -0
  39. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +4 -0
  40. data/lib/ruby_lsp/requests/support/{syntax_tree_formatting_runner.rb → syntax_tree_formatter.rb} +13 -6
  41. data/lib/ruby_lsp/requests/workspace_symbol.rb +5 -4
  42. data/lib/ruby_lsp/requests.rb +3 -1
  43. data/lib/ruby_lsp/server.rb +763 -142
  44. data/lib/ruby_lsp/setup_bundler.rb +13 -1
  45. data/lib/ruby_lsp/store.rb +3 -15
  46. data/lib/ruby_lsp/test_helper.rb +52 -0
  47. data/lib/ruby_lsp/utils.rb +68 -33
  48. metadata +11 -9
  49. data/lib/ruby_lsp/executor.rb +0 -614
  50. data/lib/ruby_lsp/requests/support/dependency_detector.rb +0 -93
  51. data/lib/ruby_lsp/requests/support/formatter_runner.rb +0 -18
  52. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +0 -34
  53. data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +0 -35
@@ -0,0 +1,169 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ class GlobalState
6
+ extend T::Sig
7
+
8
+ sig { returns(String) }
9
+ attr_reader :test_library
10
+
11
+ sig { returns(String) }
12
+ attr_accessor :formatter
13
+
14
+ sig { returns(T::Boolean) }
15
+ attr_reader :typechecker
16
+
17
+ sig { returns(RubyIndexer::Index) }
18
+ attr_reader :index
19
+
20
+ sig { returns(Encoding) }
21
+ attr_reader :encoding
22
+
23
+ sig { returns(T::Boolean) }
24
+ attr_reader :supports_watching_files
25
+
26
+ sig { void }
27
+ def initialize
28
+ @workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
29
+ @encoding = T.let(Encoding::UTF_8, Encoding)
30
+
31
+ @formatter = T.let("auto", String)
32
+ @test_library = T.let(detect_test_library, String)
33
+ @typechecker = T.let(detect_typechecker, T::Boolean)
34
+ @index = T.let(RubyIndexer::Index.new, RubyIndexer::Index)
35
+ @supported_formatters = T.let({}, T::Hash[String, Requests::Support::Formatter])
36
+ @supports_watching_files = T.let(false, T::Boolean)
37
+ end
38
+
39
+ sig { params(identifier: String, instance: Requests::Support::Formatter).void }
40
+ def register_formatter(identifier, instance)
41
+ @supported_formatters[identifier] = instance
42
+ end
43
+
44
+ sig { returns(T.nilable(Requests::Support::Formatter)) }
45
+ def active_formatter
46
+ @supported_formatters[@formatter]
47
+ end
48
+
49
+ sig { params(options: T::Hash[Symbol, T.untyped]).void }
50
+ def apply_options(options)
51
+ workspace_uri = options.dig(:workspaceFolders, 0, :uri)
52
+ @workspace_uri = URI(workspace_uri) if workspace_uri
53
+
54
+ specified_formatter = options.dig(:initializationOptions, :formatter)
55
+ @formatter = specified_formatter if specified_formatter
56
+ @formatter = detect_formatter if @formatter == "auto"
57
+
58
+ encodings = options.dig(:capabilities, :general, :positionEncodings)
59
+ @encoding = if !encodings || encodings.empty?
60
+ Encoding::UTF_16LE
61
+ elsif encodings.include?(Constant::PositionEncodingKind::UTF8)
62
+ Encoding::UTF_8
63
+ elsif encodings.include?(Constant::PositionEncodingKind::UTF16)
64
+ Encoding::UTF_16LE
65
+ else
66
+ Encoding::UTF_32
67
+ end
68
+
69
+ file_watching_caps = options.dig(:capabilities, :workspace, :didChangeWatchedFiles)
70
+ if file_watching_caps&.dig(:dynamicRegistration) && file_watching_caps&.dig(:relativePatternSupport)
71
+ @supports_watching_files = true
72
+ end
73
+ end
74
+
75
+ sig { returns(String) }
76
+ def workspace_path
77
+ T.must(@workspace_uri.to_standardized_path)
78
+ end
79
+
80
+ sig { returns(String) }
81
+ def encoding_name
82
+ case @encoding
83
+ when Encoding::UTF_8
84
+ Constant::PositionEncodingKind::UTF8
85
+ when Encoding::UTF_16LE
86
+ Constant::PositionEncodingKind::UTF16
87
+ else
88
+ Constant::PositionEncodingKind::UTF32
89
+ end
90
+ end
91
+
92
+ sig { params(gem_pattern: Regexp).returns(T::Boolean) }
93
+ def direct_dependency?(gem_pattern)
94
+ dependencies.any?(gem_pattern)
95
+ end
96
+
97
+ private
98
+
99
+ sig { returns(String) }
100
+ def detect_formatter
101
+ # NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
102
+ if direct_dependency?(/^rubocop/)
103
+ "rubocop"
104
+ elsif direct_dependency?(/^syntax_tree$/)
105
+ "syntax_tree"
106
+ else
107
+ "none"
108
+ end
109
+ end
110
+
111
+ sig { returns(String) }
112
+ def detect_test_library
113
+ if direct_dependency?(/^rspec/)
114
+ "rspec"
115
+ # A Rails app may have a dependency on minitest, but we would instead want to use the Rails test runner provided
116
+ # by ruby-lsp-rails. A Rails app doesn't need to depend on the rails gem itself, individual components like
117
+ # activestorage may be added to the gemfile so that other components aren't downloaded. Check for the presence
118
+ # of bin/rails to support these cases.
119
+ elsif File.exist?(File.join(workspace_path, "bin/rails"))
120
+ "rails"
121
+ # NOTE: Intentionally ends with $ to avoid mis-matching minitest-reporters, etc. in a Rails app.
122
+ elsif direct_dependency?(/^minitest$/)
123
+ "minitest"
124
+ elsif direct_dependency?(/^test-unit/)
125
+ "test-unit"
126
+ else
127
+ "unknown"
128
+ end
129
+ end
130
+
131
+ sig { returns(T::Boolean) }
132
+ def detect_typechecker
133
+ return false if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
134
+
135
+ # We can't read the env from within `Bundle.with_original_env` so we need to set it here.
136
+ ruby_lsp_env_is_test = (ENV["RUBY_LSP_ENV"] == "test")
137
+ Bundler.with_original_env do
138
+ sorbet_static_detected = Bundler.locked_gems.specs.any? { |spec| spec.name == "sorbet-static" }
139
+ # Don't show message while running tests, since it's noisy
140
+ if sorbet_static_detected && !ruby_lsp_env_is_test
141
+ $stderr.puts("Ruby LSP detected this is a Sorbet project so will defer to Sorbet LSP for some functionality")
142
+ end
143
+ sorbet_static_detected
144
+ end
145
+ rescue Bundler::GemfileNotFound
146
+ false
147
+ end
148
+
149
+ sig { returns(T::Array[String]) }
150
+ def dependencies
151
+ @dependencies ||= T.let(
152
+ begin
153
+ Bundler.with_original_env { Bundler.default_gemfile }
154
+ Bundler.locked_gems.dependencies.keys + gemspec_dependencies
155
+ rescue Bundler::GemfileNotFound
156
+ []
157
+ end,
158
+ T.nilable(T::Array[String]),
159
+ )
160
+ end
161
+
162
+ sig { returns(T::Array[String]) }
163
+ def gemspec_dependencies
164
+ Bundler.locked_gems.sources
165
+ .grep(Bundler::Source::Gemspec)
166
+ .flat_map { _1.gemspec&.dependencies&.map(&:name) }
167
+ end
168
+ end
169
+ end
@@ -20,12 +20,13 @@ require "prism/visitor"
20
20
  require "language_server-protocol"
21
21
 
22
22
  require "ruby-lsp"
23
+ require "ruby_lsp/base_server"
23
24
  require "ruby_indexer/ruby_indexer"
24
25
  require "core_ext/uri"
25
26
  require "ruby_lsp/utils"
26
27
  require "ruby_lsp/parameter_scope"
28
+ require "ruby_lsp/global_state"
27
29
  require "ruby_lsp/server"
28
- require "ruby_lsp/executor"
29
30
  require "ruby_lsp/requests"
30
31
  require "ruby_lsp/response_builders"
31
32
  require "ruby_lsp/document"
@@ -33,3 +34,5 @@ require "ruby_lsp/ruby_document"
33
34
  require "ruby_lsp/store"
34
35
  require "ruby_lsp/addon"
35
36
  require "ruby_lsp/requests/support/rubocop_runner"
37
+ require "ruby_lsp/requests/support/rubocop_formatter"
38
+ require "ruby_lsp/requests/support/syntax_tree_formatter"
@@ -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]
@@ -66,17 +68,22 @@ module RubyLsp
66
68
  command: generate_test_command(group_stack: @group_stack),
67
69
  kind: :group,
68
70
  )
69
- end
70
71
 
71
- @group_id_stack.push(@group_id)
72
- @group_id += 1
72
+ @group_id_stack.push(@group_id)
73
+ @group_id += 1
74
+ end
73
75
  end
74
76
 
75
77
  sig { params(node: Prism::ClassNode).void }
76
78
  def on_class_node_leave(node)
77
79
  @visibility_stack.pop
78
80
  @group_stack.pop
79
- @group_id_stack.pop
81
+
82
+ class_name = node.constant_path.slice
83
+
84
+ if @path && class_name.end_with?("Test")
85
+ @group_id_stack.pop
86
+ end
80
87
  end
81
88
 
82
89
  sig { params(node: Prism::DefNode).void }
@@ -156,7 +163,7 @@ module RubyLsp
156
163
  sig { params(node: Prism::Node, name: String, command: String, kind: Symbol).void }
157
164
  def add_test_code_lens(node, name:, command:, kind:)
158
165
  # 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
166
+ return unless SUPPORTED_TEST_LIBRARIES.include?(@global_state.test_library) && @path
160
167
 
161
168
  arguments = [
162
169
  @path,
@@ -208,7 +215,7 @@ module RubyLsp
208
215
  def generate_test_command(group_stack: [], spec_name: nil, method_name: nil)
209
216
  command = BASE_COMMAND + T.must(@path)
210
217
 
211
- case DependencyDetector.instance.detected_test_library
218
+ case @global_state.test_library
212
219
  when "minitest"
213
220
  last_dynamic_reference_index = group_stack.rindex(DYNAMIC_REFERENCE_MARKER)
214
221
  command += if last_dynamic_reference_index
@@ -264,12 +271,14 @@ module RubyLsp
264
271
 
265
272
  return unless name
266
273
 
267
- add_test_code_lens(
268
- node,
269
- name: name,
270
- command: generate_test_command(spec_name: name),
271
- kind: kind,
272
- )
274
+ if @path
275
+ add_test_code_lens(
276
+ node,
277
+ name: name,
278
+ command: generate_test_command(spec_name: name),
279
+ kind: kind,
280
+ )
281
+ end
273
282
  end
274
283
  end
275
284
  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)