ruby-lsp 0.23.15 → 0.26.9
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 +17 -14
- data/exe/ruby-lsp-check +0 -4
- data/exe/ruby-lsp-launcher +41 -14
- data/exe/ruby-lsp-test-exec +6 -0
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +0 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +0 -1
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +4 -3
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +42 -20
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +1 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +49 -62
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +84 -74
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +6 -9
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +9 -14
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +12 -8
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +4 -4
- data/lib/ruby_lsp/addon.rb +44 -15
- data/lib/ruby_lsp/base_server.rb +56 -37
- data/lib/ruby_lsp/client_capabilities.rb +6 -1
- data/lib/ruby_lsp/document.rb +174 -62
- data/lib/ruby_lsp/erb_document.rb +10 -8
- data/lib/ruby_lsp/global_state.rb +86 -33
- data/lib/ruby_lsp/internal.rb +6 -3
- data/lib/ruby_lsp/listeners/completion.rb +22 -11
- data/lib/ruby_lsp/listeners/definition.rb +41 -21
- data/lib/ruby_lsp/listeners/document_highlight.rb +26 -1
- data/lib/ruby_lsp/listeners/document_link.rb +64 -28
- data/lib/ruby_lsp/listeners/hover.rb +27 -16
- data/lib/ruby_lsp/listeners/inlay_hints.rb +5 -3
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +2 -2
- data/lib/ruby_lsp/listeners/signature_help.rb +2 -2
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -79
- data/lib/ruby_lsp/listeners/test_discovery.rb +39 -21
- data/lib/ruby_lsp/listeners/test_style.rb +75 -35
- data/lib/ruby_lsp/rbs_document.rb +3 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +83 -58
- data/lib/ruby_lsp/requests/code_actions.rb +20 -5
- data/lib/ruby_lsp/requests/code_lens.rb +27 -6
- data/lib/ruby_lsp/requests/completion.rb +3 -3
- data/lib/ruby_lsp/requests/completion_resolve.rb +8 -6
- data/lib/ruby_lsp/requests/definition.rb +4 -7
- data/lib/ruby_lsp/requests/discover_tests.rb +2 -2
- data/lib/ruby_lsp/requests/document_highlight.rb +2 -2
- data/lib/ruby_lsp/requests/document_link.rb +1 -1
- data/lib/ruby_lsp/requests/folding_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +64 -12
- data/lib/ruby_lsp/requests/hover.rb +3 -6
- data/lib/ruby_lsp/requests/inlay_hints.rb +4 -4
- data/lib/ruby_lsp/requests/on_type_formatting.rb +1 -1
- data/lib/ruby_lsp/requests/prepare_rename.rb +1 -1
- data/lib/ruby_lsp/requests/references.rb +10 -21
- data/lib/ruby_lsp/requests/rename.rb +9 -10
- data/lib/ruby_lsp/requests/request.rb +8 -8
- data/lib/ruby_lsp/requests/selection_ranges.rb +2 -2
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +2 -2
- data/lib/ruby_lsp/requests/signature_help.rb +2 -2
- data/lib/ruby_lsp/requests/support/annotation.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +9 -12
- data/lib/ruby_lsp/requests/support/formatter.rb +16 -15
- data/lib/ruby_lsp/requests/support/package_url.rb +414 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +7 -1
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +2 -2
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +13 -3
- data/lib/ruby_lsp/requests/support/source_uri.rb +7 -4
- data/lib/ruby_lsp/requests/support/test_item.rb +7 -1
- data/lib/ruby_lsp/requests/workspace_symbol.rb +20 -12
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +1 -4
- data/lib/ruby_lsp/response_builders/document_symbol.rb +2 -3
- data/lib/ruby_lsp/response_builders/hover.rb +1 -4
- data/lib/ruby_lsp/response_builders/response_builder.rb +6 -7
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +4 -5
- data/lib/ruby_lsp/response_builders/signature_help.rb +1 -2
- data/lib/ruby_lsp/response_builders/test_collection.rb +29 -3
- data/lib/ruby_lsp/ruby_document.rb +14 -42
- data/lib/ruby_lsp/scripts/compose_bundle.rb +3 -3
- data/lib/ruby_lsp/scripts/compose_bundle_windows.rb +3 -1
- data/lib/ruby_lsp/server.rb +173 -130
- data/lib/ruby_lsp/setup_bundler.rb +114 -47
- data/lib/ruby_lsp/static_docs.rb +1 -0
- data/lib/ruby_lsp/store.rb +6 -16
- data/lib/ruby_lsp/test_helper.rb +1 -4
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +121 -17
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +65 -25
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +16 -18
- data/lib/ruby_lsp/utils.rb +102 -13
- data/static_docs/break.md +103 -0
- metadata +8 -33
- data/lib/ruby_indexer/test/class_variables_test.rb +0 -140
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +0 -770
- data/lib/ruby_indexer/test/configuration_test.rb +0 -280
- data/lib/ruby_indexer/test/constant_test.rb +0 -402
- data/lib/ruby_indexer/test/enhancements_test.rb +0 -325
- data/lib/ruby_indexer/test/global_variable_test.rb +0 -49
- data/lib/ruby_indexer/test/index_test.rb +0 -2190
- data/lib/ruby_indexer/test/instance_variables_test.rb +0 -240
- data/lib/ruby_indexer/test/method_test.rb +0 -973
- data/lib/ruby_indexer/test/prefix_tree_test.rb +0 -150
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +0 -380
- data/lib/ruby_indexer/test/reference_finder_test.rb +0 -330
- data/lib/ruby_indexer/test/test_case.rb +0 -51
- data/lib/ruby_indexer/test/uri_test.rb +0 -85
- data/lib/ruby_lsp/load_sorbet.rb +0 -62
|
@@ -52,9 +52,9 @@ module RubyIndexer
|
|
|
52
52
|
comments = comments_to_string(declaration)
|
|
53
53
|
entry = if declaration.is_a?(RBS::AST::Declarations::Class)
|
|
54
54
|
parent_class = declaration.super_class&.name&.name&.to_s
|
|
55
|
-
Entry::Class.new(nesting, uri, location, location, comments, parent_class)
|
|
55
|
+
Entry::Class.new(@index.configuration, nesting, uri, location, location, comments, parent_class)
|
|
56
56
|
else
|
|
57
|
-
Entry::Module.new(nesting, uri, location, location, comments)
|
|
57
|
+
Entry::Module.new(@index.configuration, nesting, uri, location, location, comments)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
add_declaration_mixins_to_entry(declaration, entry)
|
|
@@ -103,29 +103,21 @@ module RubyIndexer
|
|
|
103
103
|
#: (RBS::AST::Members::MethodDefinition member, Entry::Namespace owner) -> void
|
|
104
104
|
def handle_method(member, owner)
|
|
105
105
|
name = member.name.name
|
|
106
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
|
106
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
|
107
107
|
location = to_ruby_indexer_location(member.location)
|
|
108
108
|
comments = comments_to_string(member)
|
|
109
109
|
|
|
110
|
-
visibility = case member.visibility
|
|
111
|
-
when :private
|
|
112
|
-
Entry::Visibility::PRIVATE
|
|
113
|
-
when :protected
|
|
114
|
-
Entry::Visibility::PROTECTED
|
|
115
|
-
else
|
|
116
|
-
Entry::Visibility::PUBLIC
|
|
117
|
-
end
|
|
118
|
-
|
|
119
110
|
real_owner = member.singleton? ? @index.existing_or_new_singleton_class(owner.name) : owner
|
|
120
111
|
signatures = signatures(member)
|
|
121
112
|
@index.add(Entry::Method.new(
|
|
113
|
+
@index.configuration,
|
|
122
114
|
name,
|
|
123
115
|
uri,
|
|
124
116
|
location,
|
|
125
117
|
location,
|
|
126
118
|
comments,
|
|
127
119
|
signatures,
|
|
128
|
-
visibility,
|
|
120
|
+
member.visibility || :public,
|
|
129
121
|
real_owner,
|
|
130
122
|
))
|
|
131
123
|
end
|
|
@@ -252,6 +244,7 @@ module RubyIndexer
|
|
|
252
244
|
def handle_constant(declaration, nesting, uri)
|
|
253
245
|
fully_qualified_name = [*nesting, declaration.name.name.to_s].join("::")
|
|
254
246
|
@index.add(Entry::Constant.new(
|
|
247
|
+
@index.configuration,
|
|
255
248
|
fully_qualified_name,
|
|
256
249
|
uri,
|
|
257
250
|
to_ruby_indexer_location(declaration.location),
|
|
@@ -267,6 +260,7 @@ module RubyIndexer
|
|
|
267
260
|
comments = comments_to_string(declaration)
|
|
268
261
|
|
|
269
262
|
@index.add(Entry::GlobalVariable.new(
|
|
263
|
+
@index.configuration,
|
|
270
264
|
name,
|
|
271
265
|
uri,
|
|
272
266
|
location,
|
|
@@ -276,10 +270,11 @@ module RubyIndexer
|
|
|
276
270
|
|
|
277
271
|
#: (RBS::AST::Members::Alias member, Entry::Namespace owner_entry) -> void
|
|
278
272
|
def handle_signature_alias(member, owner_entry)
|
|
279
|
-
uri = URI::Generic.from_path(path: member.location.buffer.name)
|
|
273
|
+
uri = URI::Generic.from_path(path: member.location.buffer.name.to_s)
|
|
280
274
|
comments = comments_to_string(member)
|
|
281
275
|
|
|
282
276
|
entry = Entry::UnresolvedMethodAlias.new(
|
|
277
|
+
@index.configuration,
|
|
283
278
|
member.new_name.to_s,
|
|
284
279
|
member.old_name.to_s,
|
|
285
280
|
owner_entry,
|
|
@@ -3,11 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
module RubyIndexer
|
|
5
5
|
class ReferenceFinder
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
abstract!
|
|
10
|
-
end
|
|
6
|
+
# @abstract
|
|
7
|
+
class Target; end
|
|
11
8
|
|
|
12
9
|
class ConstTarget < Target
|
|
13
10
|
#: String
|
|
@@ -35,10 +32,14 @@ module RubyIndexer
|
|
|
35
32
|
#: String
|
|
36
33
|
attr_reader :name
|
|
37
34
|
|
|
38
|
-
#:
|
|
39
|
-
|
|
35
|
+
#: Array[String]
|
|
36
|
+
attr_reader :owner_ancestors
|
|
37
|
+
|
|
38
|
+
#: (String name, Array[String] owner_ancestors) -> void
|
|
39
|
+
def initialize(name, owner_ancestors)
|
|
40
40
|
super()
|
|
41
41
|
@name = name
|
|
42
|
+
@owner_ancestors = owner_ancestors
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
|
|
@@ -325,7 +326,10 @@ module RubyIndexer
|
|
|
325
326
|
def collect_instance_variable_references(name, location, declaration)
|
|
326
327
|
return unless @target.is_a?(InstanceVariableTarget) && name == @target.name
|
|
327
328
|
|
|
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
|
|
329
333
|
end
|
|
330
334
|
end
|
|
331
335
|
end
|
|
@@ -8,7 +8,7 @@ module RubyIndexer
|
|
|
8
8
|
class << self
|
|
9
9
|
#: -> instance
|
|
10
10
|
def module_function_scope
|
|
11
|
-
new(module_func: true, visibility:
|
|
11
|
+
new(module_func: true, visibility: :private)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
#: -> instance
|
|
@@ -17,14 +17,14 @@ module RubyIndexer
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
#:
|
|
20
|
+
#: Symbol
|
|
21
21
|
attr_reader :visibility
|
|
22
22
|
|
|
23
23
|
#: bool
|
|
24
24
|
attr_reader :module_func
|
|
25
25
|
|
|
26
|
-
#: (?visibility:
|
|
27
|
-
def initialize(visibility:
|
|
26
|
+
#: (?visibility: Symbol, ?module_func: bool) -> void
|
|
27
|
+
def initialize(visibility: :public, module_func: false)
|
|
28
28
|
@visibility = visibility
|
|
29
29
|
@module_func = module_func
|
|
30
30
|
end
|
data/lib/ruby_lsp/addon.rb
CHANGED
|
@@ -19,12 +19,8 @@ module RubyLsp
|
|
|
19
19
|
# end
|
|
20
20
|
# end
|
|
21
21
|
# ```
|
|
22
|
+
# @abstract
|
|
22
23
|
class Addon
|
|
23
|
-
extend T::Sig
|
|
24
|
-
extend T::Helpers
|
|
25
|
-
|
|
26
|
-
abstract!
|
|
27
|
-
|
|
28
24
|
@addons = [] #: Array[Addon]
|
|
29
25
|
@addon_classes = [] #: Array[singleton(Addon)]
|
|
30
26
|
# Add-on instances that have declared a handler to accept file watcher events
|
|
@@ -60,7 +56,28 @@ module RubyLsp
|
|
|
60
56
|
addon_files = Gem.find_files("ruby_lsp/**/addon.rb")
|
|
61
57
|
|
|
62
58
|
if include_project_addons
|
|
63
|
-
|
|
59
|
+
project_addons = Dir.glob("#{global_state.workspace_path}/**/ruby_lsp/**/addon.rb")
|
|
60
|
+
bundle_path = Bundler.bundle_path.to_s
|
|
61
|
+
gems_dir = Bundler.bundle_path.join("gems")
|
|
62
|
+
|
|
63
|
+
# Create an array of rejection glob patterns to ignore add-ons already discovered through Gem.find_files if
|
|
64
|
+
# they are also copied inside the workspace for whatever reason. We received reports of projects having gems
|
|
65
|
+
# installed in vendor/bundle despite BUNDLE_PATH pointing elsewhere. Without this mechanism, we will
|
|
66
|
+
# double-require the same add-on, potentially for different versions of the same gem, which leads to incorrect
|
|
67
|
+
# behavior
|
|
68
|
+
reject_glob_patterns = addon_files.map do |path|
|
|
69
|
+
relative_gem_path = Pathname.new(path).relative_path_from(gems_dir)
|
|
70
|
+
first_part, *parts = relative_gem_path.to_s.split(File::SEPARATOR)
|
|
71
|
+
first_part&.gsub!(/-([0-9.]+)$/, "*")
|
|
72
|
+
"**/#{first_part}/#{parts.join("/")}"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
project_addons.reject! do |path|
|
|
76
|
+
path.start_with?(bundle_path) ||
|
|
77
|
+
reject_glob_patterns.any? { |pattern| File.fnmatch?(pattern, path, File::Constants::FNM_PATHNAME) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
addon_files.concat(project_addons)
|
|
64
81
|
end
|
|
65
82
|
|
|
66
83
|
errors = addon_files.filter_map do |addon_path|
|
|
@@ -178,22 +195,34 @@ module RubyLsp
|
|
|
178
195
|
|
|
179
196
|
# Each add-on should implement `MyAddon#activate` and use to perform any sort of initialization, such as
|
|
180
197
|
# reading information into memory or even spawning a separate process
|
|
181
|
-
|
|
182
|
-
|
|
198
|
+
# @abstract
|
|
199
|
+
#: (GlobalState, Thread::Queue) -> void
|
|
200
|
+
def activate(global_state, outgoing_queue)
|
|
201
|
+
raise AbstractMethodInvokedError
|
|
202
|
+
end
|
|
183
203
|
|
|
184
|
-
# Each add-on
|
|
204
|
+
# Each add-on must implement `MyAddon#deactivate` and use to perform any clean up, like shutting down a
|
|
185
205
|
# child process
|
|
186
|
-
|
|
187
|
-
|
|
206
|
+
# @abstract
|
|
207
|
+
#: -> void
|
|
208
|
+
def deactivate
|
|
209
|
+
raise AbstractMethodInvokedError
|
|
210
|
+
end
|
|
188
211
|
|
|
189
212
|
# Add-ons should override the `name` method to return the add-on name
|
|
190
|
-
|
|
191
|
-
|
|
213
|
+
# @abstract
|
|
214
|
+
#: -> String
|
|
215
|
+
def name
|
|
216
|
+
raise AbstractMethodInvokedError
|
|
217
|
+
end
|
|
192
218
|
|
|
193
219
|
# Add-ons should override the `version` method to return a semantic version string representing the add-on's
|
|
194
220
|
# version. This is used for compatibility checks
|
|
195
|
-
|
|
196
|
-
|
|
221
|
+
# @abstract
|
|
222
|
+
#: -> String
|
|
223
|
+
def version
|
|
224
|
+
raise AbstractMethodInvokedError
|
|
225
|
+
end
|
|
197
226
|
|
|
198
227
|
# Handle a response from a window/showMessageRequest request. Add-ons must include the addon_name as part of the
|
|
199
228
|
# original request so that the response is delegated to the correct add-on and must override this method to handle
|
data/lib/ruby_lsp/base_server.rb
CHANGED
|
@@ -2,19 +2,15 @@
|
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
4
|
module RubyLsp
|
|
5
|
+
# @abstract
|
|
5
6
|
class BaseServer
|
|
6
|
-
extend T::Sig
|
|
7
|
-
extend T::Helpers
|
|
8
|
-
|
|
9
|
-
abstract!
|
|
10
|
-
|
|
11
7
|
#: (**untyped options) -> void
|
|
12
8
|
def initialize(**options)
|
|
9
|
+
@reader = MessageReader.new(options[:reader] || $stdin) #: MessageReader
|
|
10
|
+
@writer = MessageWriter.new(options[:writer] || $stdout) #: MessageWriter
|
|
13
11
|
@test_mode = options[:test_mode] #: bool?
|
|
14
12
|
@setup_error = options[:setup_error] #: StandardError?
|
|
15
13
|
@install_error = options[:install_error] #: StandardError?
|
|
16
|
-
@writer = Transport::Stdio::Writer.new #: Transport::Stdio::Writer
|
|
17
|
-
@reader = Transport::Stdio::Reader.new #: Transport::Stdio::Reader
|
|
18
14
|
@incoming_queue = Thread::Queue.new #: Thread::Queue
|
|
19
15
|
@outgoing_queue = Thread::Queue.new #: Thread::Queue
|
|
20
16
|
@cancelled_requests = [] #: Array[Integer]
|
|
@@ -40,7 +36,7 @@ module RubyLsp
|
|
|
40
36
|
|
|
41
37
|
#: -> void
|
|
42
38
|
def start
|
|
43
|
-
@reader.
|
|
39
|
+
@reader.each_message do |message|
|
|
44
40
|
method = message[:method]
|
|
45
41
|
|
|
46
42
|
# We must parse the document under a mutex lock or else we might switch threads and accept text edits in the
|
|
@@ -87,8 +83,7 @@ module RubyLsp
|
|
|
87
83
|
# The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything
|
|
88
84
|
# else is pushed into the incoming queue
|
|
89
85
|
case method
|
|
90
|
-
when "initialize", "initialized", "
|
|
91
|
-
"rubyLsp/diagnoseState"
|
|
86
|
+
when "initialize", "initialized", "rubyLsp/diagnoseState", "$/cancelRequest"
|
|
92
87
|
process_message(message)
|
|
93
88
|
when "shutdown"
|
|
94
89
|
@global_state.synchronize do
|
|
@@ -98,13 +93,36 @@ module RubyLsp
|
|
|
98
93
|
@writer.write(Result.new(id: message[:id], response: nil).to_hash)
|
|
99
94
|
end
|
|
100
95
|
when "exit"
|
|
101
|
-
|
|
96
|
+
exit(@incoming_queue.closed? ? 0 : 1)
|
|
102
97
|
else
|
|
103
98
|
@incoming_queue << message
|
|
104
99
|
end
|
|
105
100
|
end
|
|
106
101
|
end
|
|
107
102
|
|
|
103
|
+
# This method is only intended to be used in tests! Pops the latest response that would be sent to the client
|
|
104
|
+
#: -> untyped
|
|
105
|
+
def pop_response
|
|
106
|
+
@outgoing_queue.pop(timeout: 20) || raise("No message received from server")
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# This method is only intended to be used in tests! Pushes a message to the incoming queue directly
|
|
110
|
+
#: (Hash[Symbol, untyped] message) -> void
|
|
111
|
+
def push_message(message)
|
|
112
|
+
@incoming_queue << message
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @abstract
|
|
116
|
+
#: (Hash[Symbol, untyped] message) -> void
|
|
117
|
+
def process_message(message)
|
|
118
|
+
raise AbstractMethodInvokedError
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
#: -> bool?
|
|
122
|
+
def test_mode?
|
|
123
|
+
@test_mode
|
|
124
|
+
end
|
|
125
|
+
|
|
108
126
|
#: -> void
|
|
109
127
|
def run_shutdown
|
|
110
128
|
@incoming_queue.clear
|
|
@@ -118,24 +136,14 @@ module RubyLsp
|
|
|
118
136
|
@store.clear
|
|
119
137
|
end
|
|
120
138
|
|
|
121
|
-
|
|
122
|
-
#: -> untyped
|
|
123
|
-
def pop_response
|
|
124
|
-
@outgoing_queue.pop
|
|
125
|
-
end
|
|
139
|
+
private
|
|
126
140
|
|
|
127
|
-
#
|
|
128
|
-
#:
|
|
129
|
-
def
|
|
130
|
-
|
|
141
|
+
# @abstract
|
|
142
|
+
#: -> void
|
|
143
|
+
def shutdown
|
|
144
|
+
raise AbstractMethodInvokedError
|
|
131
145
|
end
|
|
132
146
|
|
|
133
|
-
sig { abstract.params(message: T::Hash[Symbol, T.untyped]).void }
|
|
134
|
-
def process_message(message); end
|
|
135
|
-
|
|
136
|
-
sig { abstract.void }
|
|
137
|
-
def shutdown; end
|
|
138
|
-
|
|
139
147
|
#: (Integer id, String message, ?type: Integer) -> void
|
|
140
148
|
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
|
|
141
149
|
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
|
|
@@ -146,20 +154,31 @@ module RubyLsp
|
|
|
146
154
|
def new_worker
|
|
147
155
|
Thread.new do
|
|
148
156
|
while (message = @incoming_queue.pop)
|
|
149
|
-
|
|
157
|
+
handle_incoming_message(message)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
send_message(Result.new(id: id, response: nil))
|
|
155
|
-
@cancelled_requests.delete(id)
|
|
156
|
-
next
|
|
157
|
-
end
|
|
158
|
-
end
|
|
162
|
+
#: (Hash[Symbol, untyped]) -> void
|
|
163
|
+
def handle_incoming_message(message)
|
|
164
|
+
id = message[:id]
|
|
159
165
|
|
|
160
|
-
|
|
166
|
+
# Check if the request was cancelled before trying to process it
|
|
167
|
+
@global_state.synchronize do
|
|
168
|
+
if id && @cancelled_requests.delete(id)
|
|
169
|
+
send_message(Error.new(
|
|
170
|
+
id: id,
|
|
171
|
+
code: Constant::ErrorCodes::REQUEST_CANCELLED,
|
|
172
|
+
message: "Request #{id} was cancelled",
|
|
173
|
+
))
|
|
174
|
+
|
|
175
|
+
return
|
|
161
176
|
end
|
|
162
177
|
end
|
|
178
|
+
|
|
179
|
+
process_message(message)
|
|
180
|
+
# Ensure we remove the request if it got cancelled while it was being processed
|
|
181
|
+
@cancelled_requests.delete(id)
|
|
163
182
|
end
|
|
164
183
|
|
|
165
184
|
#: ((Result | Error | Notification | Request) message) -> void
|
|
@@ -180,7 +199,7 @@ module RubyLsp
|
|
|
180
199
|
|
|
181
200
|
#: (String message, ?type: Integer) -> void
|
|
182
201
|
def send_log_message(message, type: Constant::MessageType::LOG)
|
|
183
|
-
send_message(Notification.window_log_message(message, type:
|
|
202
|
+
send_message(Notification.window_log_message(message, type: type))
|
|
184
203
|
end
|
|
185
204
|
end
|
|
186
205
|
end
|
|
@@ -10,7 +10,8 @@ module RubyLsp
|
|
|
10
10
|
:supports_request_delegation,
|
|
11
11
|
:window_show_message_supports_extra_properties,
|
|
12
12
|
:supports_progress,
|
|
13
|
-
:supports_diagnostic_refresh
|
|
13
|
+
:supports_diagnostic_refresh,
|
|
14
|
+
:supports_code_lens_refresh
|
|
14
15
|
|
|
15
16
|
#: -> void
|
|
16
17
|
def initialize
|
|
@@ -34,6 +35,9 @@ module RubyLsp
|
|
|
34
35
|
|
|
35
36
|
# The editor supports server initiated refresh for diagnostics
|
|
36
37
|
@supports_diagnostic_refresh = false #: bool
|
|
38
|
+
|
|
39
|
+
# The editor supports server initiated refresh for code lenses
|
|
40
|
+
@supports_code_lens_refresh = false #: bool
|
|
37
41
|
end
|
|
38
42
|
|
|
39
43
|
#: (Hash[Symbol, untyped] capabilities) -> void
|
|
@@ -61,6 +65,7 @@ module RubyLsp
|
|
|
61
65
|
@supports_progress = progress if progress
|
|
62
66
|
|
|
63
67
|
@supports_diagnostic_refresh = workspace_capabilities.dig(:diagnostics, :refreshSupport) || false
|
|
68
|
+
@supports_code_lens_refresh = workspace_capabilities.dig(:codeLens, :refreshSupport) || false
|
|
64
69
|
end
|
|
65
70
|
|
|
66
71
|
#: -> bool
|