ruby-lsp 0.23.11 → 0.23.13
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_language_server_aliases.rb +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_register_with_handler_method.rb +3 -5
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +81 -115
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +117 -166
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +9 -7
- data/lib/ruby_indexer/lib/ruby_indexer/entry.rb +88 -200
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +56 -192
- data/lib/ruby_indexer/lib/ruby_indexer/location.rb +4 -27
- data/lib/ruby_indexer/lib/ruby_indexer/prefix_tree.rb +14 -16
- data/lib/ruby_indexer/lib/ruby_indexer/rbs_indexer.rb +22 -45
- data/lib/ruby_indexer/lib/ruby_indexer/reference_finder.rb +42 -60
- 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/configuration_test.rb +42 -3
- data/lib/ruby_indexer/test/method_test.rb +28 -2
- data/lib/ruby_indexer/test/rbs_indexer_test.rb +1 -1
- data/lib/ruby_lsp/addon.rb +44 -71
- data/lib/ruby_lsp/base_server.rb +29 -32
- data/lib/ruby_lsp/client_capabilities.rb +10 -12
- data/lib/ruby_lsp/document.rb +34 -45
- data/lib/ruby_lsp/erb_document.rb +24 -36
- data/lib/ruby_lsp/global_state.rb +51 -56
- data/lib/ruby_lsp/internal.rb +2 -0
- data/lib/ruby_lsp/listeners/code_lens.rb +81 -88
- data/lib/ruby_lsp/listeners/completion.rb +36 -55
- data/lib/ruby_lsp/listeners/definition.rb +37 -51
- data/lib/ruby_lsp/listeners/document_highlight.rb +123 -150
- data/lib/ruby_lsp/listeners/document_link.rb +43 -62
- data/lib/ruby_lsp/listeners/document_symbol.rb +35 -49
- data/lib/ruby_lsp/listeners/folding_ranges.rb +32 -39
- data/lib/ruby_lsp/listeners/hover.rb +81 -100
- data/lib/ruby_lsp/listeners/inlay_hints.rb +4 -11
- data/lib/ruby_lsp/listeners/semantic_highlighting.rb +42 -51
- data/lib/ruby_lsp/listeners/signature_help.rb +6 -25
- data/lib/ruby_lsp/listeners/spec_style.rb +155 -0
- data/lib/ruby_lsp/listeners/test_discovery.rb +89 -0
- data/lib/ruby_lsp/listeners/test_style.rb +160 -88
- data/lib/ruby_lsp/node_context.rb +12 -39
- data/lib/ruby_lsp/rbs_document.rb +8 -6
- data/lib/ruby_lsp/requests/code_action_resolve.rb +10 -10
- data/lib/ruby_lsp/requests/code_actions.rb +14 -26
- data/lib/ruby_lsp/requests/code_lens.rb +6 -17
- data/lib/ruby_lsp/requests/completion.rb +7 -20
- data/lib/ruby_lsp/requests/completion_resolve.rb +5 -5
- data/lib/ruby_lsp/requests/definition.rb +8 -17
- data/lib/ruby_lsp/requests/diagnostics.rb +8 -11
- data/lib/ruby_lsp/requests/discover_tests.rb +18 -5
- data/lib/ruby_lsp/requests/document_highlight.rb +5 -15
- data/lib/ruby_lsp/requests/document_link.rb +6 -17
- data/lib/ruby_lsp/requests/document_symbol.rb +5 -8
- data/lib/ruby_lsp/requests/folding_ranges.rb +7 -15
- data/lib/ruby_lsp/requests/formatting.rb +6 -9
- data/lib/ruby_lsp/requests/go_to_relevant_file.rb +87 -0
- data/lib/ruby_lsp/requests/hover.rb +8 -18
- data/lib/ruby_lsp/requests/inlay_hints.rb +6 -17
- data/lib/ruby_lsp/requests/on_type_formatting.rb +28 -38
- data/lib/ruby_lsp/requests/prepare_rename.rb +4 -9
- data/lib/ruby_lsp/requests/prepare_type_hierarchy.rb +4 -13
- data/lib/ruby_lsp/requests/range_formatting.rb +5 -6
- data/lib/ruby_lsp/requests/references.rb +6 -36
- data/lib/ruby_lsp/requests/rename.rb +11 -37
- data/lib/ruby_lsp/requests/request.rb +7 -19
- data/lib/ruby_lsp/requests/selection_ranges.rb +5 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +12 -31
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +5 -6
- data/lib/ruby_lsp/requests/signature_help.rb +8 -26
- data/lib/ruby_lsp/requests/support/annotation.rb +4 -10
- data/lib/ruby_lsp/requests/support/common.rb +13 -50
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +27 -35
- data/lib/ruby_lsp/requests/support/rubocop_formatter.rb +9 -12
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +22 -34
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -3
- data/lib/ruby_lsp/requests/support/sorbet.rb +29 -38
- data/lib/ruby_lsp/requests/support/source_uri.rb +16 -30
- data/lib/ruby_lsp/requests/support/syntax_tree_formatter.rb +12 -19
- data/lib/ruby_lsp/requests/support/test_item.rb +10 -14
- data/lib/ruby_lsp/requests/type_hierarchy_supertypes.rb +5 -6
- data/lib/ruby_lsp/requests/workspace_symbol.rb +4 -4
- data/lib/ruby_lsp/response_builders/collection_response_builder.rb +5 -5
- data/lib/ruby_lsp/response_builders/document_symbol.rb +10 -16
- data/lib/ruby_lsp/response_builders/hover.rb +10 -13
- data/lib/ruby_lsp/response_builders/response_builder.rb +1 -1
- data/lib/ruby_lsp/response_builders/semantic_highlighting.rb +59 -87
- data/lib/ruby_lsp/response_builders/signature_help.rb +5 -6
- data/lib/ruby_lsp/response_builders/test_collection.rb +6 -10
- data/lib/ruby_lsp/ruby_document.rb +22 -60
- data/lib/ruby_lsp/ruby_lsp_reporter_plugin.rb +109 -0
- data/lib/ruby_lsp/scope.rb +7 -11
- data/lib/ruby_lsp/server.rb +133 -74
- data/lib/ruby_lsp/setup_bundler.rb +58 -57
- data/lib/ruby_lsp/static_docs.rb +4 -7
- data/lib/ruby_lsp/store.rb +21 -40
- data/lib/ruby_lsp/test_helper.rb +3 -12
- data/lib/ruby_lsp/test_reporter.rb +207 -0
- data/lib/ruby_lsp/test_unit_test_runner.rb +98 -0
- data/lib/ruby_lsp/type_inferrer.rb +9 -13
- data/lib/ruby_lsp/utils.rb +37 -81
- metadata +9 -3
@@ -4,22 +4,21 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class SignatureHelp < ResponseBuilder
|
7
|
-
extend T::Sig
|
8
|
-
|
9
7
|
ResponseType = type_member { { fixed: T.nilable(Interface::SignatureHelp) } }
|
10
8
|
|
11
|
-
|
9
|
+
#: -> void
|
12
10
|
def initialize
|
13
11
|
super
|
14
|
-
@signature_help =
|
12
|
+
@signature_help = nil #: ResponseType
|
15
13
|
end
|
16
14
|
|
17
|
-
|
15
|
+
#: (ResponseType signature_help) -> void
|
18
16
|
def replace(signature_help)
|
19
17
|
@signature_help = signature_help
|
20
18
|
end
|
21
19
|
|
22
|
-
|
20
|
+
# @override
|
21
|
+
#: -> ResponseType
|
23
22
|
def response
|
24
23
|
@signature_help
|
25
24
|
end
|
@@ -4,32 +4,28 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module ResponseBuilders
|
6
6
|
class TestCollection < ResponseBuilder
|
7
|
-
class DuplicateIdError < StandardError; end
|
8
|
-
|
9
|
-
extend T::Sig
|
10
7
|
extend T::Generic
|
11
8
|
|
12
9
|
ResponseType = type_member { { fixed: Requests::Support::TestItem } }
|
13
10
|
|
14
|
-
|
11
|
+
#: -> void
|
15
12
|
def initialize
|
16
13
|
super
|
17
|
-
@items =
|
14
|
+
@items = {} #: Hash[String, ResponseType]
|
18
15
|
end
|
19
16
|
|
20
|
-
|
17
|
+
#: (ResponseType item) -> void
|
21
18
|
def add(item)
|
22
|
-
raise DuplicateIdError, "TestItem ID is already in use" if @items.key?(item.id)
|
23
|
-
|
24
19
|
@items[item.id] = item
|
25
20
|
end
|
26
21
|
|
27
|
-
|
22
|
+
#: (String id) -> ResponseType?
|
28
23
|
def [](id)
|
29
24
|
@items[id]
|
30
25
|
end
|
31
26
|
|
32
|
-
|
27
|
+
# @override
|
28
|
+
#: -> Array[ResponseType]
|
33
29
|
def response
|
34
30
|
@items.values
|
35
31
|
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
class RubyDocument < Document
|
6
|
-
extend T::Sig
|
7
6
|
extend T::Generic
|
8
7
|
|
9
8
|
ParseResultType = type_member { { fixed: Prism::ParseResult } }
|
@@ -35,38 +34,15 @@ module RubyLsp
|
|
35
34
|
end
|
36
35
|
|
37
36
|
class << self
|
38
|
-
|
39
|
-
|
40
|
-
sig do
|
41
|
-
params(
|
42
|
-
node: Prism::Node,
|
43
|
-
char_position: Integer,
|
44
|
-
code_units_cache: T.any(
|
45
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
46
|
-
Prism::CodeUnitsCache,
|
47
|
-
),
|
48
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
49
|
-
).returns(NodeContext)
|
50
|
-
end
|
37
|
+
#: (Prism::Node node, Integer char_position, code_units_cache: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache), ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
51
38
|
def locate(node, char_position, code_units_cache:, node_types: [])
|
52
|
-
queue =
|
39
|
+
queue = node.child_nodes.compact #: Array[Prism::Node?]
|
53
40
|
closest = node
|
54
|
-
parent =
|
55
|
-
nesting_nodes =
|
56
|
-
[],
|
57
|
-
T::Array[T.any(
|
58
|
-
Prism::ClassNode,
|
59
|
-
Prism::ModuleNode,
|
60
|
-
Prism::SingletonClassNode,
|
61
|
-
Prism::DefNode,
|
62
|
-
Prism::BlockNode,
|
63
|
-
Prism::LambdaNode,
|
64
|
-
Prism::ProgramNode,
|
65
|
-
)],
|
66
|
-
)
|
41
|
+
parent = nil #: Prism::Node?
|
42
|
+
nesting_nodes = [] #: Array[(Prism::ClassNode | Prism::ModuleNode | Prism::SingletonClassNode | Prism::DefNode | Prism::BlockNode | Prism::LambdaNode | Prism::ProgramNode)] # rubocop:disable Layout/LineLength
|
67
43
|
|
68
44
|
nesting_nodes << node if node.is_a?(Prism::ProgramNode)
|
69
|
-
call_node =
|
45
|
+
call_node = nil #: Prism::CallNode?
|
70
46
|
|
71
47
|
until queue.empty?
|
72
48
|
candidate = queue.shift
|
@@ -150,24 +126,18 @@ module RubyLsp
|
|
150
126
|
end
|
151
127
|
end
|
152
128
|
|
153
|
-
|
154
|
-
returns(T.any(
|
155
|
-
T.proc.params(arg0: Integer).returns(Integer),
|
156
|
-
Prism::CodeUnitsCache,
|
157
|
-
))
|
158
|
-
end
|
129
|
+
#: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
159
130
|
attr_reader :code_units_cache
|
160
131
|
|
161
|
-
|
132
|
+
#: (source: String, version: Integer, uri: URI::Generic, global_state: GlobalState) -> void
|
162
133
|
def initialize(source:, version:, uri:, global_state:)
|
163
134
|
super
|
164
|
-
@code_units_cache =
|
165
|
-
|
166
|
-
Prism::CodeUnitsCache,
|
167
|
-
))
|
135
|
+
@code_units_cache = @parse_result
|
136
|
+
.code_units_cache(@encoding) #: (^(Integer arg0) -> Integer | Prism::CodeUnitsCache)
|
168
137
|
end
|
169
138
|
|
170
|
-
|
139
|
+
# @override
|
140
|
+
#: -> bool
|
171
141
|
def parse!
|
172
142
|
return false unless @needs_parsing
|
173
143
|
|
@@ -177,17 +147,19 @@ module RubyLsp
|
|
177
147
|
true
|
178
148
|
end
|
179
149
|
|
180
|
-
|
150
|
+
# @override
|
151
|
+
#: -> bool
|
181
152
|
def syntax_error?
|
182
153
|
@parse_result.failure?
|
183
154
|
end
|
184
155
|
|
185
|
-
|
156
|
+
# @override
|
157
|
+
#: -> LanguageId
|
186
158
|
def language_id
|
187
159
|
LanguageId::Ruby
|
188
160
|
end
|
189
161
|
|
190
|
-
|
162
|
+
#: -> SorbetLevel
|
191
163
|
def sorbet_level
|
192
164
|
sigil = parse_result.magic_comments.find do |comment|
|
193
165
|
comment.key == "typed"
|
@@ -207,17 +179,12 @@ module RubyLsp
|
|
207
179
|
end
|
208
180
|
end
|
209
181
|
|
210
|
-
|
211
|
-
params(
|
212
|
-
range: T::Hash[Symbol, T.untyped],
|
213
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
214
|
-
).returns(T.nilable(Prism::Node))
|
215
|
-
end
|
182
|
+
#: (Hash[Symbol, untyped] range, ?node_types: Array[singleton(Prism::Node)]) -> Prism::Node?
|
216
183
|
def locate_first_within_range(range, node_types: [])
|
217
184
|
start_position, end_position = find_index_by_position(range[:start], range[:end])
|
218
185
|
|
219
186
|
desired_range = (start_position...end_position)
|
220
|
-
queue =
|
187
|
+
queue = @parse_result.value.child_nodes.compact #: Array[Prism::Node?]
|
221
188
|
|
222
189
|
until queue.empty?
|
223
190
|
candidate = queue.shift
|
@@ -240,12 +207,7 @@ module RubyLsp
|
|
240
207
|
end
|
241
208
|
end
|
242
209
|
|
243
|
-
|
244
|
-
params(
|
245
|
-
position: T::Hash[Symbol, T.untyped],
|
246
|
-
node_types: T::Array[T.class_of(Prism::Node)],
|
247
|
-
).returns(NodeContext)
|
248
|
-
end
|
210
|
+
#: (Hash[Symbol, untyped] position, ?node_types: Array[singleton(Prism::Node)]) -> NodeContext
|
249
211
|
def locate_node(position, node_types: [])
|
250
212
|
char_position, _ = find_index_by_position(position)
|
251
213
|
|
@@ -257,7 +219,7 @@ module RubyLsp
|
|
257
219
|
)
|
258
220
|
end
|
259
221
|
|
260
|
-
|
222
|
+
#: -> bool
|
261
223
|
def should_index?
|
262
224
|
# This method controls when we should index documents. If there's no recent edit and the document has just been
|
263
225
|
# opened, we need to index it
|
@@ -268,7 +230,7 @@ module RubyLsp
|
|
268
230
|
|
269
231
|
private
|
270
232
|
|
271
|
-
|
233
|
+
#: -> bool
|
272
234
|
def last_edit_may_change_declarations?
|
273
235
|
case @last_edit
|
274
236
|
when Delete
|
@@ -282,7 +244,7 @@ module RubyLsp
|
|
282
244
|
end
|
283
245
|
end
|
284
246
|
|
285
|
-
|
247
|
+
#: (Hash[Symbol, Integer] position) -> bool
|
286
248
|
def position_may_impact_declarations?(position)
|
287
249
|
node_context = locate_node(position)
|
288
250
|
node_at_edit = node_context.node
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
begin
|
5
|
+
require "minitest"
|
6
|
+
rescue LoadError
|
7
|
+
return
|
8
|
+
end
|
9
|
+
|
10
|
+
require_relative "test_reporter"
|
11
|
+
require "ruby_indexer/lib/ruby_indexer/uri"
|
12
|
+
|
13
|
+
module Minitest
|
14
|
+
module Reporters
|
15
|
+
class RubyLspReporter < ::Minitest::AbstractReporter
|
16
|
+
class << self
|
17
|
+
#: (Hash[untyped, untyped]) -> void
|
18
|
+
def minitest_plugin_init(_options)
|
19
|
+
Minitest.reporter.reporters << RubyLspReporter.new
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
#: (singleton(Minitest::Test) test_class, String method_name) -> void
|
24
|
+
def prerecord(test_class, method_name)
|
25
|
+
uri = uri_from_test_class(test_class, method_name)
|
26
|
+
return unless uri
|
27
|
+
|
28
|
+
RubyLsp::TestReporter.start_test(
|
29
|
+
id: "#{test_class.name}##{method_name}",
|
30
|
+
uri: uri,
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
#: (Minitest::Result result) -> void
|
35
|
+
def record(result)
|
36
|
+
if result.error?
|
37
|
+
record_error(result)
|
38
|
+
elsif result.passed?
|
39
|
+
record_pass(result)
|
40
|
+
elsif result.skipped?
|
41
|
+
record_skip(result)
|
42
|
+
elsif result.failure
|
43
|
+
record_fail(result)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
#: (Minitest::Result result) -> void
|
50
|
+
def record_pass(result)
|
51
|
+
RubyLsp::TestReporter.record_pass(
|
52
|
+
id: id_from_result(result),
|
53
|
+
uri: uri_from_result(result),
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
#: (Minitest::Result result) -> void
|
58
|
+
def record_skip(result)
|
59
|
+
RubyLsp::TestReporter.record_skip(
|
60
|
+
id: id_from_result(result),
|
61
|
+
uri: uri_from_result(result),
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
#: (Minitest::Result result) -> void
|
66
|
+
def record_fail(result)
|
67
|
+
RubyLsp::TestReporter.record_fail(
|
68
|
+
id: id_from_result(result),
|
69
|
+
message: result.failure.message,
|
70
|
+
uri: uri_from_result(result),
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
#: (Minitest::Result result) -> void
|
75
|
+
def record_error(result)
|
76
|
+
RubyLsp::TestReporter.record_error(
|
77
|
+
id: id_from_result(result),
|
78
|
+
uri: uri_from_result(result),
|
79
|
+
message: result.failures.first.message,
|
80
|
+
)
|
81
|
+
end
|
82
|
+
|
83
|
+
#: (Minitest::Result result) -> String
|
84
|
+
def id_from_result(result)
|
85
|
+
"#{result.klass}##{result.name}"
|
86
|
+
end
|
87
|
+
|
88
|
+
#: (Minitest::Result result) -> URI::Generic
|
89
|
+
def uri_from_result(result)
|
90
|
+
file = result.source_location[0]
|
91
|
+
absolute_path = File.expand_path(file, Dir.pwd)
|
92
|
+
URI::Generic.from_path(path: absolute_path)
|
93
|
+
end
|
94
|
+
|
95
|
+
#: (singleton(Minitest::Test) test_class, String method_name) -> URI::Generic?
|
96
|
+
def uri_from_test_class(test_class, method_name)
|
97
|
+
file, _line = test_class.instance_method(method_name).source_location
|
98
|
+
return unless file
|
99
|
+
|
100
|
+
return if file.start_with?("(eval at ") # test is dynamically defined
|
101
|
+
|
102
|
+
absolute_path = File.expand_path(file, Dir.pwd)
|
103
|
+
URI::Generic.from_path(path: absolute_path)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
Minitest.extensions << Minitest::Reporters::RubyLspReporter
|
data/lib/ruby_lsp/scope.rb
CHANGED
@@ -3,26 +3,24 @@
|
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
class Scope
|
6
|
-
|
7
|
-
|
8
|
-
sig { returns(T.nilable(Scope)) }
|
6
|
+
#: Scope?
|
9
7
|
attr_reader :parent
|
10
8
|
|
11
|
-
|
9
|
+
#: (?Scope? parent) -> void
|
12
10
|
def initialize(parent = nil)
|
13
11
|
@parent = parent
|
14
12
|
|
15
13
|
# A hash of name => type
|
16
|
-
@locals =
|
14
|
+
@locals = {} #: Hash[Symbol, Local]
|
17
15
|
end
|
18
16
|
|
19
17
|
# Add a new local to this scope. The types should only be `:parameter` or `:variable`
|
20
|
-
|
18
|
+
#: ((String | Symbol) name, Symbol type) -> void
|
21
19
|
def add(name, type)
|
22
20
|
@locals[name.to_sym] = Local.new(type)
|
23
21
|
end
|
24
22
|
|
25
|
-
|
23
|
+
#: ((String | Symbol) name) -> Local?
|
26
24
|
def lookup(name)
|
27
25
|
sym = name.to_sym
|
28
26
|
entry = @locals[sym]
|
@@ -33,12 +31,10 @@ module RubyLsp
|
|
33
31
|
end
|
34
32
|
|
35
33
|
class Local
|
36
|
-
|
37
|
-
|
38
|
-
sig { returns(Symbol) }
|
34
|
+
#: Symbol
|
39
35
|
attr_reader :type
|
40
36
|
|
41
|
-
|
37
|
+
#: (Symbol type) -> void
|
42
38
|
def initialize(type)
|
43
39
|
@type = type
|
44
40
|
end
|