ruby-lsp 0.23.10 → 0.23.12
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/README.md +2 -2
- data/VERSION +1 -1
- data/exe/ruby-lsp-launcher +12 -11
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +52 -77
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +61 -144
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +8 -6
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +74 -183
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +55 -181
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +12 -14
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +21 -44
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +40 -58
- data/lib/ruby_indexer/lib/ruby_indexer/uri.rb +9 -16
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +5 -9
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +75 -0
- data/lib/ruby_indexer/test/configuration_test.rb +32 -2
- data/lib/ruby_indexer/test/index_test.rb +21 -0
- data/lib/ruby_indexer/test/method_test.rb +2 -2
- data/lib/ruby_lsp/addon.rb +32 -67
- data/lib/ruby_lsp/base_server.rb +12 -11
- data/lib/ruby_lsp/client_capabilities.rb +4 -6
- data/lib/ruby_lsp/document.rb +21 -32
- data/lib/ruby_lsp/erb_document.rb +17 -27
- data/lib/ruby_lsp/global_state.rb +30 -32
- data/lib/ruby_lsp/internal.rb +6 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +21 -39
- data/lib/ruby_lsp/listeners/completion.rb +34 -53
- data/lib/ruby_lsp/listeners/definition.rb +35 -49
- data/lib/ruby_lsp/listeners/document_highlight.rb +60 -69
- data/lib/ruby_lsp/listeners/document_link.rb +9 -19
- data/lib/ruby_lsp/listeners/document_symbol.rb +34 -48
- data/lib/ruby_lsp/listeners/folding_ranges.rb +31 -38
- data/lib/ruby_lsp/listeners/hover.rb +37 -47
- data/lib/ruby_lsp/listeners/inlay_hints.rb +3 -10
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +29 -35
- data/lib/ruby_lsp/listeners/signature_help.rb +4 -23
- data/lib/ruby_lsp/listeners/spec_style.rb +199 -0
- data/lib/ruby_lsp/listeners/test_style.rb +270 -0
- data/lib/ruby_lsp/node_context.rb +8 -35
- data/lib/ruby_lsp/rbs_document.rb +7 -5
- data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
- data/lib/ruby_lsp/requests/code_actions.rb +5 -14
- data/lib/ruby_lsp/requests/code_lens.rb +4 -13
- data/lib/ruby_lsp/requests/completion.rb +4 -15
- data/lib/ruby_lsp/requests/completion_resolve.rb +4 -4
- data/lib/ruby_lsp/requests/definition.rb +4 -12
- data/lib/ruby_lsp/requests/diagnostics.rb +6 -9
- data/lib/ruby_lsp/requests/discover_tests.rb +74 -0
- data/lib/ruby_lsp/requests/document_highlight.rb +3 -11
- data/lib/ruby_lsp/requests/document_link.rb +4 -13
- data/lib/ruby_lsp/requests/document_symbol.rb +4 -7
- data/lib/ruby_lsp/requests/folding_ranges.rb +4 -7
- data/lib/ruby_lsp/requests/formatting.rb +4 -7
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
- data/lib/ruby_lsp/requests/hover.rb +6 -16
- data/lib/ruby_lsp/requests/inlay_hints.rb +4 -13
- data/lib/ruby_lsp/requests/on_type_formatting.rb +17 -24
- data/lib/ruby_lsp/requests/prepare_rename.rb +3 -8
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +3 -4
- data/lib/ruby_lsp/requests/references.rb +5 -35
- data/lib/ruby_lsp/requests/rename.rb +9 -35
- data/lib/ruby_lsp/requests/request.rb +5 -17
- data/lib/ruby_lsp/requests/selection_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +6 -23
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +4 -5
- data/lib/ruby_lsp/requests/signature_help.rb +6 -24
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +12 -47
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +12 -14
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +7 -10
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +9 -15
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +1 -7
- data/lib/ruby_lsp/requests/support/source_uri.rb +5 -16
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +7 -10
- data/lib/ruby_lsp/requests/support/test_item.rb +60 -0
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +4 -5
- data/lib/ruby_lsp/requests/workspace_symbol.rb +3 -3
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +4 -4
- data/lib/ruby_lsp/response_builders/document_symbol.rb +8 -11
- data/lib/ruby_lsp/response_builders/hover.rb +5 -5
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +18 -40
- data/lib/ruby_lsp/response_builders/signature_help.rb +4 -5
- data/lib/ruby_lsp/response_builders/test_collection.rb +34 -0
- data/lib/ruby_lsp/ruby_document.rb +15 -40
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +106 -0
- data/lib/ruby_lsp/scope.rb +6 -10
- data/lib/ruby_lsp/server.rb +169 -72
- data/lib/ruby_lsp/setup_bundler.rb +25 -17
- data/lib/ruby_lsp/store.rb +12 -28
- data/lib/ruby_lsp/test_helper.rb +3 -12
- data/lib/ruby_lsp/test_reporter.rb +71 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +96 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +27 -65
- metadata +12 -3
@@ -12,7 +12,7 @@ module RubyIndexer
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def test_load_configuration_executes_configure_block
|
15
|
-
@config.apply_config({ "excluded_patterns" => ["**/fixtures
|
15
|
+
@config.apply_config({ "excluded_patterns" => ["**/fixtures/**/*"] })
|
16
16
|
uris = @config.indexable_uris
|
17
17
|
|
18
18
|
bundle_path = Bundler.bundle_path.join("gems")
|
@@ -39,7 +39,11 @@ module RubyIndexer
|
|
39
39
|
next if lazy_spec.name == "ruby-lsp"
|
40
40
|
|
41
41
|
spec = Gem::Specification.find_by_name(lazy_spec.name)
|
42
|
-
|
42
|
+
|
43
|
+
test_uris = uris.select do |uri|
|
44
|
+
File.fnmatch?(File.join(spec.full_gem_path, "test/**/*"), uri.full_path, File::Constants::FNM_PATHNAME)
|
45
|
+
end
|
46
|
+
assert_empty(test_uris)
|
43
47
|
rescue Gem::MissingSpecError
|
44
48
|
# Transitive dependencies might be missing when running tests on Windows
|
45
49
|
end
|
@@ -235,5 +239,31 @@ module RubyIndexer
|
|
235
239
|
end
|
236
240
|
end
|
237
241
|
end
|
242
|
+
|
243
|
+
def test_indexables_include_non_test_files_in_test_directories
|
244
|
+
# In order to linearize test parent classes and accurately detect the framework being used, then intermediate
|
245
|
+
# parent classes _must_ also be indexed. Otherwise, we have no way of linearizing the rest of the ancestors to
|
246
|
+
# determine what the test class ultimately inherits from.
|
247
|
+
#
|
248
|
+
# Therefore, we need to ensure that test files are excluded, but non test files inside test directories have to be
|
249
|
+
# indexed
|
250
|
+
FileUtils.touch("test/test_case.rb")
|
251
|
+
|
252
|
+
uris = @config.indexable_uris
|
253
|
+
project_paths = uris.filter_map do |uri|
|
254
|
+
path = uri.full_path
|
255
|
+
next if path.start_with?(Bundler.bundle_path.to_s) || path.start_with?(RbConfig::CONFIG["rubylibdir"])
|
256
|
+
|
257
|
+
Pathname.new(path).relative_path_from(Dir.pwd).to_s
|
258
|
+
end
|
259
|
+
|
260
|
+
begin
|
261
|
+
assert_includes(project_paths, "test/requests/support/expectations_test_runner.rb")
|
262
|
+
assert_includes(project_paths, "test/test_helper.rb")
|
263
|
+
assert_includes(project_paths, "test/test_case.rb")
|
264
|
+
ensure
|
265
|
+
FileUtils.rm("test/test_case.rb")
|
266
|
+
end
|
267
|
+
end
|
238
268
|
end
|
239
269
|
end
|
@@ -2161,5 +2161,26 @@ module RubyIndexer
|
|
2161
2161
|
|
2162
2162
|
assert_equal("@@hello", candidates.first&.name)
|
2163
2163
|
end
|
2164
|
+
|
2165
|
+
def test_actual_nesting
|
2166
|
+
assert_equal(["Foo"], Index.actual_nesting([], "Foo"))
|
2167
|
+
assert_equal(["TopLevel", "Foo"], Index.actual_nesting(["First", "::TopLevel"], "Foo"))
|
2168
|
+
assert_equal(["TopLevel", "Another", "Foo"], Index.actual_nesting(["::TopLevel", "Another"], "Foo"))
|
2169
|
+
assert_equal(["TopLevel"], Index.actual_nesting(["First", "::TopLevel"], nil))
|
2170
|
+
end
|
2171
|
+
|
2172
|
+
def test_constant_name
|
2173
|
+
node = Prism.parse("class var::Foo; end").value.statements.body.first.constant_path
|
2174
|
+
assert_nil(Index.constant_name(node))
|
2175
|
+
|
2176
|
+
node = Prism.parse("class ; end").value.statements.body.first.constant_path
|
2177
|
+
assert_nil(Index.constant_name(node))
|
2178
|
+
|
2179
|
+
node = Prism.parse("class method_call; end").value.statements.body.first.constant_path
|
2180
|
+
assert_nil(Index.constant_name(node))
|
2181
|
+
|
2182
|
+
node = Prism.parse("class Foo; end").value.statements.body.first.constant_path
|
2183
|
+
assert_equal("Foo", Index.constant_name(node))
|
2184
|
+
end
|
2164
2185
|
end
|
2165
2186
|
end
|
@@ -926,14 +926,14 @@ module RubyIndexer
|
|
926
926
|
|
927
927
|
private
|
928
928
|
|
929
|
-
|
929
|
+
#: (Entry::Method entry, String call_string) -> void
|
930
930
|
def assert_signature_matches(entry, call_string)
|
931
931
|
sig = T.must(entry.signatures.first)
|
932
932
|
arguments = parse_prism_args(call_string)
|
933
933
|
assert(sig.matches?(arguments), "Expected #{call_string} to match #{entry.name}#{entry.decorated_parameters}")
|
934
934
|
end
|
935
935
|
|
936
|
-
|
936
|
+
#: (Entry::Method entry, String call_string) -> void
|
937
937
|
def refute_signature_matches(entry, call_string)
|
938
938
|
sig = T.must(entry.signatures.first)
|
939
939
|
arguments = parse_prism_args(call_string)
|
data/lib/ruby_lsp/addon.rb
CHANGED
@@ -35,32 +35,24 @@ module RubyLsp
|
|
35
35
|
class IncompatibleApiError < StandardError; end
|
36
36
|
|
37
37
|
class << self
|
38
|
-
|
39
|
-
|
40
|
-
sig { returns(T::Array[Addon]) }
|
38
|
+
#: Array[Addon]
|
41
39
|
attr_accessor :addons
|
42
40
|
|
43
|
-
|
41
|
+
#: Array[Addon]
|
44
42
|
attr_accessor :file_watcher_addons
|
45
43
|
|
46
|
-
|
44
|
+
#: Array[singleton(Addon)]
|
47
45
|
attr_reader :addon_classes
|
48
46
|
|
49
47
|
# Automatically track and instantiate add-on classes
|
50
|
-
|
48
|
+
#: (singleton(Addon) child_class) -> void
|
51
49
|
def inherited(child_class)
|
52
50
|
addon_classes << child_class
|
53
51
|
super
|
54
52
|
end
|
55
53
|
|
56
54
|
# Discovers and loads all add-ons. Returns a list of errors when trying to require add-ons
|
57
|
-
|
58
|
-
params(
|
59
|
-
global_state: GlobalState,
|
60
|
-
outgoing_queue: Thread::Queue,
|
61
|
-
include_project_addons: T::Boolean,
|
62
|
-
).returns(T::Array[StandardError])
|
63
|
-
end
|
55
|
+
#: (GlobalState global_state, Thread::Queue outgoing_queue, ?include_project_addons: bool) -> Array[StandardError]
|
64
56
|
def load_addons(global_state, outgoing_queue, include_project_addons: true)
|
65
57
|
# Require all add-ons entry points, which should be placed under
|
66
58
|
# `some_gem/lib/ruby_lsp/your_gem_name/addon.rb` or in the workspace under
|
@@ -98,7 +90,7 @@ module RubyLsp
|
|
98
90
|
end
|
99
91
|
|
100
92
|
# Unloads all add-ons. Only intended to be invoked once when shutting down the Ruby LSP server
|
101
|
-
|
93
|
+
#: -> void
|
102
94
|
def unload_addons
|
103
95
|
@addons.each(&:deactivate)
|
104
96
|
@addons.clear
|
@@ -112,7 +104,7 @@ module RubyLsp
|
|
112
104
|
# Important: if the add-on is not found, AddonNotFoundError will be raised. If the add-on is found, but its
|
113
105
|
# current version does not satisfy the given version constraint, then IncompatibleApiError will be raised. It is
|
114
106
|
# the responsibility of the add-ons using this API to handle these errors appropriately.
|
115
|
-
|
107
|
+
#: (String addon_name, *String version_constraints) -> Addon
|
116
108
|
def get(addon_name, *version_constraints)
|
117
109
|
if version_constraints.empty?
|
118
110
|
raise IncompatibleApiError, "Must specify version constraints when accessing other add-ons"
|
@@ -144,7 +136,7 @@ module RubyLsp
|
|
144
136
|
# end
|
145
137
|
# end
|
146
138
|
# ```
|
147
|
-
|
139
|
+
#: (*String version_constraints) -> void
|
148
140
|
def depend_on_ruby_lsp!(*version_constraints)
|
149
141
|
version_object = Gem::Version.new(RubyLsp::VERSION)
|
150
142
|
|
@@ -155,23 +147,23 @@ module RubyLsp
|
|
155
147
|
end
|
156
148
|
end
|
157
149
|
|
158
|
-
|
150
|
+
#: -> void
|
159
151
|
def initialize
|
160
152
|
@errors = T.let([], T::Array[StandardError])
|
161
153
|
end
|
162
154
|
|
163
|
-
|
155
|
+
#: (StandardError error) -> self
|
164
156
|
def add_error(error)
|
165
157
|
@errors << error
|
166
158
|
self
|
167
159
|
end
|
168
160
|
|
169
|
-
|
161
|
+
#: -> bool
|
170
162
|
def error?
|
171
163
|
@errors.any?
|
172
164
|
end
|
173
165
|
|
174
|
-
|
166
|
+
#: -> String
|
175
167
|
def formatted_errors
|
176
168
|
<<~ERRORS
|
177
169
|
#{name}:
|
@@ -179,7 +171,7 @@ module RubyLsp
|
|
179
171
|
ERRORS
|
180
172
|
end
|
181
173
|
|
182
|
-
|
174
|
+
#: -> String
|
183
175
|
def errors_details
|
184
176
|
@errors.map(&:full_message).join("\n\n")
|
185
177
|
end
|
@@ -207,69 +199,42 @@ module RubyLsp
|
|
207
199
|
# original request so that the response is delegated to the correct add-on and must override this method to handle
|
208
200
|
# the response
|
209
201
|
# https://microsoft.github.io/language-server-protocol/specification#window_showMessageRequest
|
210
|
-
|
202
|
+
# @overridable
|
203
|
+
#: (String title) -> void
|
211
204
|
def handle_window_show_message_response(title); end
|
212
205
|
|
213
206
|
# Creates a new CodeLens listener. This method is invoked on every CodeLens request
|
214
|
-
|
215
|
-
|
216
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
|
217
|
-
uri: URI::Generic,
|
218
|
-
dispatcher: Prism::Dispatcher,
|
219
|
-
).void
|
220
|
-
end
|
207
|
+
# @overridable
|
208
|
+
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens] response_builder, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
|
221
209
|
def create_code_lens_listener(response_builder, uri, dispatcher); end
|
222
210
|
|
223
211
|
# Creates a new Hover listener. This method is invoked on every Hover request
|
224
|
-
|
225
|
-
|
226
|
-
response_builder: ResponseBuilders::Hover,
|
227
|
-
node_context: NodeContext,
|
228
|
-
dispatcher: Prism::Dispatcher,
|
229
|
-
).void
|
230
|
-
end
|
212
|
+
# @overridable
|
213
|
+
#: (ResponseBuilders::Hover response_builder, NodeContext node_context, Prism::Dispatcher dispatcher) -> void
|
231
214
|
def create_hover_listener(response_builder, node_context, dispatcher); end
|
232
215
|
|
233
216
|
# Creates a new DocumentSymbol listener. This method is invoked on every DocumentSymbol request
|
234
|
-
|
235
|
-
|
236
|
-
response_builder: ResponseBuilders::DocumentSymbol,
|
237
|
-
dispatcher: Prism::Dispatcher,
|
238
|
-
).void
|
239
|
-
end
|
217
|
+
# @overridable
|
218
|
+
#: (ResponseBuilders::DocumentSymbol response_builder, Prism::Dispatcher dispatcher) -> void
|
240
219
|
def create_document_symbol_listener(response_builder, dispatcher); end
|
241
220
|
|
242
|
-
|
243
|
-
|
244
|
-
response_builder: ResponseBuilders::SemanticHighlighting,
|
245
|
-
dispatcher: Prism::Dispatcher,
|
246
|
-
).void
|
247
|
-
end
|
221
|
+
# @overridable
|
222
|
+
#: (ResponseBuilders::SemanticHighlighting response_builder, Prism::Dispatcher dispatcher) -> void
|
248
223
|
def create_semantic_highlighting_listener(response_builder, dispatcher); end
|
249
224
|
|
250
225
|
# Creates a new Definition listener. This method is invoked on every Definition request
|
251
|
-
|
252
|
-
|
253
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
|
254
|
-
Interface::Location,
|
255
|
-
Interface::LocationLink,
|
256
|
-
)],
|
257
|
-
uri: URI::Generic,
|
258
|
-
node_context: NodeContext,
|
259
|
-
dispatcher: Prism::Dispatcher,
|
260
|
-
).void
|
261
|
-
end
|
226
|
+
# @overridable
|
227
|
+
#: (ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)] response_builder, URI::Generic uri, NodeContext node_context, Prism::Dispatcher dispatcher) -> void
|
262
228
|
def create_definition_listener(response_builder, uri, node_context, dispatcher); end
|
263
229
|
|
264
230
|
# Creates a new Completion listener. This method is invoked on every Completion request
|
265
|
-
|
266
|
-
|
267
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
268
|
-
node_context: NodeContext,
|
269
|
-
dispatcher: Prism::Dispatcher,
|
270
|
-
uri: URI::Generic,
|
271
|
-
).void
|
272
|
-
end
|
231
|
+
# @overridable
|
232
|
+
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, NodeContext node_context, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
273
233
|
def create_completion_listener(response_builder, node_context, dispatcher, uri); end
|
234
|
+
|
235
|
+
# Creates a new Discover Tests listener. This method is invoked on every DiscoverTests request
|
236
|
+
# @overridable
|
237
|
+
#: (ResponseBuilders::TestCollection response_builder, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
238
|
+
def create_discover_tests_listener(response_builder, dispatcher, uri); end
|
274
239
|
end
|
275
240
|
end
|
data/lib/ruby_lsp/base_server.rb
CHANGED
@@ -8,7 +8,7 @@ module RubyLsp
|
|
8
8
|
|
9
9
|
abstract!
|
10
10
|
|
11
|
-
|
11
|
+
#: (**untyped options) -> void
|
12
12
|
def initialize(**options)
|
13
13
|
@test_mode = T.let(options[:test_mode], T.nilable(T::Boolean))
|
14
14
|
@setup_error = T.let(options[:setup_error], T.nilable(StandardError))
|
@@ -41,7 +41,7 @@ module RubyLsp
|
|
41
41
|
process_message(initialize_request) if initialize_request
|
42
42
|
end
|
43
43
|
|
44
|
-
|
44
|
+
#: -> void
|
45
45
|
def start
|
46
46
|
@reader.read do |message|
|
47
47
|
method = message[:method]
|
@@ -90,7 +90,8 @@ module RubyLsp
|
|
90
90
|
# The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything
|
91
91
|
# else is pushed into the incoming queue
|
92
92
|
case method
|
93
|
-
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange"
|
93
|
+
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange",
|
94
|
+
"rubyLsp/diagnoseState"
|
94
95
|
process_message(message)
|
95
96
|
when "shutdown"
|
96
97
|
@global_state.synchronize do
|
@@ -107,7 +108,7 @@ module RubyLsp
|
|
107
108
|
end
|
108
109
|
end
|
109
110
|
|
110
|
-
|
111
|
+
#: -> void
|
111
112
|
def run_shutdown
|
112
113
|
@incoming_queue.clear
|
113
114
|
@outgoing_queue.clear
|
@@ -121,13 +122,13 @@ module RubyLsp
|
|
121
122
|
end
|
122
123
|
|
123
124
|
# This method is only intended to be used in tests! Pops the latest response that would be sent to the client
|
124
|
-
|
125
|
+
#: -> untyped
|
125
126
|
def pop_response
|
126
127
|
@outgoing_queue.pop
|
127
128
|
end
|
128
129
|
|
129
130
|
# This method is only intended to be used in tests! Pushes a message to the incoming queue directly
|
130
|
-
|
131
|
+
#: (Hash[Symbol, untyped] message) -> void
|
131
132
|
def push_message(message)
|
132
133
|
@incoming_queue << message
|
133
134
|
end
|
@@ -138,13 +139,13 @@ module RubyLsp
|
|
138
139
|
sig { abstract.void }
|
139
140
|
def shutdown; end
|
140
141
|
|
141
|
-
|
142
|
+
#: (Integer id, String message, ?type: Integer) -> void
|
142
143
|
def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
|
143
144
|
send_message(Error.new(id: id, code: Constant::ErrorCodes::REQUEST_FAILED, message: message))
|
144
145
|
send_message(Notification.window_show_message(message, type: type))
|
145
146
|
end
|
146
147
|
|
147
|
-
|
148
|
+
#: -> Thread
|
148
149
|
def new_worker
|
149
150
|
Thread.new do
|
150
151
|
while (message = T.let(@incoming_queue.pop, T.nilable(T::Hash[Symbol, T.untyped])))
|
@@ -164,7 +165,7 @@ module RubyLsp
|
|
164
165
|
end
|
165
166
|
end
|
166
167
|
|
167
|
-
|
168
|
+
#: ((Result | Error | Notification | Request) message) -> void
|
168
169
|
def send_message(message)
|
169
170
|
# When we're shutting down the server, there's a small race condition between closing the thread queues and
|
170
171
|
# finishing remaining requests. We may close the queue in the middle of processing a request, which will then fail
|
@@ -175,12 +176,12 @@ module RubyLsp
|
|
175
176
|
@current_request_id += 1 if message.is_a?(Request)
|
176
177
|
end
|
177
178
|
|
178
|
-
|
179
|
+
#: (Integer id) -> void
|
179
180
|
def send_empty_response(id)
|
180
181
|
send_message(Result.new(id: id, response: nil))
|
181
182
|
end
|
182
183
|
|
183
|
-
|
184
|
+
#: (String message, ?type: Integer) -> void
|
184
185
|
def send_log_message(message, type: Constant::MessageType::LOG)
|
185
186
|
send_message(Notification.window_log_message(message, type: Constant::MessageType::LOG))
|
186
187
|
end
|
@@ -5,16 +5,14 @@ module RubyLsp
|
|
5
5
|
# This class stores all client capabilities that the Ruby LSP and its add-ons depend on to ensure that we're
|
6
6
|
# not enabling functionality unsupported by the editor connecting to the server
|
7
7
|
class ClientCapabilities
|
8
|
-
|
9
|
-
|
10
|
-
sig { returns(T::Boolean) }
|
8
|
+
#: bool
|
11
9
|
attr_reader :supports_watching_files,
|
12
10
|
:supports_request_delegation,
|
13
11
|
:window_show_message_supports_extra_properties,
|
14
12
|
:supports_progress,
|
15
13
|
:supports_diagnostic_refresh
|
16
14
|
|
17
|
-
|
15
|
+
#: -> void
|
18
16
|
def initialize
|
19
17
|
# The editor supports watching files. This requires two capabilities: dynamic registration and relative pattern
|
20
18
|
# support
|
@@ -38,7 +36,7 @@ module RubyLsp
|
|
38
36
|
@supports_diagnostic_refresh = T.let(false, T::Boolean)
|
39
37
|
end
|
40
38
|
|
41
|
-
|
39
|
+
#: (Hash[Symbol, untyped] capabilities) -> void
|
42
40
|
def apply_client_capabilities(capabilities)
|
43
41
|
workspace_capabilities = capabilities[:workspace] || {}
|
44
42
|
|
@@ -65,7 +63,7 @@ module RubyLsp
|
|
65
63
|
@supports_diagnostic_refresh = workspace_capabilities.dig(:diagnostics, :refreshSupport) || false
|
66
64
|
end
|
67
65
|
|
68
|
-
|
66
|
+
#: -> bool
|
69
67
|
def supports_rename?
|
70
68
|
@supported_resource_operations.include?("rename")
|
71
69
|
end
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -25,28 +25,28 @@ module RubyLsp
|
|
25
25
|
|
26
26
|
abstract!
|
27
27
|
|
28
|
-
|
28
|
+
#: ParseResultType
|
29
29
|
attr_reader :parse_result
|
30
30
|
|
31
|
-
|
31
|
+
#: String
|
32
32
|
attr_reader :source
|
33
33
|
|
34
|
-
|
34
|
+
#: Integer
|
35
35
|
attr_reader :version
|
36
36
|
|
37
|
-
|
37
|
+
#: URI::Generic
|
38
38
|
attr_reader :uri
|
39
39
|
|
40
|
-
|
40
|
+
#: Encoding
|
41
41
|
attr_reader :encoding
|
42
42
|
|
43
|
-
|
43
|
+
#: Edit?
|
44
44
|
attr_reader :last_edit
|
45
45
|
|
46
|
-
|
46
|
+
#: (Interface::SemanticTokens | Object)
|
47
47
|
attr_accessor :semantic_tokens
|
48
48
|
|
49
|
-
|
49
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
50
50
|
def initialize(source:, version:, uri:, global_state:)
|
51
51
|
@source = source
|
52
52
|
@version = version
|
@@ -61,7 +61,7 @@ module RubyLsp
|
|
61
61
|
parse!
|
62
62
|
end
|
63
63
|
|
64
|
-
|
64
|
+
#: (Document[untyped] other) -> bool
|
65
65
|
def ==(other)
|
66
66
|
self.class == other.class && uri == other.uri && @source == other.source
|
67
67
|
end
|
@@ -69,13 +69,7 @@ module RubyLsp
|
|
69
69
|
sig { abstract.returns(LanguageId) }
|
70
70
|
def language_id; end
|
71
71
|
|
72
|
-
|
73
|
-
type_parameters(:T)
|
74
|
-
.params(
|
75
|
-
request_name: String,
|
76
|
-
block: T.proc.params(document: Document[ParseResultType]).returns(T.type_parameter(:T)),
|
77
|
-
).returns(T.type_parameter(:T))
|
78
|
-
end
|
72
|
+
#: [T] (String request_name) { (Document[ParseResultType] document) -> T } -> T
|
79
73
|
def cache_fetch(request_name, &block)
|
80
74
|
cached = @cache[request_name]
|
81
75
|
return cached if cached != EMPTY_CACHE
|
@@ -85,17 +79,17 @@ module RubyLsp
|
|
85
79
|
result
|
86
80
|
end
|
87
81
|
|
88
|
-
|
82
|
+
#: [T] (String request_name, T value) -> T
|
89
83
|
def cache_set(request_name, value)
|
90
84
|
@cache[request_name] = value
|
91
85
|
end
|
92
86
|
|
93
|
-
|
87
|
+
#: (String request_name) -> untyped
|
94
88
|
def cache_get(request_name)
|
95
89
|
@cache[request_name]
|
96
90
|
end
|
97
91
|
|
98
|
-
|
92
|
+
#: (Array[Hash[Symbol, untyped]] edits, version: Integer) -> void
|
99
93
|
def push_edits(edits, version:)
|
100
94
|
edits.each do |edit|
|
101
95
|
range = edit[:range]
|
@@ -132,17 +126,12 @@ module RubyLsp
|
|
132
126
|
sig { abstract.returns(T::Boolean) }
|
133
127
|
def syntax_error?; end
|
134
128
|
|
135
|
-
|
129
|
+
#: -> bool
|
136
130
|
def past_expensive_limit?
|
137
131
|
@source.length > MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES
|
138
132
|
end
|
139
133
|
|
140
|
-
|
141
|
-
params(
|
142
|
-
start_pos: T::Hash[Symbol, T.untyped],
|
143
|
-
end_pos: T.nilable(T::Hash[Symbol, T.untyped]),
|
144
|
-
).returns([Integer, T.nilable(Integer)])
|
145
|
-
end
|
134
|
+
#: (Hash[Symbol, untyped] start_pos, ?Hash[Symbol, untyped]? end_pos) -> [Integer, Integer?]
|
146
135
|
def find_index_by_position(start_pos, end_pos = nil)
|
147
136
|
@global_state.synchronize do
|
148
137
|
scanner = create_scanner
|
@@ -154,7 +143,7 @@ module RubyLsp
|
|
154
143
|
|
155
144
|
private
|
156
145
|
|
157
|
-
|
146
|
+
#: -> Scanner
|
158
147
|
def create_scanner
|
159
148
|
Scanner.new(@source, @encoding)
|
160
149
|
end
|
@@ -165,10 +154,10 @@ module RubyLsp
|
|
165
154
|
|
166
155
|
abstract!
|
167
156
|
|
168
|
-
|
157
|
+
#: Hash[Symbol, untyped]
|
169
158
|
attr_reader :range
|
170
159
|
|
171
|
-
|
160
|
+
#: (Hash[Symbol, untyped] range) -> void
|
172
161
|
def initialize(range)
|
173
162
|
@range = range
|
174
163
|
end
|
@@ -185,7 +174,7 @@ module RubyLsp
|
|
185
174
|
# After character 0xFFFF, UTF-16 considers characters to have length 2 and we have to account for that
|
186
175
|
SURROGATE_PAIR_START = T.let(0xFFFF, Integer)
|
187
176
|
|
188
|
-
|
177
|
+
#: (String source, Encoding encoding) -> void
|
189
178
|
def initialize(source, encoding)
|
190
179
|
@current_line = T.let(0, Integer)
|
191
180
|
@pos = T.let(0, Integer)
|
@@ -194,7 +183,7 @@ module RubyLsp
|
|
194
183
|
end
|
195
184
|
|
196
185
|
# Finds the character index inside the source string for a given line and column
|
197
|
-
|
186
|
+
#: (Hash[Symbol, untyped] position) -> Integer
|
198
187
|
def find_char_position(position)
|
199
188
|
# Find the character index for the beginning of the requested line
|
200
189
|
until @current_line == position[:line]
|
@@ -224,7 +213,7 @@ module RubyLsp
|
|
224
213
|
|
225
214
|
# Subtract 1 for each character after 0xFFFF in the current line from the column position, so that we hit the
|
226
215
|
# right character in the UTF-8 representation
|
227
|
-
|
216
|
+
#: (Integer current_position, Integer requested_position) -> Integer
|
228
217
|
def utf_16_character_position_correction(current_position, requested_position)
|
229
218
|
utf16_unicode_correction = 0
|
230
219
|
|