ruby-lsp 0.23.16 → 0.23.18
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/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +16 -19
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +0 -3
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +9 -19
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +37 -68
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +6 -9
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +1 -10
- data/lib/ruby_indexer/lib/ruby_indexer/visibility_scope.rb +4 -4
- data/lib/ruby_indexer/test/index_test.rb +7 -0
- data/lib/ruby_indexer/test/method_test.rb +7 -7
- data/lib/ruby_indexer/test/prefix_tree_test.rb +8 -8
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +4 -3
- data/lib/ruby_indexer/test/test_case.rb +7 -1
- data/lib/ruby_lsp/client_capabilities.rb +6 -1
- data/lib/ruby_lsp/document.rb +7 -11
- data/lib/ruby_lsp/erb_document.rb +3 -6
- data/lib/ruby_lsp/internal.rb +6 -1
- data/lib/ruby_lsp/listeners/completion.rb +8 -8
- data/lib/ruby_lsp/listeners/definition.rb +7 -7
- data/lib/ruby_lsp/listeners/document_link.rb +7 -10
- data/lib/ruby_lsp/listeners/hover.rb +18 -14
- data/lib/ruby_lsp/listeners/signature_help.rb +2 -2
- data/lib/ruby_lsp/listeners/spec_style.rb +11 -11
- data/lib/ruby_lsp/listeners/test_discovery.rb +1 -1
- data/lib/ruby_lsp/listeners/test_style.rb +10 -5
- data/lib/ruby_lsp/rbs_document.rb +3 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +44 -39
- data/lib/ruby_lsp/requests/code_lens.rb +16 -4
- data/lib/ruby_lsp/requests/completion.rb +2 -2
- data/lib/ruby_lsp/requests/definition.rb +3 -6
- data/lib/ruby_lsp/requests/document_highlight.rb +1 -1
- 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 +0 -2
- data/lib/ruby_lsp/requests/hover.rb +2 -5
- data/lib/ruby_lsp/requests/inlay_hints.rb +1 -1
- data/lib/ruby_lsp/requests/references.rb +1 -16
- data/lib/ruby_lsp/requests/rename.rb +1 -4
- data/lib/ruby_lsp/requests/request.rb +3 -2
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/requests/support/annotation.rb +1 -1
- data/lib/ruby_lsp/requests/support/common.rb +0 -5
- data/lib/ruby_lsp/requests/support/test_item.rb +7 -1
- 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 +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +1 -2
- 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 +3 -36
- data/lib/ruby_lsp/server.rb +76 -22
- data/lib/ruby_lsp/store.rb +6 -6
- data/lib/ruby_lsp/test_reporters/lsp_reporter.rb +47 -10
- data/lib/ruby_lsp/test_reporters/minitest_reporter.rb +6 -23
- data/lib/ruby_lsp/test_reporters/test_unit_reporter.rb +5 -17
- data/lib/ruby_lsp/utils.rb +43 -0
- metadata +1 -1
@@ -2,11 +2,8 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
+
#: [ParseResultType = Prism::ParseResult]
|
5
6
|
class RubyDocument < Document
|
6
|
-
extend T::Generic
|
7
|
-
|
8
|
-
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
9
|
-
|
10
7
|
METHODS_THAT_CHANGE_DECLARATIONS = [
|
11
8
|
:private_constant,
|
12
9
|
:attr_reader,
|
@@ -23,16 +20,6 @@ module RubyLsp
|
|
23
20
|
:private_class_method,
|
24
21
|
].freeze
|
25
22
|
|
26
|
-
class SorbetLevel < T::Enum
|
27
|
-
enums do
|
28
|
-
None = new("none")
|
29
|
-
Ignore = new("ignore")
|
30
|
-
False = new("false")
|
31
|
-
True = new("true")
|
32
|
-
Strict = new("strict")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
23
|
class << self
|
37
24
|
#: (Prism::Node node, Integer char_position, code_units_cache: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache), ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
38
25
|
def locate(node, char_position, code_units_cache:, node_types: [])
|
@@ -154,29 +141,9 @@ module RubyLsp
|
|
154
141
|
end
|
155
142
|
|
156
143
|
# @override
|
157
|
-
#: ->
|
144
|
+
#: -> Symbol
|
158
145
|
def language_id
|
159
|
-
|
160
|
-
end
|
161
|
-
|
162
|
-
#: -> SorbetLevel
|
163
|
-
def sorbet_level
|
164
|
-
sigil = parse_result.magic_comments.find do |comment|
|
165
|
-
comment.key == "typed"
|
166
|
-
end&.value
|
167
|
-
|
168
|
-
case sigil
|
169
|
-
when "ignore"
|
170
|
-
SorbetLevel::Ignore
|
171
|
-
when "false"
|
172
|
-
SorbetLevel::False
|
173
|
-
when "true"
|
174
|
-
SorbetLevel::True
|
175
|
-
when "strict", "strong"
|
176
|
-
SorbetLevel::Strict
|
177
|
-
else
|
178
|
-
SorbetLevel::None
|
179
|
-
end
|
146
|
+
:ruby
|
180
147
|
end
|
181
148
|
|
182
149
|
#: (Hash[Symbol, untyped] range, ?node_types: Array[singleton(Prism::Node)]) -> Prism::Node?
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -32,6 +32,8 @@ module RubyLsp
|
|
32
32
|
text_document_document_link(message)
|
33
33
|
when "textDocument/codeLens"
|
34
34
|
text_document_code_lens(message)
|
35
|
+
when "codeLens/resolve"
|
36
|
+
code_lens_resolve(message)
|
35
37
|
when "textDocument/semanticTokens/full"
|
36
38
|
text_document_semantic_tokens_full(message)
|
37
39
|
when "textDocument/semanticTokens/full/delta"
|
@@ -242,7 +244,9 @@ module RubyLsp
|
|
242
244
|
|
243
245
|
bundle_env_path = File.join(".ruby-lsp", "bundle_env")
|
244
246
|
bundle_env = if File.exist?(bundle_env_path)
|
245
|
-
env = File.readlines(bundle_env_path).to_h
|
247
|
+
env = File.readlines(bundle_env_path).to_h do |line|
|
248
|
+
line.chomp.split("=", 2) #: as [String, String]
|
249
|
+
end
|
246
250
|
FileUtils.rm(bundle_env_path)
|
247
251
|
env
|
248
252
|
end
|
@@ -385,11 +389,11 @@ module RubyLsp
|
|
385
389
|
text_document = message.dig(:params, :textDocument)
|
386
390
|
language_id = case text_document[:languageId]
|
387
391
|
when "erb", "eruby"
|
388
|
-
|
392
|
+
:erb
|
389
393
|
when "rbs"
|
390
|
-
|
394
|
+
:rbs
|
391
395
|
else
|
392
|
-
|
396
|
+
:ruby
|
393
397
|
end
|
394
398
|
|
395
399
|
document = @store.set(
|
@@ -489,13 +493,16 @@ module RubyLsp
|
|
489
493
|
folding_range = Requests::FoldingRanges.new(parse_result.comments, dispatcher)
|
490
494
|
document_symbol = Requests::DocumentSymbol.new(uri, dispatcher)
|
491
495
|
document_link = Requests::DocumentLink.new(uri, parse_result.comments, dispatcher)
|
492
|
-
code_lens = Requests::CodeLens.new(@global_state, uri, dispatcher)
|
493
496
|
inlay_hint = Requests::InlayHints.new(
|
494
497
|
document,
|
495
498
|
@store.features_configuration.dig(:inlayHint), #: as !nil
|
496
499
|
dispatcher,
|
497
500
|
)
|
498
501
|
|
502
|
+
# The code lens listener requires the index to be populated, so the DeclarationListener must be inserted first in
|
503
|
+
# the dispatcher's state
|
504
|
+
code_lens = nil #: Requests::CodeLens?
|
505
|
+
|
499
506
|
if document.is_a?(RubyDocument) && document.should_index?
|
500
507
|
# Re-index the file as it is modified. This mode of indexing updates entries only. Require path trees are only
|
501
508
|
# updated on save
|
@@ -505,10 +512,12 @@ module RubyLsp
|
|
505
512
|
@global_state.index.handle_change(uri) do |index|
|
506
513
|
index.delete(uri, skip_require_paths_tree: true)
|
507
514
|
RubyIndexer::DeclarationListener.new(index, dispatcher, parse_result, uri, collect_comments: true)
|
515
|
+
code_lens = Requests::CodeLens.new(@global_state, uri, dispatcher)
|
508
516
|
dispatcher.dispatch(parse_result.value)
|
509
517
|
end
|
510
518
|
end
|
511
519
|
else
|
520
|
+
code_lens = Requests::CodeLens.new(@global_state, uri, dispatcher)
|
512
521
|
dispatcher.dispatch(parse_result.value)
|
513
522
|
end
|
514
523
|
|
@@ -517,7 +526,11 @@ module RubyLsp
|
|
517
526
|
document.cache_set("textDocument/foldingRange", folding_range.perform)
|
518
527
|
document.cache_set("textDocument/documentSymbol", document_symbol.perform)
|
519
528
|
document.cache_set("textDocument/documentLink", document_link.perform)
|
520
|
-
document.cache_set(
|
529
|
+
document.cache_set(
|
530
|
+
"textDocument/codeLens",
|
531
|
+
code_lens #: as !nil
|
532
|
+
.perform,
|
533
|
+
)
|
521
534
|
document.cache_set("textDocument/inlayHint", inlay_hint.perform)
|
522
535
|
|
523
536
|
send_message(Result.new(id: message[:id], response: document.cache_get(message[:method])))
|
@@ -672,6 +685,10 @@ module RubyLsp
|
|
672
685
|
"Formatting error: #{error.message}",
|
673
686
|
type: Constant::MessageType::ERROR,
|
674
687
|
))
|
688
|
+
send_message(Notification.window_log_message(
|
689
|
+
"Formatting failed with\r\n: #{error.full_message}",
|
690
|
+
type: Constant::MessageType::ERROR,
|
691
|
+
))
|
675
692
|
send_empty_response(message[:id])
|
676
693
|
end
|
677
694
|
|
@@ -795,12 +812,16 @@ module RubyLsp
|
|
795
812
|
)
|
796
813
|
end
|
797
814
|
|
798
|
-
#: (Document[untyped] document) ->
|
815
|
+
#: (Document[untyped] document) -> SorbetLevel
|
799
816
|
def sorbet_level(document)
|
800
|
-
return
|
801
|
-
return
|
817
|
+
return SorbetLevel.ignore unless document.is_a?(RubyDocument)
|
818
|
+
return SorbetLevel.ignore unless @global_state.has_type_checker
|
819
|
+
|
820
|
+
sigil = document.parse_result.magic_comments.find do |comment|
|
821
|
+
comment.key == "typed"
|
822
|
+
end&.value
|
802
823
|
|
803
|
-
|
824
|
+
SorbetLevel.new(sigil)
|
804
825
|
end
|
805
826
|
|
806
827
|
#: (Hash[Symbol, untyped] message) -> void
|
@@ -871,17 +892,9 @@ module RubyLsp
|
|
871
892
|
end
|
872
893
|
|
873
894
|
result = Requests::CodeActionResolve.new(document, @global_state, params).perform
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
fail_request_and_notify(message[:id], "Invalid selection for extract variable refactor")
|
878
|
-
when Requests::CodeActionResolve::Error::InvalidTargetRange
|
879
|
-
fail_request_and_notify(message[:id], "Couldn't find an appropriate location to place extracted refactor")
|
880
|
-
when Requests::CodeActionResolve::Error::UnknownCodeAction
|
881
|
-
fail_request_and_notify(message[:id], "Unknown code action")
|
882
|
-
else
|
883
|
-
send_message(Result.new(id: message[:id], response: result))
|
884
|
-
end
|
895
|
+
send_message(Result.new(id: message[:id], response: result))
|
896
|
+
rescue Requests::CodeActionResolve::CodeActionError => e
|
897
|
+
fail_request_and_notify(message[:id], e.message)
|
885
898
|
end
|
886
899
|
|
887
900
|
#: (Hash[Symbol, untyped] message) -> void
|
@@ -921,6 +934,10 @@ module RubyLsp
|
|
921
934
|
"Error running diagnostics: #{error.message}",
|
922
935
|
type: Constant::MessageType::ERROR,
|
923
936
|
))
|
937
|
+
send_message(Notification.window_log_message(
|
938
|
+
"Diagnostics failed with\r\n: #{error.full_message}",
|
939
|
+
type: Constant::MessageType::ERROR,
|
940
|
+
))
|
924
941
|
send_empty_response(message[:id])
|
925
942
|
end
|
926
943
|
|
@@ -1109,7 +1126,7 @@ module RubyLsp
|
|
1109
1126
|
# Clear all document caches for pull diagnostics
|
1110
1127
|
@global_state.synchronize do
|
1111
1128
|
@store.each do |_uri, document|
|
1112
|
-
document.
|
1129
|
+
document.clear_cache("textDocument/diagnostic")
|
1113
1130
|
end
|
1114
1131
|
end
|
1115
1132
|
|
@@ -1265,9 +1282,25 @@ module RubyLsp
|
|
1265
1282
|
# allocations and garbage collections are faster
|
1266
1283
|
GC.compact unless @test_mode
|
1267
1284
|
|
1285
|
+
@global_state.synchronize do
|
1286
|
+
# If we linearize ancestors while the index is not fully populated, we may end up caching incorrect results
|
1287
|
+
# that were missing namespaces. After indexing is complete, we need to clear the ancestors cache and start
|
1288
|
+
# again
|
1289
|
+
@global_state.index.clear_ancestors
|
1290
|
+
|
1291
|
+
# The results for code lens depend on ancestor linearization, so we need to clear any previously computed
|
1292
|
+
# responses
|
1293
|
+
@store.each { |_uri, document| document.clear_cache("textDocument/codeLens") }
|
1294
|
+
end
|
1295
|
+
|
1268
1296
|
# Always end the progress notification even if indexing failed or else it never goes away and the user has no
|
1269
1297
|
# way of dismissing it
|
1270
1298
|
end_progress("indexing-progress")
|
1299
|
+
|
1300
|
+
# Request a code lens refresh if we populated them before all test parent classes were indexed
|
1301
|
+
if @global_state.client_capabilities.supports_code_lens_refresh
|
1302
|
+
send_message(Request.new(id: @current_request_id, method: "workspace/codeLens/refresh", params: nil))
|
1303
|
+
end
|
1271
1304
|
end
|
1272
1305
|
end
|
1273
1306
|
|
@@ -1482,5 +1515,26 @@ module RubyLsp
|
|
1482
1515
|
},
|
1483
1516
|
))
|
1484
1517
|
end
|
1518
|
+
|
1519
|
+
#: (Hash[Symbol, untyped] message) -> void
|
1520
|
+
def code_lens_resolve(message)
|
1521
|
+
code_lens = message[:params]
|
1522
|
+
args = code_lens.dig(:data, :arguments)
|
1523
|
+
|
1524
|
+
case code_lens.dig(:data, :kind)
|
1525
|
+
when "run_test"
|
1526
|
+
code_lens[:command] = Interface::Command.new(title: "▶ Run", command: "rubyLsp.runTest", arguments: args)
|
1527
|
+
when "run_test_in_terminal"
|
1528
|
+
code_lens[:command] =
|
1529
|
+
Interface::Command.new(title: "▶ Run in terminal", command: "rubyLsp.runTestInTerminal", arguments: args)
|
1530
|
+
when "debug_test"
|
1531
|
+
code_lens[:command] = Interface::Command.new(title: "⚙ Debug", command: "rubyLsp.debugTest", arguments: args)
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
send_message(Result.new(
|
1535
|
+
id: message[:id],
|
1536
|
+
response: code_lens,
|
1537
|
+
))
|
1538
|
+
end
|
1485
1539
|
end
|
1486
1540
|
end
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -38,11 +38,11 @@ module RubyLsp
|
|
38
38
|
ext = File.extname(path)
|
39
39
|
language_id = case ext
|
40
40
|
when ".erb", ".rhtml"
|
41
|
-
|
41
|
+
:erb
|
42
42
|
when ".rbs"
|
43
|
-
|
43
|
+
:rbs
|
44
44
|
else
|
45
|
-
|
45
|
+
:ruby
|
46
46
|
end
|
47
47
|
|
48
48
|
set(uri: uri, source: File.binread(path), version: 0, language_id: language_id)
|
@@ -51,12 +51,12 @@ module RubyLsp
|
|
51
51
|
raise NonExistingDocumentError, uri.to_s
|
52
52
|
end
|
53
53
|
|
54
|
-
#: (uri: URI::Generic, source: String, version: Integer, language_id:
|
54
|
+
#: (uri: URI::Generic, source: String, version: Integer, language_id: Symbol) -> Document[untyped]
|
55
55
|
def set(uri:, source:, version:, language_id:)
|
56
56
|
@state[uri.to_s] = case language_id
|
57
|
-
when
|
57
|
+
when :erb
|
58
58
|
ERBDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
|
59
|
-
when
|
59
|
+
when :rbs
|
60
60
|
RBSDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
|
61
61
|
else
|
62
62
|
RubyDocument.new(source: source, version: version, uri: uri, global_state: @global_state)
|
@@ -4,21 +4,40 @@
|
|
4
4
|
require "json"
|
5
5
|
require "socket"
|
6
6
|
require "singleton"
|
7
|
+
require "tmpdir"
|
7
8
|
|
8
9
|
module RubyLsp
|
9
10
|
class LspReporter
|
10
11
|
include Singleton
|
11
12
|
|
13
|
+
#: bool
|
14
|
+
attr_reader :invoked_shutdown
|
15
|
+
|
12
16
|
#: -> void
|
13
17
|
def initialize
|
18
|
+
dir_path = File.join(Dir.tmpdir, "ruby-lsp")
|
19
|
+
FileUtils.mkdir_p(dir_path)
|
20
|
+
|
21
|
+
port_path = File.join(dir_path, "test_reporter_port")
|
14
22
|
port = ENV["RUBY_LSP_REPORTER_PORT"]
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
23
|
+
|
24
|
+
@io = begin
|
25
|
+
# The environment variable is only used for tests. The extension always writes to the temporary file
|
26
|
+
if port
|
27
|
+
TCPSocket.new("localhost", port)
|
28
|
+
elsif File.exist?(port_path)
|
29
|
+
TCPSocket.new("localhost", File.read(port_path))
|
30
|
+
else
|
31
|
+
# For tests that don't spawn the TCP server
|
32
|
+
require "stringio"
|
33
|
+
StringIO.new
|
34
|
+
end
|
35
|
+
rescue
|
19
36
|
require "stringio"
|
20
37
|
StringIO.new
|
21
38
|
end #: IO | StringIO
|
39
|
+
|
40
|
+
@invoked_shutdown = false #: bool
|
22
41
|
end
|
23
42
|
|
24
43
|
#: -> void
|
@@ -34,13 +53,15 @@ module RubyLsp
|
|
34
53
|
# reporter, use `shutdown` instead
|
35
54
|
#: -> void
|
36
55
|
def internal_shutdown
|
56
|
+
@invoked_shutdown = true
|
57
|
+
|
37
58
|
send_message("finish")
|
38
59
|
@io.close
|
39
60
|
end
|
40
61
|
|
41
|
-
#: (id: String, uri: URI::Generic) -> void
|
42
|
-
def start_test(id:, uri:)
|
43
|
-
send_message("start", id: id, uri: uri.to_s)
|
62
|
+
#: (id: String, uri: URI::Generic, ?line: Integer?) -> void
|
63
|
+
def start_test(id:, uri:, line: nil)
|
64
|
+
send_message("start", id: id, uri: uri.to_s, line: line)
|
44
65
|
end
|
45
66
|
|
46
67
|
#: (id: String, uri: URI::Generic) -> void
|
@@ -63,6 +84,17 @@ module RubyLsp
|
|
63
84
|
send_message("error", id: id, message: message, uri: uri.to_s)
|
64
85
|
end
|
65
86
|
|
87
|
+
#: (Method | UnboundMethod) -> [URI::Generic, Integer?]?
|
88
|
+
def uri_and_line_for(method_object)
|
89
|
+
file_path, line = method_object.source_location
|
90
|
+
return unless file_path
|
91
|
+
return if file_path.start_with?("(eval at ")
|
92
|
+
|
93
|
+
uri = URI::Generic.from_path(path: File.expand_path(file_path))
|
94
|
+
zero_based_line = line ? line - 1 : nil
|
95
|
+
[uri, zero_based_line]
|
96
|
+
end
|
97
|
+
|
66
98
|
# Gather the results returned by Coverage.result and format like the VS Code test explorer expects
|
67
99
|
#
|
68
100
|
# Coverage result format:
|
@@ -94,10 +126,9 @@ module RubyLsp
|
|
94
126
|
def gather_coverage_results
|
95
127
|
# Ignore coverage results inside dependencies
|
96
128
|
bundle_path = Bundler.bundle_path.to_s
|
97
|
-
default_gems_path = File.dirname(RbConfig::CONFIG["rubylibdir"])
|
98
129
|
|
99
130
|
result = Coverage.result.reject do |file_path, _coverage_info|
|
100
|
-
file_path.start_with?(bundle_path
|
131
|
+
file_path.start_with?(bundle_path) || !file_path.start_with?(Dir.pwd)
|
101
132
|
end
|
102
133
|
|
103
134
|
result.to_h do |file_path, coverage_info|
|
@@ -142,7 +173,7 @@ module RubyLsp
|
|
142
173
|
|
143
174
|
private
|
144
175
|
|
145
|
-
#: (
|
176
|
+
#: (String?, **untyped) -> void
|
146
177
|
def send_message(method_name, **params)
|
147
178
|
json_message = { method: method_name, params: params }.to_json
|
148
179
|
@io.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
@@ -161,4 +192,10 @@ if ENV["RUBY_LSP_TEST_RUNNER"] == "coverage"
|
|
161
192
|
File.write(File.join(".ruby-lsp", "coverage_result.json"), coverage_results.to_json)
|
162
193
|
RubyLsp::LspReporter.instance.internal_shutdown
|
163
194
|
end
|
195
|
+
elsif ENV["RUBY_LSP_TEST_RUNNER"] && ENV["RUBY_LSP_ENV"] != "test"
|
196
|
+
at_exit do
|
197
|
+
# If the test process crashed immediately without finishing the tests, we still need to tell the extension that the
|
198
|
+
# execution ended so that it can clean up
|
199
|
+
RubyLsp::LspReporter.instance.internal_shutdown unless RubyLsp::LspReporter.instance.invoked_shutdown
|
200
|
+
end
|
164
201
|
end
|
@@ -51,16 +51,19 @@ module RubyLsp
|
|
51
51
|
|
52
52
|
#: (singleton(Minitest::Test) test_class, String method_name) -> void
|
53
53
|
def prerecord(test_class, method_name)
|
54
|
-
uri =
|
54
|
+
uri, line = LspReporter.instance.uri_and_line_for(test_class.instance_method(method_name))
|
55
55
|
return unless uri
|
56
56
|
|
57
|
-
LspReporter.instance.start_test(id: "#{test_class.name}##{method_name}", uri: uri)
|
57
|
+
LspReporter.instance.start_test(id: "#{test_class.name}##{method_name}", uri: uri, line: line)
|
58
58
|
end
|
59
59
|
|
60
60
|
#: (Minitest::Result result) -> void
|
61
61
|
def record(result)
|
62
62
|
id = "#{result.klass}##{result.name}"
|
63
|
-
|
63
|
+
file_path, _line = result.source_location
|
64
|
+
return unless file_path
|
65
|
+
|
66
|
+
uri = URI::Generic.from_path(path: File.expand_path(file_path))
|
64
67
|
|
65
68
|
if result.error?
|
66
69
|
message = result.failures.first.message
|
@@ -79,26 +82,6 @@ module RubyLsp
|
|
79
82
|
def report
|
80
83
|
LspReporter.instance.shutdown
|
81
84
|
end
|
82
|
-
|
83
|
-
private
|
84
|
-
|
85
|
-
#: (Minitest::Result result) -> URI::Generic
|
86
|
-
def uri_from_result(result)
|
87
|
-
file = result.source_location[0]
|
88
|
-
absolute_path = File.expand_path(file, Dir.pwd)
|
89
|
-
URI::Generic.from_path(path: absolute_path)
|
90
|
-
end
|
91
|
-
|
92
|
-
#: (singleton(Minitest::Test) test_class, String method_name) -> URI::Generic?
|
93
|
-
def uri_from_test_class(test_class, method_name)
|
94
|
-
file, _line = test_class.instance_method(method_name).source_location
|
95
|
-
return unless file
|
96
|
-
|
97
|
-
return if file.start_with?("(eval at ") # test is dynamically defined
|
98
|
-
|
99
|
-
absolute_path = File.expand_path(file, Dir.pwd)
|
100
|
-
URI::Generic.from_path(path: absolute_path)
|
101
|
-
end
|
102
85
|
end
|
103
86
|
end
|
104
87
|
|
@@ -26,12 +26,12 @@ module RubyLsp
|
|
26
26
|
def test_started(test)
|
27
27
|
super
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
return unless @current_uri
|
29
|
+
uri, line = LspReporter.instance.uri_and_line_for(test.method(test.method_name))
|
30
|
+
return unless uri
|
32
31
|
|
33
|
-
@
|
34
|
-
|
32
|
+
@current_uri = uri
|
33
|
+
@current_test_id = "#{test.class.name}##{test.method_name}"
|
34
|
+
LspReporter.instance.start_test(id: @current_test_id, uri: @current_uri, line: line)
|
35
35
|
end
|
36
36
|
|
37
37
|
#: (::Test::Unit::TestCase test) -> void
|
@@ -62,18 +62,6 @@ module RubyLsp
|
|
62
62
|
LspReporter.instance.shutdown
|
63
63
|
end
|
64
64
|
|
65
|
-
#: (::Test::Unit::TestCase test) -> URI::Generic?
|
66
|
-
def uri_for_test(test)
|
67
|
-
location = test.method(test.method_name).source_location
|
68
|
-
return unless location
|
69
|
-
|
70
|
-
file, _line = location
|
71
|
-
return if file.start_with?("(eval at ")
|
72
|
-
|
73
|
-
absolute_path = File.expand_path(file, Dir.pwd)
|
74
|
-
URI::Generic.from_path(path: absolute_path)
|
75
|
-
end
|
76
|
-
|
77
65
|
#: -> void
|
78
66
|
def attach_to_mediator
|
79
67
|
# Events we care about
|
data/lib/ruby_lsp/utils.rb
CHANGED
@@ -259,4 +259,47 @@ module RubyLsp
|
|
259
259
|
@configuration[:enableAll] || @configuration[feature]
|
260
260
|
end
|
261
261
|
end
|
262
|
+
|
263
|
+
class SorbetLevel
|
264
|
+
class << self
|
265
|
+
#: -> SorbetLevel
|
266
|
+
def ignore
|
267
|
+
new("ignore")
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
#: (String?) -> void
|
272
|
+
def initialize(sigil)
|
273
|
+
@level = case sigil
|
274
|
+
when "ignore"
|
275
|
+
:ignore
|
276
|
+
when "false"
|
277
|
+
:false
|
278
|
+
when "true"
|
279
|
+
:true
|
280
|
+
when "strict", "strong"
|
281
|
+
:strict
|
282
|
+
else
|
283
|
+
:none
|
284
|
+
end #: Symbol
|
285
|
+
end
|
286
|
+
|
287
|
+
#: -> bool
|
288
|
+
def ignore? = @level == :ignore
|
289
|
+
|
290
|
+
#: -> bool
|
291
|
+
def false? = @level == :false
|
292
|
+
|
293
|
+
#: -> bool
|
294
|
+
def true? = @level == :true
|
295
|
+
|
296
|
+
#: -> bool
|
297
|
+
def strict? = @level == :strict
|
298
|
+
|
299
|
+
#: -> bool
|
300
|
+
def none? = @level == :none
|
301
|
+
|
302
|
+
#: -> bool
|
303
|
+
def true_or_higher? = @level == :true || @level == :strict
|
304
|
+
end
|
262
305
|
end
|