ruby-lsp 0.27.0.beta1 → 0.27.0.beta2

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.
@@ -1,335 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module RubyIndexer
5
- class ReferenceFinder
6
- # @abstract
7
- class Target; end
8
-
9
- class ConstTarget < Target
10
- #: String
11
- attr_reader :fully_qualified_name
12
-
13
- #: (String fully_qualified_name) -> void
14
- def initialize(fully_qualified_name)
15
- super()
16
- @fully_qualified_name = fully_qualified_name
17
- end
18
- end
19
-
20
- class MethodTarget < Target
21
- #: String
22
- attr_reader :method_name
23
-
24
- #: (String method_name) -> void
25
- def initialize(method_name)
26
- super()
27
- @method_name = method_name
28
- end
29
- end
30
-
31
- class InstanceVariableTarget < Target
32
- #: String
33
- attr_reader :name
34
-
35
- #: Array[String]
36
- attr_reader :owner_ancestors
37
-
38
- #: (String name, Array[String] owner_ancestors) -> void
39
- def initialize(name, owner_ancestors)
40
- super()
41
- @name = name
42
- @owner_ancestors = owner_ancestors
43
- end
44
- end
45
-
46
- class Reference
47
- #: String
48
- attr_reader :name
49
-
50
- #: Prism::Location
51
- attr_reader :location
52
-
53
- #: bool
54
- attr_reader :declaration
55
-
56
- #: (String name, Prism::Location location, declaration: bool) -> void
57
- def initialize(name, location, declaration:)
58
- @name = name
59
- @location = location
60
- @declaration = declaration
61
- end
62
- end
63
-
64
- #: (Target target, RubyIndexer::Index index, Prism::Dispatcher dispatcher, URI::Generic uri, ?include_declarations: bool) -> void
65
- def initialize(target, index, dispatcher, uri, include_declarations: true)
66
- @target = target
67
- @index = index
68
- @uri = uri
69
- @include_declarations = include_declarations
70
- @stack = [] #: Array[String]
71
- @references = [] #: Array[Reference]
72
-
73
- dispatcher.register(
74
- self,
75
- :on_class_node_enter,
76
- :on_class_node_leave,
77
- :on_module_node_enter,
78
- :on_module_node_leave,
79
- :on_singleton_class_node_enter,
80
- :on_singleton_class_node_leave,
81
- :on_def_node_enter,
82
- :on_def_node_leave,
83
- :on_multi_write_node_enter,
84
- :on_constant_path_write_node_enter,
85
- :on_constant_path_or_write_node_enter,
86
- :on_constant_path_operator_write_node_enter,
87
- :on_constant_path_and_write_node_enter,
88
- :on_constant_or_write_node_enter,
89
- :on_constant_path_node_enter,
90
- :on_constant_read_node_enter,
91
- :on_constant_write_node_enter,
92
- :on_constant_or_write_node_enter,
93
- :on_constant_and_write_node_enter,
94
- :on_constant_operator_write_node_enter,
95
- :on_instance_variable_read_node_enter,
96
- :on_instance_variable_write_node_enter,
97
- :on_instance_variable_and_write_node_enter,
98
- :on_instance_variable_operator_write_node_enter,
99
- :on_instance_variable_or_write_node_enter,
100
- :on_instance_variable_target_node_enter,
101
- :on_call_node_enter,
102
- )
103
- end
104
-
105
- #: -> Array[Reference]
106
- def references
107
- return @references if @include_declarations
108
-
109
- @references.reject(&:declaration)
110
- end
111
-
112
- #: (Prism::ClassNode node) -> void
113
- def on_class_node_enter(node)
114
- @stack << node.constant_path.slice
115
- end
116
-
117
- #: (Prism::ClassNode node) -> void
118
- def on_class_node_leave(node)
119
- @stack.pop
120
- end
121
-
122
- #: (Prism::ModuleNode node) -> void
123
- def on_module_node_enter(node)
124
- @stack << node.constant_path.slice
125
- end
126
-
127
- #: (Prism::ModuleNode node) -> void
128
- def on_module_node_leave(node)
129
- @stack.pop
130
- end
131
-
132
- #: (Prism::SingletonClassNode node) -> void
133
- def on_singleton_class_node_enter(node)
134
- expression = node.expression
135
- return unless expression.is_a?(Prism::SelfNode)
136
-
137
- @stack << "<#{@stack.last}>"
138
- end
139
-
140
- #: (Prism::SingletonClassNode node) -> void
141
- def on_singleton_class_node_leave(node)
142
- @stack.pop
143
- end
144
-
145
- #: (Prism::ConstantPathNode node) -> void
146
- def on_constant_path_node_enter(node)
147
- name = Index.constant_name(node)
148
- return unless name
149
-
150
- collect_constant_references(name, node.location)
151
- end
152
-
153
- #: (Prism::ConstantReadNode node) -> void
154
- def on_constant_read_node_enter(node)
155
- name = Index.constant_name(node)
156
- return unless name
157
-
158
- collect_constant_references(name, node.location)
159
- end
160
-
161
- #: (Prism::MultiWriteNode node) -> void
162
- def on_multi_write_node_enter(node)
163
- [*node.lefts, *node.rest, *node.rights].each do |target|
164
- case target
165
- when Prism::ConstantTargetNode, Prism::ConstantPathTargetNode
166
- collect_constant_references(target.name.to_s, target.location)
167
- end
168
- end
169
- end
170
-
171
- #: (Prism::ConstantPathWriteNode node) -> void
172
- def on_constant_path_write_node_enter(node)
173
- target = node.target
174
- return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
175
-
176
- name = Index.constant_name(target)
177
- return unless name
178
-
179
- collect_constant_references(name, target.location)
180
- end
181
-
182
- #: (Prism::ConstantPathOrWriteNode node) -> void
183
- def on_constant_path_or_write_node_enter(node)
184
- target = node.target
185
- return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
186
-
187
- name = Index.constant_name(target)
188
- return unless name
189
-
190
- collect_constant_references(name, target.location)
191
- end
192
-
193
- #: (Prism::ConstantPathOperatorWriteNode node) -> void
194
- def on_constant_path_operator_write_node_enter(node)
195
- target = node.target
196
- return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
197
-
198
- name = Index.constant_name(target)
199
- return unless name
200
-
201
- collect_constant_references(name, target.location)
202
- end
203
-
204
- #: (Prism::ConstantPathAndWriteNode node) -> void
205
- def on_constant_path_and_write_node_enter(node)
206
- target = node.target
207
- return unless target.parent.nil? || target.parent.is_a?(Prism::ConstantReadNode)
208
-
209
- name = Index.constant_name(target)
210
- return unless name
211
-
212
- collect_constant_references(name, target.location)
213
- end
214
-
215
- #: (Prism::ConstantWriteNode node) -> void
216
- def on_constant_write_node_enter(node)
217
- collect_constant_references(node.name.to_s, node.name_loc)
218
- end
219
-
220
- #: (Prism::ConstantOrWriteNode node) -> void
221
- def on_constant_or_write_node_enter(node)
222
- collect_constant_references(node.name.to_s, node.name_loc)
223
- end
224
-
225
- #: (Prism::ConstantAndWriteNode node) -> void
226
- def on_constant_and_write_node_enter(node)
227
- collect_constant_references(node.name.to_s, node.name_loc)
228
- end
229
-
230
- #: (Prism::ConstantOperatorWriteNode node) -> void
231
- def on_constant_operator_write_node_enter(node)
232
- collect_constant_references(node.name.to_s, node.name_loc)
233
- end
234
-
235
- #: (Prism::DefNode node) -> void
236
- def on_def_node_enter(node)
237
- if @target.is_a?(MethodTarget) && (name = node.name.to_s) == @target.method_name
238
- @references << Reference.new(name, node.name_loc, declaration: true)
239
- end
240
-
241
- if node.receiver.is_a?(Prism::SelfNode)
242
- @stack << "<#{@stack.last}>"
243
- end
244
- end
245
-
246
- #: (Prism::DefNode node) -> void
247
- def on_def_node_leave(node)
248
- if node.receiver.is_a?(Prism::SelfNode)
249
- @stack.pop
250
- end
251
- end
252
-
253
- #: (Prism::InstanceVariableReadNode node) -> void
254
- def on_instance_variable_read_node_enter(node)
255
- collect_instance_variable_references(node.name.to_s, node.location, false)
256
- end
257
-
258
- #: (Prism::InstanceVariableWriteNode node) -> void
259
- def on_instance_variable_write_node_enter(node)
260
- collect_instance_variable_references(node.name.to_s, node.name_loc, true)
261
- end
262
-
263
- #: (Prism::InstanceVariableAndWriteNode node) -> void
264
- def on_instance_variable_and_write_node_enter(node)
265
- collect_instance_variable_references(node.name.to_s, node.name_loc, true)
266
- end
267
-
268
- #: (Prism::InstanceVariableOperatorWriteNode node) -> void
269
- def on_instance_variable_operator_write_node_enter(node)
270
- collect_instance_variable_references(node.name.to_s, node.name_loc, true)
271
- end
272
-
273
- #: (Prism::InstanceVariableOrWriteNode node) -> void
274
- def on_instance_variable_or_write_node_enter(node)
275
- collect_instance_variable_references(node.name.to_s, node.name_loc, true)
276
- end
277
-
278
- #: (Prism::InstanceVariableTargetNode node) -> void
279
- def on_instance_variable_target_node_enter(node)
280
- collect_instance_variable_references(node.name.to_s, node.location, true)
281
- end
282
-
283
- #: (Prism::CallNode node) -> void
284
- def on_call_node_enter(node)
285
- if @target.is_a?(MethodTarget) && (name = node.name.to_s) == @target.method_name
286
- @references << Reference.new(
287
- name,
288
- node.message_loc, #: as !nil
289
- declaration: false,
290
- )
291
- end
292
- end
293
-
294
- private
295
-
296
- #: (String name, Prism::Location location) -> void
297
- def collect_constant_references(name, location)
298
- return unless @target.is_a?(ConstTarget)
299
-
300
- entries = @index.resolve(name, @stack)
301
- return unless entries
302
-
303
- # Filter down to all constant declarations that match the expected name and type
304
- matching_entries = entries.select do |e|
305
- [
306
- Entry::Namespace,
307
- Entry::Constant,
308
- Entry::ConstantAlias,
309
- Entry::UnresolvedConstantAlias,
310
- ].any? { |klass| e.is_a?(klass) } &&
311
- e.name == @target.fully_qualified_name
312
- end
313
-
314
- return if matching_entries.empty?
315
-
316
- # If any of the matching entries have the same location as the constant and were
317
- # defined in the same file, then it is that constant's declaration
318
- declaration = matching_entries.any? do |e|
319
- e.uri == @uri && e.name_location == location
320
- end
321
-
322
- @references << Reference.new(name, location, declaration: declaration)
323
- end
324
-
325
- #: (String name, Prism::Location location, bool declaration) -> void
326
- def collect_instance_variable_references(name, location, declaration)
327
- return unless @target.is_a?(InstanceVariableTarget) && name == @target.name
328
-
329
- receiver_type = Index.actual_nesting(@stack, nil).join("::")
330
- if @target.owner_ancestors.include?(receiver_type)
331
- @references << Reference.new(name, location, declaration: declaration)
332
- end
333
- end
334
- end
335
- end
@@ -1,20 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- module RubyLsp
5
- # The path to the `static_docs` directory, where we keep long-form static documentation
6
- STATIC_DOCS_PATH = File.join(
7
- File.dirname(
8
- File.dirname(
9
- __dir__, #: as !nil
10
- ),
11
- ),
12
- "static_docs",
13
- ) #: String
14
-
15
- # A map of keyword => short documentation to be displayed on hover or completion
16
- KEYWORD_DOCS = {
17
- "break" => "Terminates the execution of a block or loop",
18
- "yield" => "Invokes the passed block with the given arguments",
19
- }.freeze #: Hash[String, String]
20
- end
data/static_docs/break.md DELETED
@@ -1,103 +0,0 @@
1
- # Break
2
-
3
- In Ruby, the `break` keyword is used to exit a loop or block prematurely. Unlike `next` which skips to the next iteration, `break` terminates the loop entirely and continues with the code after the loop.
4
-
5
- ```ruby
6
- # Basic break usage in a loop
7
- 5.times do |i|
8
- break if i == 3
9
-
10
- puts i
11
- end
12
- # Output:
13
- # 0
14
- # 1
15
- # 2
16
- ```
17
-
18
- The `break` statement can be used with any of Ruby's iteration methods or loops.
19
-
20
- ```ruby
21
- array = [1, 2, 3, 4, 5]
22
-
23
- # Break in each iteration
24
- array.each do |num|
25
- break if num > 3
26
-
27
- puts "Number: #{num}"
28
- end
29
- # Output:
30
- # Number: 1
31
- # Number: 2
32
- # Number: 3
33
-
34
- # Break in an infinite loop
35
- count = 0
36
- loop do
37
- count += 1
38
- break if count >= 3
39
-
40
- puts "Count: #{count}"
41
- end
42
- # Output:
43
- # Count: 1
44
- # Count: 2
45
- ```
46
-
47
- ## Break with a Value
48
-
49
- When used inside a block, `break` can return a value that becomes the result of the method call.
50
-
51
- ```ruby
52
- # Break with a return value in map
53
- result = [1, 2, 3, 4, 5].map do |num|
54
- break "Too large!" if num > 3
55
-
56
- num * 2
57
- end
58
- puts result # Output: "Too large!"
59
-
60
- # Break with a value in find
61
- number = (1..10).find do |n|
62
- break n if n > 5 && n.even?
63
- end
64
- puts number # Output: 6
65
- ```
66
-
67
- ## Break in Nested Loops
68
-
69
- When using `break` in nested loops, it only exits the innermost loop. To break from nested loops, you typically need to use a flag or return.
70
-
71
- ```ruby
72
- # Break in nested iteration
73
- (1..3).each do |i|
74
- puts "Outer: #{i}"
75
-
76
- (1..3).each do |j|
77
- break if j == 2
78
-
79
- puts " Inner: #{j}"
80
- end
81
- end
82
- # Output:
83
- # Outer: 1
84
- # Inner: 1
85
- # Outer: 2
86
- # Inner: 1
87
- # Outer: 3
88
- # Inner: 1
89
-
90
- # Breaking from nested loops with a flag
91
- found = false
92
- (1..3).each do |i|
93
- (1..3).each do |j|
94
- if i * j == 4
95
- found = true
96
- break
97
- end
98
- end
99
- break if found
100
- end
101
- ```
102
-
103
- The `break` keyword is essential for controlling loop execution and implementing early exit conditions. It's particularly useful when you've found what you're looking for and don't need to continue iterating.
data/static_docs/yield.md DELETED
@@ -1,81 +0,0 @@
1
- # Yield
2
-
3
- In Ruby, every method implicitly accepts a block, even when not included in the parameters list.
4
-
5
- ```ruby
6
- def foo
7
- end
8
-
9
- foo { 123 } # works!
10
- ```
11
-
12
- The `yield` keyword is used to invoke the block that was passed with arguments.
13
-
14
- ```ruby
15
- # Consider this method call. The block being passed to the method `foo` accepts an argument called `a`.
16
- # It then takes whatever argument was passed and multiplies it by 2
17
- foo do |a|
18
- a * 2
19
- end
20
-
21
- # In the `foo` method declaration, we can use `yield` to invoke the block that was passed and provide the block
22
- # with the value for the `a` argument
23
- def foo
24
- # Invoke the block passed to `foo` with the number 10 as the argument `a`
25
- result = yield(10)
26
- puts result # Will print 20
27
- end
28
- ```
29
-
30
- If `yield` is used to invoke the block, but no block was passed, that will result in a local jump error.
31
-
32
- ```ruby
33
- # If we invoke `foo` without a block, trying to `yield` will fail
34
- foo
35
-
36
- # `foo': no block given (yield) (LocalJumpError)
37
- ```
38
-
39
- We can decide to use `yield` conditionally by using Ruby's `block_given?` method, which will return `true` if a block
40
- was passed to the method.
41
-
42
- ```ruby
43
- def foo
44
- # If a block is passed when invoking `foo`, call the block with argument 10 and print the result.
45
- # Otherwise, just print that no block was passed
46
- if block_given?
47
- result = yield(10)
48
- puts result
49
- else
50
- puts "No block passed!"
51
- end
52
- end
53
-
54
- foo do |a|
55
- a * 2
56
- end
57
- # => 20
58
-
59
- foo
60
- # => No block passed!
61
- ```
62
-
63
- ## Block parameter
64
-
65
- In addition to implicit blocks, Ruby also allows developers to use explicit block parameters as part of the method's
66
- signature. In this scenario, we can use the reference to the block directly instead of relying on the `yield` keyword.
67
-
68
- ```ruby
69
- # Block parameters are prefixed with & and a name
70
- def foo(&my_block_param)
71
- # If a block was passed to `foo`, `my_block_param` will be a `Proc` object. Otherwise, it will be `nil`. We can use
72
- # that to check for its presence
73
- if my_block_param
74
- # Explicit block parameters are invoked using the method `call`, which is present in all `Proc` objects
75
- result = my_block_param.call(10)
76
- puts result
77
- else
78
- puts "No block passed!"
79
- end
80
- end
81
- ```