ruby-lsp 0.14.6 → 0.16.4

Sign up to get free protection for your applications and to get access to all the features.
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)