ruby-lsp 0.11.2 → 0.12.0
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.
- checksums.yaml +4 -4
- data/VERSION +1 -1
- data/exe/ruby-lsp +2 -1
- data/exe/ruby-lsp-doctor +16 -0
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +5 -1
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +205 -0
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +23 -106
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +6 -6
- data/lib/ruby_indexer/lib/ruby_indexer/visitor.rb +101 -49
- data/lib/ruby_indexer/ruby_indexer.rb +1 -0
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +49 -16
- data/lib/ruby_indexer/test/constant_test.rb +99 -36
- data/lib/ruby_indexer/test/index_test.rb +1 -1
- data/lib/ruby_indexer/test/method_test.rb +73 -0
- data/lib/ruby_indexer/test/test_case.rb +5 -1
- data/lib/ruby_lsp/addon.rb +8 -8
- data/lib/ruby_lsp/document.rb +14 -14
- data/lib/ruby_lsp/executor.rb +89 -53
- data/lib/ruby_lsp/internal.rb +7 -2
- data/lib/ruby_lsp/listener.rb +6 -6
- data/lib/ruby_lsp/requests/base_request.rb +1 -9
- data/lib/ruby_lsp/requests/code_action_resolve.rb +3 -3
- data/lib/ruby_lsp/requests/code_lens.rb +30 -30
- data/lib/ruby_lsp/requests/completion.rb +83 -32
- data/lib/ruby_lsp/requests/definition.rb +21 -15
- data/lib/ruby_lsp/requests/diagnostics.rb +1 -1
- data/lib/ruby_lsp/requests/document_highlight.rb +508 -31
- data/lib/ruby_lsp/requests/document_link.rb +24 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +42 -42
- data/lib/ruby_lsp/requests/folding_ranges.rb +83 -77
- data/lib/ruby_lsp/requests/hover.rb +22 -17
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -6
- data/lib/ruby_lsp/requests/selection_ranges.rb +13 -105
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +92 -92
- data/lib/ruby_lsp/requests/support/annotation.rb +3 -3
- data/lib/ruby_lsp/requests/support/common.rb +5 -5
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -0
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +10 -7
- data/lib/ruby_lsp/requests/support/sorbet.rb +28 -28
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/requests.rb +0 -1
- data/lib/ruby_lsp/setup_bundler.rb +8 -5
- metadata +19 -17
- data/lib/ruby_lsp/event_emitter.rb +0 -351
- data/lib/ruby_lsp/requests/support/highlight_target.rb +0 -118
data/lib/ruby_lsp/executor.rb
CHANGED
@@ -92,14 +92,14 @@ module RubyLsp
|
|
92
92
|
return cached_response if cached_response
|
93
93
|
|
94
94
|
# Run listeners for the document
|
95
|
-
|
96
|
-
folding_range = Requests::FoldingRanges.new(document.parse_result.comments,
|
97
|
-
document_symbol = Requests::DocumentSymbol.new(
|
98
|
-
document_link = Requests::DocumentLink.new(uri, document.comments,
|
99
|
-
code_lens = Requests::CodeLens.new(uri,
|
95
|
+
dispatcher = Prism::Dispatcher.new
|
96
|
+
folding_range = Requests::FoldingRanges.new(document.parse_result.comments, dispatcher, @message_queue)
|
97
|
+
document_symbol = Requests::DocumentSymbol.new(dispatcher, @message_queue)
|
98
|
+
document_link = Requests::DocumentLink.new(uri, document.comments, dispatcher, @message_queue)
|
99
|
+
code_lens = Requests::CodeLens.new(uri, dispatcher, @message_queue)
|
100
100
|
|
101
|
-
semantic_highlighting = Requests::SemanticHighlighting.new(
|
102
|
-
|
101
|
+
semantic_highlighting = Requests::SemanticHighlighting.new(dispatcher, @message_queue)
|
102
|
+
dispatcher.dispatch(document.tree)
|
103
103
|
|
104
104
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
105
105
|
# we actually received
|
@@ -210,21 +210,31 @@ module RubyLsp
|
|
210
210
|
# stuck indexing files
|
211
211
|
RubyIndexer.configuration.load_config
|
212
212
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
message
|
221
|
-
|
222
|
-
|
223
|
-
|
213
|
+
Thread.new do
|
214
|
+
begin
|
215
|
+
@index.index_all do |percentage|
|
216
|
+
progress("indexing-progress", percentage)
|
217
|
+
true
|
218
|
+
rescue ClosedQueueError
|
219
|
+
# Since we run indexing on a separate thread, it's possible to kill the server before indexing is complete.
|
220
|
+
# In those cases, the message queue will be closed and raise a ClosedQueueError. By returning `false`, we
|
221
|
+
# tell the index to stop working immediately
|
222
|
+
false
|
223
|
+
end
|
224
|
+
rescue StandardError => error
|
225
|
+
@message_queue << Notification.new(
|
226
|
+
message: "window/showMessage",
|
227
|
+
params: Interface::ShowMessageParams.new(
|
228
|
+
type: Constant::MessageType::ERROR,
|
229
|
+
message: "Error while indexing: #{error.message}",
|
230
|
+
),
|
231
|
+
)
|
232
|
+
end
|
224
233
|
|
225
|
-
|
226
|
-
|
227
|
-
|
234
|
+
# Always end the progress notification even if indexing failed or else it never goes away and the user has no
|
235
|
+
# way of dismissing it
|
236
|
+
end_progress("indexing-progress")
|
237
|
+
end
|
228
238
|
end
|
229
239
|
|
230
240
|
sig { params(query: T.nilable(String)).returns(T::Array[Interface::WorkspaceSymbol]) }
|
@@ -247,20 +257,20 @@ module RubyLsp
|
|
247
257
|
document = @store.get(uri)
|
248
258
|
target, parent, nesting = document.locate_node(
|
249
259
|
position,
|
250
|
-
node_types: [
|
260
|
+
node_types: [Prism::CallNode, Prism::ConstantReadNode, Prism::ConstantPathNode],
|
251
261
|
)
|
252
262
|
|
253
|
-
target = parent if target.is_a?(
|
263
|
+
target = parent if target.is_a?(Prism::ConstantReadNode) && parent.is_a?(Prism::ConstantPathNode)
|
254
264
|
|
255
|
-
|
265
|
+
dispatcher = Prism::Dispatcher.new
|
256
266
|
base_listener = Requests::Definition.new(
|
257
267
|
uri,
|
258
268
|
nesting,
|
259
269
|
@index,
|
260
|
-
|
270
|
+
dispatcher,
|
261
271
|
@message_queue,
|
262
272
|
)
|
263
|
-
|
273
|
+
dispatcher.dispatch_once(target)
|
264
274
|
base_listener.response
|
265
275
|
end
|
266
276
|
|
@@ -279,16 +289,16 @@ module RubyLsp
|
|
279
289
|
|
280
290
|
if (Requests::Hover::ALLOWED_TARGETS.include?(parent.class) &&
|
281
291
|
!Requests::Hover::ALLOWED_TARGETS.include?(target.class)) ||
|
282
|
-
(parent.is_a?(
|
292
|
+
(parent.is_a?(Prism::ConstantPathNode) && target.is_a?(Prism::ConstantReadNode))
|
283
293
|
target = parent
|
284
294
|
end
|
285
295
|
|
286
296
|
# Instantiate all listeners
|
287
|
-
|
288
|
-
hover = Requests::Hover.new(@index, nesting,
|
297
|
+
dispatcher = Prism::Dispatcher.new
|
298
|
+
hover = Requests::Hover.new(@index, nesting, dispatcher, @message_queue)
|
289
299
|
|
290
300
|
# Emit events for all listeners
|
291
|
-
|
301
|
+
dispatcher.dispatch_once(target)
|
292
302
|
|
293
303
|
hover.response
|
294
304
|
end
|
@@ -367,9 +377,9 @@ module RubyLsp
|
|
367
377
|
document = @store.get(uri)
|
368
378
|
|
369
379
|
target, parent = document.locate_node(position)
|
370
|
-
|
371
|
-
listener = Requests::DocumentHighlight.new(target, parent,
|
372
|
-
|
380
|
+
dispatcher = Prism::Dispatcher.new
|
381
|
+
listener = Requests::DocumentHighlight.new(target, parent, dispatcher, @message_queue)
|
382
|
+
dispatcher.visit(document.tree)
|
373
383
|
listener.response
|
374
384
|
end
|
375
385
|
|
@@ -380,9 +390,9 @@ module RubyLsp
|
|
380
390
|
start_line = range.dig(:start, :line)
|
381
391
|
end_line = range.dig(:end, :line)
|
382
392
|
|
383
|
-
|
384
|
-
listener = Requests::InlayHints.new(start_line..end_line,
|
385
|
-
|
393
|
+
dispatcher = Prism::Dispatcher.new
|
394
|
+
listener = Requests::InlayHints.new(start_line..end_line, dispatcher, @message_queue)
|
395
|
+
dispatcher.visit(document.tree)
|
386
396
|
listener.response
|
387
397
|
end
|
388
398
|
|
@@ -444,13 +454,13 @@ module RubyLsp
|
|
444
454
|
start_line = range.dig(:start, :line)
|
445
455
|
end_line = range.dig(:end, :line)
|
446
456
|
|
447
|
-
|
457
|
+
dispatcher = Prism::Dispatcher.new
|
448
458
|
listener = Requests::SemanticHighlighting.new(
|
449
|
-
|
459
|
+
dispatcher,
|
450
460
|
@message_queue,
|
451
461
|
range: start_line..end_line,
|
452
462
|
)
|
453
|
-
|
463
|
+
dispatcher.visit(document.tree)
|
454
464
|
|
455
465
|
Requests::Support::SemanticTokenEncoder.new.encode(listener.response)
|
456
466
|
end
|
@@ -471,29 +481,29 @@ module RubyLsp
|
|
471
481
|
# the node, as it could not be a constant
|
472
482
|
target_node_types = if ("A".."Z").cover?(document.source[char_position - 1])
|
473
483
|
char_position -= 1
|
474
|
-
[
|
484
|
+
[Prism::ConstantReadNode, Prism::ConstantPathNode]
|
475
485
|
else
|
476
|
-
[
|
486
|
+
[Prism::CallNode]
|
477
487
|
end
|
478
488
|
|
479
489
|
matched, parent, nesting = document.locate(document.tree, char_position, node_types: target_node_types)
|
480
490
|
return unless matched && parent
|
481
491
|
|
482
492
|
target = case matched
|
483
|
-
when
|
493
|
+
when Prism::CallNode
|
484
494
|
message = matched.message
|
485
495
|
return unless message == "require"
|
486
496
|
|
487
497
|
args = matched.arguments&.arguments
|
488
|
-
return if args.nil? || args.is_a?(
|
498
|
+
return if args.nil? || args.is_a?(Prism::ForwardingArgumentsNode)
|
489
499
|
|
490
500
|
argument = args.first
|
491
|
-
return unless argument.is_a?(
|
501
|
+
return unless argument.is_a?(Prism::StringNode)
|
492
502
|
return unless (argument.location.start_offset..argument.location.end_offset).cover?(char_position)
|
493
503
|
|
494
504
|
argument
|
495
|
-
when
|
496
|
-
if parent.is_a?(
|
505
|
+
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
506
|
+
if parent.is_a?(Prism::ConstantPathNode) && matched.is_a?(Prism::ConstantReadNode)
|
497
507
|
parent
|
498
508
|
else
|
499
509
|
matched
|
@@ -502,19 +512,19 @@ module RubyLsp
|
|
502
512
|
|
503
513
|
return unless target
|
504
514
|
|
505
|
-
|
515
|
+
dispatcher = Prism::Dispatcher.new
|
506
516
|
listener = Requests::Completion.new(
|
507
517
|
@index,
|
508
518
|
nesting,
|
509
|
-
|
519
|
+
dispatcher,
|
510
520
|
@message_queue,
|
511
521
|
)
|
512
|
-
|
522
|
+
dispatcher.dispatch_once(target)
|
513
523
|
listener.response
|
514
524
|
end
|
515
525
|
|
516
|
-
sig { params(id: String, title: String).void }
|
517
|
-
def begin_progress(id, title)
|
526
|
+
sig { params(id: String, title: String, percentage: Integer).void }
|
527
|
+
def begin_progress(id, title, percentage: 0)
|
518
528
|
return unless @store.supports_progress
|
519
529
|
|
520
530
|
@message_queue << Request.new(
|
@@ -526,7 +536,29 @@ module RubyLsp
|
|
526
536
|
message: "$/progress",
|
527
537
|
params: Interface::ProgressParams.new(
|
528
538
|
token: id,
|
529
|
-
value: Interface::WorkDoneProgressBegin.new(
|
539
|
+
value: Interface::WorkDoneProgressBegin.new(
|
540
|
+
kind: "begin",
|
541
|
+
title: title,
|
542
|
+
percentage: percentage,
|
543
|
+
message: "#{percentage}% completed",
|
544
|
+
),
|
545
|
+
),
|
546
|
+
)
|
547
|
+
end
|
548
|
+
|
549
|
+
sig { params(id: String, percentage: Integer).void }
|
550
|
+
def progress(id, percentage)
|
551
|
+
return unless @store.supports_progress
|
552
|
+
|
553
|
+
@message_queue << Notification.new(
|
554
|
+
message: "$/progress",
|
555
|
+
params: Interface::ProgressParams.new(
|
556
|
+
token: id,
|
557
|
+
value: Interface::WorkDoneProgressReport.new(
|
558
|
+
kind: "report",
|
559
|
+
percentage: percentage,
|
560
|
+
message: "#{percentage}% completed",
|
561
|
+
),
|
530
562
|
),
|
531
563
|
)
|
532
564
|
end
|
@@ -542,6 +574,9 @@ module RubyLsp
|
|
542
574
|
value: Interface::WorkDoneProgressEnd.new(kind: "end"),
|
543
575
|
),
|
544
576
|
)
|
577
|
+
rescue ClosedQueueError
|
578
|
+
# If the server was killed and the message queue is already closed, there's no way to end the progress
|
579
|
+
# notification
|
545
580
|
end
|
546
581
|
|
547
582
|
sig { params(options: T::Hash[Symbol, T.untyped]).returns(Interface::InitializeResult) }
|
@@ -557,7 +592,8 @@ module RubyLsp
|
|
557
592
|
encodings.first
|
558
593
|
end
|
559
594
|
|
560
|
-
|
595
|
+
progress = options.dig(:capabilities, :window, :workDoneProgress)
|
596
|
+
@store.supports_progress = progress.nil? ? true : progress
|
561
597
|
formatter = options.dig(:initializationOptions, :formatter) || "auto"
|
562
598
|
@store.formatter = if formatter == "auto"
|
563
599
|
DependencyDetector.instance.detected_formatter
|
data/lib/ruby_lsp/internal.rb
CHANGED
@@ -1,8 +1,14 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
# If YARP is in the bundle, we have to remove it from the $LOAD_PATH because it contains a default export named `prism`
|
5
|
+
# that will conflict with the actual Prism gem
|
6
|
+
yarp_require_paths = Gem.loaded_specs["yarp"]&.full_require_paths
|
7
|
+
$LOAD_PATH.delete_if { |path| yarp_require_paths.include?(path) } if yarp_require_paths
|
8
|
+
|
4
9
|
require "sorbet-runtime"
|
5
|
-
require "
|
10
|
+
require "prism"
|
11
|
+
require "prism/visitor"
|
6
12
|
require "language_server-protocol"
|
7
13
|
require "bundler"
|
8
14
|
require "uri"
|
@@ -16,7 +22,6 @@ require "ruby_lsp/utils"
|
|
16
22
|
require "ruby_lsp/parameter_scope"
|
17
23
|
require "ruby_lsp/server"
|
18
24
|
require "ruby_lsp/executor"
|
19
|
-
require "ruby_lsp/event_emitter"
|
20
25
|
require "ruby_lsp/requests"
|
21
26
|
require "ruby_lsp/listener"
|
22
27
|
require "ruby_lsp/store"
|
data/lib/ruby_lsp/listener.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
# Listener is an abstract class to be used by requests for listening to events emitted when visiting an AST using the
|
6
|
-
#
|
6
|
+
# Prism::Dispatcher.
|
7
7
|
class Listener
|
8
8
|
extend T::Sig
|
9
9
|
extend T::Helpers
|
@@ -14,9 +14,9 @@ module RubyLsp
|
|
14
14
|
|
15
15
|
abstract!
|
16
16
|
|
17
|
-
sig { params(
|
18
|
-
def initialize(
|
19
|
-
@
|
17
|
+
sig { params(dispatcher: Prism::Dispatcher, message_queue: Thread::Queue).void }
|
18
|
+
def initialize(dispatcher, message_queue)
|
19
|
+
@dispatcher = dispatcher
|
20
20
|
@message_queue = message_queue
|
21
21
|
end
|
22
22
|
|
@@ -43,8 +43,8 @@ module RubyLsp
|
|
43
43
|
# When inheriting from ExtensibleListener, the `super` of constructor must be called **after** the subclass's own
|
44
44
|
# ivars have been initialized. This is because the constructor of ExtensibleListener calls
|
45
45
|
# `initialize_external_listener` which may depend on the subclass's ivars.
|
46
|
-
sig { params(
|
47
|
-
def initialize(
|
46
|
+
sig { params(dispatcher: Prism::Dispatcher, message_queue: Thread::Queue).void }
|
47
|
+
def initialize(dispatcher, message_queue)
|
48
48
|
super
|
49
49
|
@response_merged = T.let(false, T::Boolean)
|
50
50
|
@external_listeners = T.let(
|
@@ -4,7 +4,7 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
# :nodoc:
|
7
|
-
class BaseRequest <
|
7
|
+
class BaseRequest < Prism::Visitor
|
8
8
|
extend T::Sig
|
9
9
|
extend T::Helpers
|
10
10
|
include Support::Common
|
@@ -19,14 +19,6 @@ module RubyLsp
|
|
19
19
|
|
20
20
|
sig { abstract.returns(Object) }
|
21
21
|
def run; end
|
22
|
-
|
23
|
-
# YARP implements `visit_all` using `map` instead of `each` for users who want to use the pattern
|
24
|
-
# `result = visitor.visit(tree)`. However, we don't use that pattern and should avoid producing a new array for
|
25
|
-
# every single node visited
|
26
|
-
sig { params(nodes: T::Array[T.nilable(YARP::Node)]).void }
|
27
|
-
def visit_all(nodes)
|
28
|
-
nodes.each { |node| visit(node) }
|
29
|
-
end
|
30
22
|
end
|
31
23
|
end
|
32
24
|
end
|
@@ -55,7 +55,7 @@ module RubyLsp
|
|
55
55
|
|
56
56
|
# Find the closest statements node, so that we place the refactor in a valid position
|
57
57
|
closest_statements, parent_statements = @document
|
58
|
-
.locate(@document.tree, start_index, node_types: [
|
58
|
+
.locate(@document.tree, start_index, node_types: [Prism::StatementsNode, Prism::BlockNode])
|
59
59
|
|
60
60
|
return Error::InvalidTargetRange if closest_statements.nil? || closest_statements.child_nodes.compact.empty?
|
61
61
|
|
@@ -66,11 +66,11 @@ module RubyLsp
|
|
66
66
|
distance <= 0 ? Float::INFINITY : distance
|
67
67
|
end)
|
68
68
|
|
69
|
-
return Error::InvalidTargetRange if closest_node.is_a?(
|
69
|
+
return Error::InvalidTargetRange if closest_node.is_a?(Prism::MissingNode)
|
70
70
|
|
71
71
|
closest_node_loc = closest_node.location
|
72
72
|
# If the parent expression is a single line block, then we have to extract it inside of the oneline block
|
73
|
-
if parent_statements.is_a?(
|
73
|
+
if parent_statements.is_a?(Prism::BlockNode) &&
|
74
74
|
parent_statements.location.start_line == parent_statements.location.end_line
|
75
75
|
|
76
76
|
variable_source = " #{NEW_VARIABLE_NAME} = #{extracted_source};"
|
@@ -25,36 +25,36 @@ module RubyLsp
|
|
25
25
|
ResponseType = type_member { { fixed: T::Array[Interface::CodeLens] } }
|
26
26
|
|
27
27
|
BASE_COMMAND = T.let((File.exist?("Gemfile.lock") ? "bundle exec ruby" : "ruby") + " -Itest ", String)
|
28
|
-
ACCESS_MODIFIERS = T.let([
|
28
|
+
ACCESS_MODIFIERS = T.let([:public, :private, :protected], T::Array[Symbol])
|
29
29
|
SUPPORTED_TEST_LIBRARIES = T.let(["minitest", "test-unit"], T::Array[String])
|
30
30
|
|
31
31
|
sig { override.returns(ResponseType) }
|
32
32
|
attr_reader :_response
|
33
33
|
|
34
|
-
sig { params(uri: URI::Generic,
|
35
|
-
def initialize(uri,
|
34
|
+
sig { params(uri: URI::Generic, dispatcher: Prism::Dispatcher, message_queue: Thread::Queue).void }
|
35
|
+
def initialize(uri, dispatcher, message_queue)
|
36
36
|
@uri = T.let(uri, URI::Generic)
|
37
37
|
@_response = T.let([], ResponseType)
|
38
38
|
@path = T.let(uri.to_standardized_path, T.nilable(String))
|
39
39
|
# visibility_stack is a stack of [current_visibility, previous_visibility]
|
40
|
-
@visibility_stack = T.let([[
|
40
|
+
@visibility_stack = T.let([[:public, :public]], T::Array[T::Array[T.nilable(Symbol)]])
|
41
41
|
@class_stack = T.let([], T::Array[String])
|
42
42
|
|
43
|
-
super(
|
43
|
+
super(dispatcher, message_queue)
|
44
44
|
|
45
|
-
|
45
|
+
dispatcher.register(
|
46
46
|
self,
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
47
|
+
:on_class_node_enter,
|
48
|
+
:on_class_node_leave,
|
49
|
+
:on_def_node_enter,
|
50
|
+
:on_call_node_enter,
|
51
|
+
:on_call_node_leave,
|
52
52
|
)
|
53
53
|
end
|
54
54
|
|
55
|
-
sig { params(node:
|
56
|
-
def
|
57
|
-
@visibility_stack.push([
|
55
|
+
sig { params(node: Prism::ClassNode).void }
|
56
|
+
def on_class_node_enter(node)
|
57
|
+
@visibility_stack.push([:public, :public])
|
58
58
|
class_name = node.constant_path.slice
|
59
59
|
@class_stack.push(class_name)
|
60
60
|
|
@@ -68,19 +68,19 @@ module RubyLsp
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
sig { params(node:
|
72
|
-
def
|
71
|
+
sig { params(node: Prism::ClassNode).void }
|
72
|
+
def on_class_node_leave(node)
|
73
73
|
@visibility_stack.pop
|
74
74
|
@class_stack.pop
|
75
75
|
end
|
76
76
|
|
77
|
-
sig { params(node:
|
78
|
-
def
|
77
|
+
sig { params(node: Prism::DefNode).void }
|
78
|
+
def on_def_node_enter(node)
|
79
79
|
class_name = @class_stack.last
|
80
80
|
return unless class_name&.end_with?("Test")
|
81
81
|
|
82
82
|
visibility, _ = @visibility_stack.last
|
83
|
-
if visibility ==
|
83
|
+
if visibility == :public
|
84
84
|
method_name = node.name.to_s
|
85
85
|
if @path && method_name.start_with?("test_")
|
86
86
|
add_test_code_lens(
|
@@ -93,8 +93,8 @@ module RubyLsp
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
sig { params(node:
|
97
|
-
def
|
96
|
+
sig { params(node: Prism::CallNode).void }
|
97
|
+
def on_call_node_enter(node)
|
98
98
|
name = node.name
|
99
99
|
arguments = node.arguments
|
100
100
|
|
@@ -103,7 +103,7 @@ module RubyLsp
|
|
103
103
|
if arguments.nil?
|
104
104
|
@visibility_stack.pop
|
105
105
|
@visibility_stack.push([name, name])
|
106
|
-
elsif arguments.arguments.first.is_a?(
|
106
|
+
elsif arguments.arguments.first.is_a?(Prism::DefNode)
|
107
107
|
visibility, _ = @visibility_stack.pop
|
108
108
|
@visibility_stack.push([name, visibility])
|
109
109
|
end
|
@@ -111,9 +111,9 @@ module RubyLsp
|
|
111
111
|
return
|
112
112
|
end
|
113
113
|
|
114
|
-
if @path&.include?("Gemfile") && name ==
|
114
|
+
if @path&.include?("Gemfile") && name == :gem && arguments
|
115
115
|
first_argument = arguments.arguments.first
|
116
|
-
return unless first_argument.is_a?(
|
116
|
+
return unless first_argument.is_a?(Prism::StringNode)
|
117
117
|
|
118
118
|
remote = resolve_gem_remote(first_argument)
|
119
119
|
return unless remote
|
@@ -122,15 +122,15 @@ module RubyLsp
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
sig { params(node:
|
126
|
-
def
|
125
|
+
sig { params(node: Prism::CallNode).void }
|
126
|
+
def on_call_node_leave(node)
|
127
127
|
_, prev_visibility = @visibility_stack.pop
|
128
128
|
@visibility_stack.push([prev_visibility, prev_visibility])
|
129
129
|
end
|
130
130
|
|
131
131
|
sig { override.params(addon: Addon).returns(T.nilable(Listener[ResponseType])) }
|
132
132
|
def initialize_external_listener(addon)
|
133
|
-
addon.create_code_lens_listener(@uri, @
|
133
|
+
addon.create_code_lens_listener(@uri, @dispatcher, @message_queue)
|
134
134
|
end
|
135
135
|
|
136
136
|
sig { override.params(other: Listener[ResponseType]).returns(T.self_type) }
|
@@ -141,7 +141,7 @@ module RubyLsp
|
|
141
141
|
|
142
142
|
private
|
143
143
|
|
144
|
-
sig { params(node:
|
144
|
+
sig { params(node: Prism::Node, name: String, command: String, kind: Symbol).void }
|
145
145
|
def add_test_code_lens(node, name:, command:, kind:)
|
146
146
|
# don't add code lenses if the test library is not supported or unknown
|
147
147
|
return unless SUPPORTED_TEST_LIBRARIES.include?(DependencyDetector.instance.detected_test_library) && @path
|
@@ -183,7 +183,7 @@ module RubyLsp
|
|
183
183
|
)
|
184
184
|
end
|
185
185
|
|
186
|
-
sig { params(gem_name:
|
186
|
+
sig { params(gem_name: Prism::StringNode).returns(T.nilable(String)) }
|
187
187
|
def resolve_gem_remote(gem_name)
|
188
188
|
spec = Gem::Specification.stubs.find { |gem| gem.name == gem_name.content }&.to_spec
|
189
189
|
return if spec.nil?
|
@@ -215,7 +215,7 @@ module RubyLsp
|
|
215
215
|
command
|
216
216
|
end
|
217
217
|
|
218
|
-
sig { params(node:
|
218
|
+
sig { params(node: Prism::CallNode, remote: String).void }
|
219
219
|
def add_open_gem_remote_code_lens(node, remote)
|
220
220
|
@_response << create_code_lens(
|
221
221
|
node,
|