ruby-lsp 0.23.11 → 0.26.6

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 (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/VERSION +1 -1
  4. data/exe/ruby-lsp +10 -4
  5. data/exe/ruby-lsp-check +0 -4
  6. data/exe/ruby-lsp-launcher +46 -22
  7. data/exe/ruby-lsp-test-exec +6 -0
  8. data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +1 -2
  9. data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -6
  10. data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +85 -118
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +159 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +130 -253
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +189 -285
  15. data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
  16. data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +23 -27
  17. data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +31 -59
  18. data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +58 -68
  19. data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +17 -19
  20. data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +7 -11
  21. data/lib/ruby_lsp/addon.rb +88 -86
  22. data/lib/ruby_lsp/base_server.rb +79 -65
  23. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  24. data/lib/ruby_lsp/document.rb +205 -104
  25. data/lib/ruby_lsp/erb_document.rb +45 -47
  26. data/lib/ruby_lsp/global_state.rb +134 -86
  27. data/lib/ruby_lsp/internal.rb +8 -3
  28. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  29. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  30. data/lib/ruby_lsp/listeners/definition.rb +78 -72
  31. data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
  32. data/lib/ruby_lsp/listeners/document_link.rb +93 -86
  33. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  34. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  35. data/lib/ruby_lsp/listeners/hover.rb +109 -117
  36. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  37. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  38. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  39. data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
  40. data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
  41. data/lib/ruby_lsp/listeners/test_style.rb +207 -95
  42. data/lib/ruby_lsp/node_context.rb +12 -39
  43. data/lib/ruby_lsp/rbs_document.rb +10 -11
  44. data/lib/ruby_lsp/requests/code_action_resolve.rb +92 -66
  45. data/lib/ruby_lsp/requests/code_actions.rb +34 -31
  46. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  47. data/lib/ruby_lsp/requests/completion.rb +8 -21
  48. data/lib/ruby_lsp/requests/completion_resolve.rb +14 -12
  49. data/lib/ruby_lsp/requests/definition.rb +8 -20
  50. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  51. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  52. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  53. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  54. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  55. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  56. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  57. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
  58. data/lib/ruby_lsp/requests/hover.rb +12 -25
  59. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  60. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  61. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  62. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  63. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  64. data/lib/ruby_lsp/requests/references.rb +17 -57
  65. data/lib/ruby_lsp/requests/rename.rb +27 -51
  66. data/lib/ruby_lsp/requests/request.rb +13 -25
  67. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  68. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  69. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  70. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  71. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  72. data/lib/ruby_lsp/requests/support/common.rb +23 -61
  73. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  74. data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
  75. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  76. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  77. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +34 -36
  78. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  79. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  80. data/lib/ruby_lsp/requests/support/source_uri.rb +22 -33
  81. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  82. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  83. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  84. data/lib/ruby_lsp/requests/workspace_symbol.rb +24 -16
  85. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  86. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  87. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  88. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  89. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  90. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  91. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  92. data/lib/ruby_lsp/ruby_document.rb +32 -98
  93. data/lib/ruby_lsp/scope.rb +7 -11
  94. data/lib/ruby_lsp/scripts/compose_bundle.rb +7 -5
  95. data/lib/ruby_lsp/server.rb +305 -198
  96. data/lib/ruby_lsp/setup_bundler.rb +160 -97
  97. data/lib/ruby_lsp/static_docs.rb +12 -7
  98. data/lib/ruby_lsp/store.rb +21 -49
  99. data/lib/ruby_lsp/test_helper.rb +3 -16
  100. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +241 -0
  101. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  102. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  103. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  104. data/lib/ruby_lsp/utils.rb +138 -93
  105. data/static_docs/break.md +103 -0
  106. metadata +15 -34
  107. data/lib/ruby_indexer/test/class_variables_test.rb +0 -140
  108. data/lib/ruby_indexer/test/classes_and_modules_test.rb +0 -745
  109. data/lib/ruby_indexer/test/configuration_test.rb +0 -239
  110. data/lib/ruby_indexer/test/constant_test.rb +0 -402
  111. data/lib/ruby_indexer/test/enhancements_test.rb +0 -325
  112. data/lib/ruby_indexer/test/global_variable_test.rb +0 -49
  113. data/lib/ruby_indexer/test/index_test.rb +0 -2186
  114. data/lib/ruby_indexer/test/instance_variables_test.rb +0 -240
  115. data/lib/ruby_indexer/test/method_test.rb +0 -947
  116. data/lib/ruby_indexer/test/prefix_tree_test.rb +0 -150
  117. data/lib/ruby_indexer/test/rbs_indexer_test.rb +0 -386
  118. data/lib/ruby_indexer/test/reference_finder_test.rb +0 -330
  119. data/lib/ruby_indexer/test/test_case.rb +0 -51
  120. data/lib/ruby_indexer/test/uri_test.rb +0 -72
  121. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -2,94 +2,115 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
- class GlobalState
6
- extend T::Sig
5
+ # Holds the detected value and the reason for detection
6
+ class DetectionResult
7
+ #: String
8
+ attr_reader :value
9
+
10
+ #: String
11
+ attr_reader :reason
12
+
13
+ #: (String value, String reason) -> void
14
+ def initialize(value, reason)
15
+ @value = value
16
+ @reason = reason
17
+ end
18
+ end
7
19
 
8
- sig { returns(String) }
20
+ class GlobalState
21
+ #: String
9
22
  attr_reader :test_library
10
23
 
11
- sig { returns(String) }
24
+ #: String
12
25
  attr_accessor :formatter
13
26
 
14
- sig { returns(T::Boolean) }
27
+ #: bool
15
28
  attr_reader :has_type_checker
16
29
 
17
- sig { returns(RubyIndexer::Index) }
30
+ #: RubyIndexer::Index
18
31
  attr_reader :index
19
32
 
20
- sig { returns(Encoding) }
33
+ #: Encoding
21
34
  attr_reader :encoding
22
35
 
23
- sig { returns(T::Boolean) }
36
+ #: bool
24
37
  attr_reader :top_level_bundle
25
38
 
26
- sig { returns(TypeInferrer) }
39
+ #: TypeInferrer
27
40
  attr_reader :type_inferrer
28
41
 
29
- sig { returns(ClientCapabilities) }
42
+ #: ClientCapabilities
30
43
  attr_reader :client_capabilities
31
44
 
32
- sig { returns(URI::Generic) }
45
+ #: URI::Generic
33
46
  attr_reader :workspace_uri
34
47
 
35
- sig { returns(T.nilable(String)) }
48
+ #: String?
36
49
  attr_reader :telemetry_machine_id
37
50
 
38
- sig { void }
51
+ #: -> void
39
52
  def initialize
40
- @workspace_uri = T.let(URI::Generic.from_path(path: Dir.pwd), URI::Generic)
41
- @encoding = T.let(Encoding::UTF_8, Encoding)
42
-
43
- @formatter = T.let("auto", String)
44
- @linters = T.let([], T::Array[String])
45
- @test_library = T.let("minitest", String)
46
- @has_type_checker = T.let(true, T::Boolean)
47
- @index = T.let(RubyIndexer::Index.new, RubyIndexer::Index)
48
- @supported_formatters = T.let({}, T::Hash[String, Requests::Support::Formatter])
49
- @type_inferrer = T.let(TypeInferrer.new(@index), TypeInferrer)
50
- @addon_settings = T.let({}, T::Hash[String, T.untyped])
51
- @top_level_bundle = T.let(
52
- begin
53
- Bundler.with_original_env { Bundler.default_gemfile }
54
- true
55
- rescue Bundler::GemfileNotFound, Bundler::GitError
56
- false
57
- end,
58
- T::Boolean,
59
- )
60
- @client_capabilities = T.let(ClientCapabilities.new, ClientCapabilities)
61
- @enabled_feature_flags = T.let({}, T::Hash[Symbol, T::Boolean])
62
- @mutex = T.let(Mutex.new, Mutex)
63
- @telemetry_machine_id = T.let(nil, T.nilable(String))
53
+ @workspace_uri = URI::Generic.from_path(path: Dir.pwd) #: URI::Generic
54
+ @encoding = Encoding::UTF_8 #: Encoding
55
+
56
+ @formatter = "auto" #: String
57
+ @linters = [] #: Array[String]
58
+ @test_library = "minitest" #: String
59
+ @has_type_checker = true #: bool
60
+ @index = RubyIndexer::Index.new #: RubyIndexer::Index
61
+ @supported_formatters = {} #: Hash[String, Requests::Support::Formatter]
62
+ @type_inferrer = TypeInferrer.new(@index) #: TypeInferrer
63
+ @addon_settings = {} #: Hash[String, untyped]
64
+ @top_level_bundle = begin
65
+ Bundler.with_original_env { Bundler.default_gemfile }
66
+ true
67
+ rescue Bundler::GemfileNotFound, Bundler::GitError
68
+ false
69
+ end #: bool
70
+ @client_capabilities = ClientCapabilities.new #: ClientCapabilities
71
+ @enabled_feature_flags = {} #: Hash[Symbol, bool]
72
+ @mutex = Mutex.new #: Mutex
73
+ @telemetry_machine_id = nil #: String?
74
+ @feature_configuration = {
75
+ inlayHint: RequestConfig.new({
76
+ enableAll: false,
77
+ implicitRescue: false,
78
+ implicitHashValue: false,
79
+ }),
80
+ codeLens: RequestConfig.new({
81
+ enableAll: false,
82
+ enableTestCodeLens: true,
83
+ }),
84
+ } #: Hash[Symbol, RequestConfig]
64
85
  end
65
86
 
66
- sig { type_parameters(:T).params(block: T.proc.returns(T.type_parameter(:T))).returns(T.type_parameter(:T)) }
87
+ #: [T] { -> T } -> T
67
88
  def synchronize(&block)
68
89
  @mutex.synchronize(&block)
69
90
  end
70
91
 
71
- sig { params(addon_name: String).returns(T.nilable(T::Hash[Symbol, T.untyped])) }
92
+ #: (String addon_name) -> Hash[Symbol, untyped]?
72
93
  def settings_for_addon(addon_name)
73
94
  @addon_settings[addon_name]
74
95
  end
75
96
 
76
- sig { params(identifier: String, instance: Requests::Support::Formatter).void }
97
+ #: (String identifier, Requests::Support::Formatter instance) -> void
77
98
  def register_formatter(identifier, instance)
78
99
  @supported_formatters[identifier] = instance
79
100
  end
80
101
 
81
- sig { returns(T.nilable(Requests::Support::Formatter)) }
102
+ #: -> Requests::Support::Formatter?
82
103
  def active_formatter
83
104
  @supported_formatters[@formatter]
84
105
  end
85
106
 
86
- sig { returns(T::Array[Requests::Support::Formatter]) }
107
+ #: -> Array[Requests::Support::Formatter]
87
108
  def active_linters
88
109
  @linters.filter_map { |name| @supported_formatters[name] }
89
110
  end
90
111
 
91
112
  # Applies the options provided by the editor and returns an array of notifications to send back to the client
92
- sig { params(options: T::Hash[Symbol, T.untyped]).returns(T::Array[Notification]) }
113
+ #: (Hash[Symbol, untyped] options) -> Array[Notification]
93
114
  def apply_options(options)
94
115
  notifications = []
95
116
  direct_dependencies = gather_direct_dependencies
@@ -116,8 +137,11 @@ module RubyLsp
116
137
  end
117
138
 
118
139
  if @formatter == "auto"
119
- @formatter = detect_formatter(direct_dependencies, all_dependencies)
120
- notifications << Notification.window_log_message("Auto detected formatter: #{@formatter}")
140
+ formatter_result = detect_formatter(direct_dependencies, all_dependencies)
141
+ @formatter = formatter_result.value
142
+ notifications << Notification.window_log_message(
143
+ "Auto detected formatter: #{@formatter} (#{formatter_result.reason})",
144
+ )
121
145
  end
122
146
 
123
147
  specified_linters = options.dig(:initializationOptions, :linters)
@@ -138,21 +162,28 @@ module RubyLsp
138
162
  specified_linters << "rubocop_internal"
139
163
  end
140
164
 
141
- @linters = specified_linters || detect_linters(direct_dependencies, all_dependencies)
142
-
143
- notifications << if specified_linters
144
- Notification.window_log_message("Using linters specified by user: #{@linters.join(", ")}")
165
+ if specified_linters
166
+ @linters = specified_linters
167
+ notifications << Notification.window_log_message("Using linters specified by user: #{@linters.join(", ")}")
145
168
  else
146
- Notification.window_log_message("Auto detected linters: #{@linters.join(", ")}")
169
+ linter_results = detect_linters(direct_dependencies, all_dependencies)
170
+ @linters = linter_results.map(&:value)
171
+ linter_messages = linter_results.map { |r| "#{r.value} (#{r.reason})" }
172
+ notifications << Notification.window_log_message("Auto detected linters: #{linter_messages.join(", ")}")
147
173
  end
148
174
 
149
- @test_library = detect_test_library(direct_dependencies)
150
- notifications << Notification.window_log_message("Detected test library: #{@test_library}")
175
+ test_library_result = detect_test_library(direct_dependencies)
176
+ @test_library = test_library_result.value
177
+ notifications << Notification.window_log_message(
178
+ "Detected test library: #{@test_library} (#{test_library_result.reason})",
179
+ )
151
180
 
152
- @has_type_checker = detect_typechecker(all_dependencies)
153
- if @has_type_checker
181
+ typechecker_result = detect_typechecker(all_dependencies)
182
+ @has_type_checker = !typechecker_result.nil?
183
+ if typechecker_result
154
184
  notifications << Notification.window_log_message(
155
- "Ruby LSP detected this is a Sorbet project and will defer to the Sorbet LSP for some functionality",
185
+ "Ruby LSP detected this is a Sorbet project (#{typechecker_result.reason}) and will defer to the " \
186
+ "Sorbet LSP for some functionality",
156
187
  )
157
188
  end
158
189
 
@@ -180,20 +211,30 @@ module RubyLsp
180
211
  @enabled_feature_flags = enabled_flags if enabled_flags
181
212
 
182
213
  @telemetry_machine_id = options.dig(:initializationOptions, :telemetryMachineId)
214
+
215
+ options.dig(:initializationOptions, :featuresConfiguration)&.each do |feature_name, config|
216
+ @feature_configuration[feature_name]&.merge!(config)
217
+ end
218
+
183
219
  notifications
184
220
  end
185
221
 
186
- sig { params(flag: Symbol).returns(T.nilable(T::Boolean)) }
222
+ #: (Symbol) -> RequestConfig?
223
+ def feature_configuration(feature_name)
224
+ @feature_configuration[feature_name]
225
+ end
226
+
227
+ #: (Symbol flag) -> bool?
187
228
  def enabled_feature?(flag)
188
229
  @enabled_feature_flags[:all] || @enabled_feature_flags[flag]
189
230
  end
190
231
 
191
- sig { returns(String) }
232
+ #: -> String
192
233
  def workspace_path
193
- T.must(@workspace_uri.to_standardized_path)
234
+ @workspace_uri.to_standardized_path #: as !nil
194
235
  end
195
236
 
196
- sig { returns(String) }
237
+ #: -> String
197
238
  def encoding_name
198
239
  case @encoding
199
240
  when Encoding::UTF_8
@@ -205,80 +246,87 @@ module RubyLsp
205
246
  end
206
247
  end
207
248
 
208
- sig { returns(T::Boolean) }
249
+ #: -> bool
209
250
  def supports_watching_files
210
251
  @client_capabilities.supports_watching_files
211
252
  end
212
253
 
213
254
  private
214
255
 
215
- sig { params(direct_dependencies: T::Array[String], all_dependencies: T::Array[String]).returns(String) }
256
+ #: (Array[String] direct_dependencies, Array[String] all_dependencies) -> DetectionResult
216
257
  def detect_formatter(direct_dependencies, all_dependencies)
217
258
  # NOTE: Intentionally no $ at end, since we want to match rubocop-shopify, etc.
218
- return "rubocop_internal" if direct_dependencies.any?(/^rubocop/)
259
+ if direct_dependencies.any?(/^rubocop/)
260
+ return DetectionResult.new("rubocop_internal", "direct dependency matching /^rubocop/")
261
+ end
219
262
 
220
- syntax_tree_is_direct_dependency = direct_dependencies.include?("syntax_tree")
221
- return "syntax_tree" if syntax_tree_is_direct_dependency
263
+ if direct_dependencies.include?("syntax_tree")
264
+ return DetectionResult.new("syntax_tree", "direct dependency")
265
+ end
222
266
 
223
- rubocop_is_transitive_dependency = all_dependencies.include?("rubocop")
224
- return "rubocop_internal" if dot_rubocop_yml_present && rubocop_is_transitive_dependency
267
+ if all_dependencies.include?("rubocop") && dot_rubocop_yml_present
268
+ return DetectionResult.new("rubocop_internal", "transitive dependency with .rubocop.yml present")
269
+ end
225
270
 
226
- "none"
271
+ DetectionResult.new("none", "no formatter detected")
227
272
  end
228
273
 
229
274
  # Try to detect if there are linters in the project's dependencies. For auto-detection, we always only consider a
230
275
  # single linter. To have multiple linters running, the user must configure them manually
231
- sig { params(dependencies: T::Array[String], all_dependencies: T::Array[String]).returns(T::Array[String]) }
276
+ #: (Array[String] dependencies, Array[String] all_dependencies) -> Array[DetectionResult]
232
277
  def detect_linters(dependencies, all_dependencies)
233
- linters = []
278
+ linters = [] #: Array[DetectionResult]
234
279
 
235
- if dependencies.any?(/^rubocop/) || (all_dependencies.include?("rubocop") && dot_rubocop_yml_present)
236
- linters << "rubocop_internal"
280
+ if dependencies.any?(/^rubocop/)
281
+ linters << DetectionResult.new("rubocop_internal", "direct dependency matching /^rubocop/")
282
+ elsif all_dependencies.include?("rubocop") && dot_rubocop_yml_present
283
+ linters << DetectionResult.new("rubocop_internal", "transitive dependency with .rubocop.yml present")
237
284
  end
238
285
 
239
286
  linters
240
287
  end
241
288
 
242
- sig { params(dependencies: T::Array[String]).returns(String) }
289
+ #: (Array[String] dependencies) -> DetectionResult
243
290
  def detect_test_library(dependencies)
244
291
  if dependencies.any?(/^rspec/)
245
- "rspec"
292
+ DetectionResult.new("rspec", "direct dependency matching /^rspec/")
246
293
  # A Rails app may have a dependency on minitest, but we would instead want to use the Rails test runner provided
247
294
  # by ruby-lsp-rails. A Rails app doesn't need to depend on the rails gem itself, individual components like
248
295
  # activestorage may be added to the gemfile so that other components aren't downloaded. Check for the presence
249
296
  # of bin/rails to support these cases.
250
297
  elsif bin_rails_present
251
- "rails"
298
+ DetectionResult.new("rails", "bin/rails present")
252
299
  # NOTE: Intentionally ends with $ to avoid mis-matching minitest-reporters, etc. in a Rails app.
253
300
  elsif dependencies.any?(/^minitest$/)
254
- "minitest"
301
+ DetectionResult.new("minitest", "direct dependency matching /^minitest$/")
255
302
  elsif dependencies.any?(/^test-unit/)
256
- "test-unit"
303
+ DetectionResult.new("test-unit", "direct dependency matching /^test-unit/")
257
304
  else
258
- "unknown"
305
+ DetectionResult.new("unknown", "no test library detected")
259
306
  end
260
307
  end
261
308
 
262
- sig { params(dependencies: T::Array[String]).returns(T::Boolean) }
309
+ #: (Array[String] dependencies) -> DetectionResult?
263
310
  def detect_typechecker(dependencies)
264
- return false if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
311
+ return if ENV["RUBY_LSP_BYPASS_TYPECHECKER"]
312
+ return if dependencies.none?(/^sorbet-static/)
265
313
 
266
- dependencies.any?(/^sorbet-static/)
314
+ DetectionResult.new("sorbet", "sorbet-static in dependencies")
267
315
  rescue Bundler::GemfileNotFound
268
- false
316
+ nil
269
317
  end
270
318
 
271
- sig { returns(T::Boolean) }
319
+ #: -> bool
272
320
  def bin_rails_present
273
321
  File.exist?(File.join(workspace_path, "bin/rails"))
274
322
  end
275
323
 
276
- sig { returns(T::Boolean) }
324
+ #: -> bool
277
325
  def dot_rubocop_yml_present
278
326
  File.exist?(File.join(workspace_path, ".rubocop.yml"))
279
327
  end
280
328
 
281
- sig { returns(T::Array[String]) }
329
+ #: -> Array[String]
282
330
  def gather_direct_dependencies
283
331
  Bundler.with_original_env { Bundler.default_gemfile }
284
332
 
@@ -288,14 +336,14 @@ module RubyLsp
288
336
  []
289
337
  end
290
338
 
291
- sig { returns(T::Array[String]) }
339
+ #: -> Array[String]
292
340
  def gemspec_dependencies
293
341
  (Bundler.locked_gems&.sources || [])
294
342
  .grep(Bundler::Source::Gemspec)
295
343
  .flat_map { _1.gemspec&.dependencies&.map(&:name) }
296
344
  end
297
345
 
298
- sig { returns(T::Array[String]) }
346
+ #: -> Array[String]
299
347
  def gather_direct_and_indirect_dependencies
300
348
  Bundler.with_original_env { Bundler.default_gemfile }
301
349
  Bundler.locked_gems&.specs&.map(&:name) || []
@@ -6,15 +6,18 @@
6
6
  yarp_require_paths = Gem.loaded_specs["yarp"]&.full_require_paths
7
7
  $LOAD_PATH.delete_if { |path| yarp_require_paths.include?(path) } if yarp_require_paths
8
8
 
9
- require "sorbet-runtime"
10
-
11
9
  # Set Bundler's UI level to silent as soon as possible to prevent any prints to STDOUT
12
10
  require "bundler"
13
11
  Bundler.ui.level = :silent
14
12
 
15
13
  require "json"
16
14
  require "uri"
17
- require "cgi"
15
+ require "cgi/escape"
16
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.5")
17
+ # Just requiring `cgi/escape` leaves CGI.unescape broken on older rubies
18
+ # Some background on why this is necessary: https://bugs.ruby-lang.org/issues/21258
19
+ require "cgi/util"
20
+ end
18
21
  require "set"
19
22
  require "strscan"
20
23
  require "prism"
@@ -25,6 +28,7 @@ require "fileutils"
25
28
  require "open3"
26
29
  require "securerandom"
27
30
  require "shellwords"
31
+ require "set"
28
32
 
29
33
  require "ruby-lsp"
30
34
  require "ruby_lsp/base_server"
@@ -79,6 +83,7 @@ require "ruby_lsp/requests/document_link"
79
83
  require "ruby_lsp/requests/document_symbol"
80
84
  require "ruby_lsp/requests/folding_ranges"
81
85
  require "ruby_lsp/requests/formatting"
86
+ require "ruby_lsp/requests/go_to_relevant_file"
82
87
  require "ruby_lsp/requests/hover"
83
88
  require "ruby_lsp/requests/inlay_hints"
84
89
  require "ruby_lsp/requests/on_type_formatting"