ruby-lsp 0.23.11 → 0.26.2

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 (119) 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 +45 -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 +82 -116
  11. data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +140 -183
  12. data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +10 -14
  13. data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +107 -236
  14. data/lib/ruby_indexer/lib/ruby_indexer/index.rb +183 -284
  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 +25 -57
  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_indexer/test/class_variables_test.rb +14 -14
  22. data/lib/ruby_indexer/test/classes_and_modules_test.rb +65 -40
  23. data/lib/ruby_indexer/test/configuration_test.rb +49 -9
  24. data/lib/ruby_indexer/test/constant_test.rb +34 -34
  25. data/lib/ruby_indexer/test/enhancements_test.rb +1 -1
  26. data/lib/ruby_indexer/test/index_test.rb +225 -135
  27. data/lib/ruby_indexer/test/instance_variables_test.rb +61 -37
  28. data/lib/ruby_indexer/test/method_test.rb +166 -123
  29. data/lib/ruby_indexer/test/prefix_tree_test.rb +21 -21
  30. data/lib/ruby_indexer/test/rbs_indexer_test.rb +70 -75
  31. data/lib/ruby_indexer/test/reference_finder_test.rb +79 -14
  32. data/lib/ruby_indexer/test/test_case.rb +9 -3
  33. data/lib/ruby_indexer/test/uri_test.rb +15 -2
  34. data/lib/ruby_lsp/addon.rb +88 -86
  35. data/lib/ruby_lsp/base_server.rb +59 -54
  36. data/lib/ruby_lsp/client_capabilities.rb +16 -13
  37. data/lib/ruby_lsp/document.rb +205 -104
  38. data/lib/ruby_lsp/erb_document.rb +45 -47
  39. data/lib/ruby_lsp/global_state.rb +73 -57
  40. data/lib/ruby_lsp/internal.rb +8 -3
  41. data/lib/ruby_lsp/listeners/code_lens.rb +82 -89
  42. data/lib/ruby_lsp/listeners/completion.rb +81 -76
  43. data/lib/ruby_lsp/listeners/definition.rb +44 -58
  44. data/lib/ruby_lsp/listeners/document_highlight.rb +149 -151
  45. data/lib/ruby_lsp/listeners/document_link.rb +50 -70
  46. data/lib/ruby_lsp/listeners/document_symbol.rb +38 -52
  47. data/lib/ruby_lsp/listeners/folding_ranges.rb +40 -43
  48. data/lib/ruby_lsp/listeners/hover.rb +107 -115
  49. data/lib/ruby_lsp/listeners/inlay_hints.rb +8 -13
  50. data/lib/ruby_lsp/listeners/semantic_highlighting.rb +54 -56
  51. data/lib/ruby_lsp/listeners/signature_help.rb +12 -27
  52. data/lib/ruby_lsp/listeners/spec_style.rb +231 -0
  53. data/lib/ruby_lsp/listeners/test_discovery.rb +107 -0
  54. data/lib/ruby_lsp/listeners/test_style.rb +207 -95
  55. data/lib/ruby_lsp/node_context.rb +12 -39
  56. data/lib/ruby_lsp/rbs_document.rb +10 -11
  57. data/lib/ruby_lsp/requests/code_action_resolve.rb +65 -61
  58. data/lib/ruby_lsp/requests/code_actions.rb +14 -26
  59. data/lib/ruby_lsp/requests/code_lens.rb +31 -21
  60. data/lib/ruby_lsp/requests/completion.rb +8 -21
  61. data/lib/ruby_lsp/requests/completion_resolve.rb +6 -6
  62. data/lib/ruby_lsp/requests/definition.rb +8 -20
  63. data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
  64. data/lib/ruby_lsp/requests/discover_tests.rb +20 -7
  65. data/lib/ruby_lsp/requests/document_highlight.rb +6 -16
  66. data/lib/ruby_lsp/requests/document_link.rb +6 -17
  67. data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
  68. data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
  69. data/lib/ruby_lsp/requests/formatting.rb +6 -9
  70. data/lib/ruby_lsp/requests/go_to_relevant_file.rb +139 -0
  71. data/lib/ruby_lsp/requests/hover.rb +12 -25
  72. data/lib/ruby_lsp/requests/inlay_hints.rb +8 -19
  73. data/lib/ruby_lsp/requests/on_type_formatting.rb +32 -40
  74. data/lib/ruby_lsp/requests/prepare_rename.rb +5 -10
  75. data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +5 -15
  76. data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
  77. data/lib/ruby_lsp/requests/references.rb +17 -57
  78. data/lib/ruby_lsp/requests/rename.rb +27 -51
  79. data/lib/ruby_lsp/requests/request.rb +13 -25
  80. data/lib/ruby_lsp/requests/selection_ranges.rb +7 -7
  81. data/lib/ruby_lsp/requests/semantic_highlighting.rb +16 -35
  82. data/lib/ruby_lsp/requests/show_syntax_tree.rb +7 -8
  83. data/lib/ruby_lsp/requests/signature_help.rb +9 -27
  84. data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
  85. data/lib/ruby_lsp/requests/support/common.rb +23 -61
  86. data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
  87. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
  88. data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +13 -16
  89. data/lib/ruby_lsp/requests/support/rubocop_runner.rb +38 -36
  90. data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
  91. data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
  92. data/lib/ruby_lsp/requests/support/source_uri.rb +20 -32
  93. data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
  94. data/lib/ruby_lsp/requests/support/test_item.rb +16 -14
  95. data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
  96. data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
  97. data/lib/ruby_lsp/response_builders/collection_response_builder.rb +6 -9
  98. data/lib/ruby_lsp/response_builders/document_symbol.rb +15 -21
  99. data/lib/ruby_lsp/response_builders/hover.rb +12 -18
  100. data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
  101. data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +62 -91
  102. data/lib/ruby_lsp/response_builders/signature_help.rb +6 -8
  103. data/lib/ruby_lsp/response_builders/test_collection.rb +35 -13
  104. data/lib/ruby_lsp/ruby_document.rb +32 -98
  105. data/lib/ruby_lsp/scope.rb +7 -11
  106. data/lib/ruby_lsp/scripts/compose_bundle.rb +6 -4
  107. data/lib/ruby_lsp/server.rb +305 -198
  108. data/lib/ruby_lsp/setup_bundler.rb +122 -82
  109. data/lib/ruby_lsp/static_docs.rb +12 -7
  110. data/lib/ruby_lsp/store.rb +21 -49
  111. data/lib/ruby_lsp/test_helper.rb +3 -16
  112. data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +233 -0
  113. data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +145 -0
  114. data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +92 -0
  115. data/lib/ruby_lsp/type_inferrer.rb +13 -14
  116. data/lib/ruby_lsp/utils.rb +138 -93
  117. data/static_docs/break.md +103 -0
  118. metadata +14 -20
  119. data/lib/ruby_lsp/load_sorbet.rb +0 -62
@@ -2,12 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
+ #: [ParseResultType = Prism::ParseLexResult]
5
6
  class RubyDocument < Document
6
- extend T::Sig
7
- extend T::Generic
8
-
9
- ParseResultType = type_member { { fixed: Prism::ParseResult } }
10
-
11
7
  METHODS_THAT_CHANGE_DECLARATIONS = [
12
8
  :private_constant,
13
9
  :attr_reader,
@@ -24,49 +20,16 @@ module RubyLsp
24
20
  :private_class_method,
25
21
  ].freeze
26
22
 
27
- class SorbetLevel < T::Enum
28
- enums do
29
- None = new("none")
30
- Ignore = new("ignore")
31
- False = new("false")
32
- True = new("true")
33
- Strict = new("strict")
34
- end
35
- end
36
-
37
23
  class << self
38
- extend T::Sig
39
-
40
- sig do
41
- params(
42
- node: Prism::Node,
43
- char_position: Integer,
44
- code_units_cache: T.any(
45
- T.proc.params(arg0: Integer).returns(Integer),
46
- Prism::CodeUnitsCache,
47
- ),
48
- node_types: T::Array[T.class_of(Prism::Node)],
49
- ).returns(NodeContext)
50
- end
24
+ #: (Prism::Node node, Integer char_position, code_units_cache: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache), ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
51
25
  def locate(node, char_position, code_units_cache:, node_types: [])
52
- queue = T.let(node.child_nodes.compact, T::Array[T.nilable(Prism::Node)])
26
+ queue = node.child_nodes.compact #: Array[Prism::Node?]
53
27
  closest = node
54
- parent = T.let(nil, T.nilable(Prism::Node))
55
- nesting_nodes = T.let(
56
- [],
57
- T::Array[T.any(
58
- Prism::ClassNode,
59
- Prism::ModuleNode,
60
- Prism::SingletonClassNode,
61
- Prism::DefNode,
62
- Prism::BlockNode,
63
- Prism::LambdaNode,
64
- Prism::ProgramNode,
65
- )],
66
- )
28
+ parent = nil #: Prism::Node?
29
+ nesting_nodes = [] #: Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)]
67
30
 
68
31
  nesting_nodes << node if node.is_a?(Prism::ProgramNode)
69
- call_node = T.let(nil, T.nilable(Prism::CallNode))
32
+ call_node = nil #: Prism::CallNode?
70
33
 
71
34
  until queue.empty?
72
35
  candidate = queue.shift
@@ -77,7 +40,7 @@ module RubyLsp
77
40
  # Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
78
41
  # same order as the visiting mechanism, which means searching the child nodes before moving on to the next
79
42
  # sibling
80
- T.unsafe(queue).unshift(*candidate.child_nodes)
43
+ queue.unshift(*candidate.child_nodes)
81
44
 
82
45
  # Skip if the current node doesn't cover the desired position
83
46
  loc = candidate.location
@@ -150,74 +113,50 @@ module RubyLsp
150
113
  end
151
114
  end
152
115
 
153
- sig do
154
- returns(T.any(
155
- T.proc.params(arg0: Integer).returns(Integer),
156
- Prism::CodeUnitsCache,
157
- ))
158
- end
116
+ #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
159
117
  attr_reader :code_units_cache
160
118
 
161
- sig { params(source: String, version: Integer, uri: URI::Generic, global_state: GlobalState).void }
119
+ #: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
162
120
  def initialize(source:, version:, uri:, global_state:)
163
121
  super
164
- @code_units_cache = T.let(@parse_result.code_units_cache(@encoding), T.any(
165
- T.proc.params(arg0: Integer).returns(Integer),
166
- Prism::CodeUnitsCache,
167
- ))
122
+ @code_units_cache = @parse_result
123
+ .code_units_cache(@encoding) #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
168
124
  end
169
125
 
170
- sig { override.returns(T::Boolean) }
126
+ # @override
127
+ #: -> bool
171
128
  def parse!
172
129
  return false unless @needs_parsing
173
130
 
174
131
  @needs_parsing = false
175
- @parse_result = Prism.parse(@source)
132
+ @parse_result = Prism.parse_lex(@source)
176
133
  @code_units_cache = @parse_result.code_units_cache(@encoding)
177
134
  true
178
135
  end
179
136
 
180
- sig { override.returns(T::Boolean) }
137
+ #: -> Prism::ProgramNode
138
+ def ast
139
+ @parse_result.value.first
140
+ end
141
+
142
+ # @override
143
+ #: -> bool
181
144
  def syntax_error?
182
145
  @parse_result.failure?
183
146
  end
184
147
 
185
- sig { override.returns(LanguageId) }
148
+ # @override
149
+ #: -> Symbol
186
150
  def language_id
187
- LanguageId::Ruby
151
+ :ruby
188
152
  end
189
153
 
190
- sig { returns(SorbetLevel) }
191
- def sorbet_level
192
- sigil = parse_result.magic_comments.find do |comment|
193
- comment.key == "typed"
194
- end&.value
195
-
196
- case sigil
197
- when "ignore"
198
- SorbetLevel::Ignore
199
- when "false"
200
- SorbetLevel::False
201
- when "true"
202
- SorbetLevel::True
203
- when "strict", "strong"
204
- SorbetLevel::Strict
205
- else
206
- SorbetLevel::None
207
- end
208
- end
209
-
210
- sig do
211
- params(
212
- range: T::Hash[Symbol, T.untyped],
213
- node_types: T::Array[T.class_of(Prism::Node)],
214
- ).returns(T.nilable(Prism::Node))
215
- end
154
+ #: (Hash[Symbol, untyped] range, ?node_types: Array[singleton(Prism::Node)]) -> Prism::Node?
216
155
  def locate_first_within_range(range, node_types: [])
217
156
  start_position, end_position = find_index_by_position(range[:start], range[:end])
218
157
 
219
158
  desired_range = (start_position...end_position)
220
- queue = T.let(@parse_result.value.child_nodes.compact, T::Array[T.nilable(Prism::Node)])
159
+ queue = ast.child_nodes.compact #: Array[Prism::Node?]
221
160
 
222
161
  until queue.empty?
223
162
  candidate = queue.shift
@@ -228,7 +167,7 @@ module RubyLsp
228
167
  # Add the next child_nodes to the queue to be processed. The order here is important! We want to move in the
229
168
  # same order as the visiting mechanism, which means searching the child nodes before moving on to the next
230
169
  # sibling
231
- T.unsafe(queue).unshift(*candidate.child_nodes)
170
+ queue.unshift(*candidate.child_nodes)
232
171
 
233
172
  # Skip if the current node doesn't cover the desired position
234
173
  loc = candidate.location
@@ -240,24 +179,19 @@ module RubyLsp
240
179
  end
241
180
  end
242
181
 
243
- sig do
244
- params(
245
- position: T::Hash[Symbol, T.untyped],
246
- node_types: T::Array[T.class_of(Prism::Node)],
247
- ).returns(NodeContext)
248
- end
182
+ #: (Hash[Symbol, untyped] position, ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
249
183
  def locate_node(position, node_types: [])
250
184
  char_position, _ = find_index_by_position(position)
251
185
 
252
186
  RubyDocument.locate(
253
- @parse_result.value,
187
+ ast,
254
188
  char_position,
255
189
  code_units_cache: @code_units_cache,
256
190
  node_types: node_types,
257
191
  )
258
192
  end
259
193
 
260
- sig { returns(T::Boolean) }
194
+ #: -> bool
261
195
  def should_index?
262
196
  # This method controls when we should index documents. If there's no recent edit and the document has just been
263
197
  # opened, we need to index it
@@ -268,7 +202,7 @@ module RubyLsp
268
202
 
269
203
  private
270
204
 
271
- sig { returns(T::Boolean) }
205
+ #: -> bool
272
206
  def last_edit_may_change_declarations?
273
207
  case @last_edit
274
208
  when Delete
@@ -282,7 +216,7 @@ module RubyLsp
282
216
  end
283
217
  end
284
218
 
285
- sig { params(position: T::Hash[Symbol, Integer]).returns(T::Boolean) }
219
+ #: (Hash[Symbol, Integer] position) -> bool
286
220
  def position_may_impact_declarations?(position)
287
221
  node_context = locate_node(position)
288
222
  node_at_edit = node_context.node
@@ -3,26 +3,24 @@
3
3
 
4
4
  module RubyLsp
5
5
  class Scope
6
- extend T::Sig
7
-
8
- sig { returns(T.nilable(Scope)) }
6
+ #: Scope?
9
7
  attr_reader :parent
10
8
 
11
- sig { params(parent: T.nilable(Scope)).void }
9
+ #: (?Scope? parent) -> void
12
10
  def initialize(parent = nil)
13
11
  @parent = parent
14
12
 
15
13
  # A hash of name => type
16
- @locals = T.let({}, T::Hash[Symbol, Local])
14
+ @locals = {} #: Hash[Symbol, Local]
17
15
  end
18
16
 
19
17
  # Add a new local to this scope. The types should only be `:parameter` or `:variable`
20
- sig { params(name: T.any(String, Symbol), type: Symbol).void }
18
+ #: ((String | Symbol) name, Symbol type) -> void
21
19
  def add(name, type)
22
20
  @locals[name.to_sym] = Local.new(type)
23
21
  end
24
22
 
25
- sig { params(name: T.any(String, Symbol)).returns(T.nilable(Local)) }
23
+ #: ((String | Symbol) name) -> Local?
26
24
  def lookup(name)
27
25
  sym = name.to_sym
28
26
  entry = @locals[sym]
@@ -33,12 +31,10 @@ module RubyLsp
33
31
  end
34
32
 
35
33
  class Local
36
- extend T::Sig
37
-
38
- sig { returns(Symbol) }
34
+ #: Symbol
39
35
  attr_reader :type
40
36
 
41
- sig { params(type: Symbol).void }
37
+ #: (Symbol type) -> void
42
38
  def initialize(type)
43
39
  @type = type
44
40
  end
@@ -13,8 +13,10 @@ def compose(raw_initialize)
13
13
  workspace_path ||= Dir.pwd
14
14
 
15
15
  env = RubyLsp::SetupBundler.new(workspace_path, launcher: true).setup!
16
- File.write(
17
- File.join(".ruby-lsp", "bundle_env"),
18
- env.map { |k, v| "#{k}=#{v}" }.join("\n"),
19
- )
16
+
17
+ File.open(File.join(".ruby-lsp", "bundle_env"), "w") do |f|
18
+ f.flock(File::LOCK_EX)
19
+ f.write(env.map { |k, v| "#{k}=#{v}" }.join("\n"))
20
+ f.flush
21
+ end
20
22
  end