ruby-lsp 0.23.24 → 0.24.1
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 +8 -2
- data/lib/ruby_indexer/test/instance_variables_test.rb +24 -0
- data/lib/ruby_indexer/test/method_test.rb +7 -0
- data/lib/ruby_lsp/document.rb +28 -13
- data/lib/ruby_lsp/erb_document.rb +8 -3
- data/lib/ruby_lsp/listeners/spec_style.rb +7 -8
- data/lib/ruby_lsp/listeners/test_discovery.rb +17 -12
- data/lib/ruby_lsp/listeners/test_style.rb +7 -8
- data/lib/ruby_lsp/requests/code_action_resolve.rb +2 -2
- data/lib/ruby_lsp/requests/completion.rb +1 -1
- data/lib/ruby_lsp/requests/definition.rb +1 -1
- data/lib/ruby_lsp/requests/discover_tests.rb +2 -2
- data/lib/ruby_lsp/requests/document_highlight.rb +1 -1
- data/lib/ruby_lsp/requests/hover.rb +1 -1
- data/lib/ruby_lsp/requests/prepare_rename.rb +1 -1
- data/lib/ruby_lsp/requests/references.rb +4 -4
- data/lib/ruby_lsp/requests/rename.rb +8 -6
- data/lib/ruby_lsp/requests/selection_ranges.rb +1 -1
- data/lib/ruby_lsp/requests/show_syntax_tree.rb +1 -1
- data/lib/ruby_lsp/requests/signature_help.rb +1 -1
- data/lib/ruby_lsp/ruby_document.rb +9 -4
- data/lib/ruby_lsp/server.rb +8 -20
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 981f87e306aa96edd6d2e04fc274d5da24ede96d3e3333bcfdeb63039e86c9ab
|
4
|
+
data.tar.gz: 5405216e985bed5ec6bce692baeeca9611980edc53fadf4655d00503488c277d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a749ebc7c81100f0c76431d68865960ad8aeb04ed3aad37dad18c008e885a50d224157a2fdcd44b15abc2d5d5f8d7a4a2345f187662707478dbc66d191c214a2
|
7
|
+
data.tar.gz: 19a288a8121a4cf86b5fd60b9c6d11c4fd3cb26330f7667ac59b4742dbe91328b9f742dca5fb371bb58ad565afb9ec58516eb6b68dd85e641a800f89a23f81e9
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.24.1
|
@@ -9,7 +9,7 @@ module RubyIndexer
|
|
9
9
|
#: Array[String]
|
10
10
|
attr_reader :indexing_errors
|
11
11
|
|
12
|
-
#: (Index index, Prism::Dispatcher dispatcher, Prism::ParseResult parse_result, URI::Generic uri, ?collect_comments: bool) -> void
|
12
|
+
#: (Index index, Prism::Dispatcher dispatcher, Prism::ParseLexResult | Prism::ParseResult parse_result, URI::Generic uri, ?collect_comments: bool) -> void
|
13
13
|
def initialize(index, dispatcher, parse_result, uri, collect_comments: false)
|
14
14
|
@index = index
|
15
15
|
@uri = uri
|
@@ -254,12 +254,15 @@ module RubyIndexer
|
|
254
254
|
case message
|
255
255
|
when :private_constant
|
256
256
|
handle_private_constant(node)
|
257
|
-
when :attr_reader
|
257
|
+
when :attr_reader
|
258
258
|
handle_attribute(node, reader: true, writer: false)
|
259
259
|
when :attr_writer
|
260
260
|
handle_attribute(node, reader: false, writer: true)
|
261
261
|
when :attr_accessor
|
262
262
|
handle_attribute(node, reader: true, writer: true)
|
263
|
+
when :attr
|
264
|
+
has_writer = node.arguments&.arguments&.last&.is_a?(Prism::TrueNode) || false
|
265
|
+
handle_attribute(node, reader: true, writer: has_writer)
|
263
266
|
when :alias_method
|
264
267
|
handle_alias_method(node)
|
265
268
|
when :include, :prepend, :extend
|
@@ -726,6 +729,9 @@ module RubyIndexer
|
|
726
729
|
comment = @comments_by_line[line]
|
727
730
|
break unless comment
|
728
731
|
|
732
|
+
# a trailing comment from a previous line is not a comment for this node
|
733
|
+
break if comment.trailing?
|
734
|
+
|
729
735
|
comment_content = comment.location.slice
|
730
736
|
|
731
737
|
# invalid encodings would raise an "invalid byte sequence" exception
|
@@ -236,5 +236,29 @@ module RubyIndexer
|
|
236
236
|
assert_instance_of(Entry::SingletonClass, owner)
|
237
237
|
assert_equal("Foo::<Class:Foo>", owner&.name)
|
238
238
|
end
|
239
|
+
|
240
|
+
def test_class_instance_variable_comments
|
241
|
+
index(<<~RUBY)
|
242
|
+
class Foo
|
243
|
+
# Documentation for @a
|
244
|
+
@a = "Hello" #: String
|
245
|
+
@b = "World" # trailing comment
|
246
|
+
@c = "!"
|
247
|
+
end
|
248
|
+
end
|
249
|
+
RUBY
|
250
|
+
|
251
|
+
assert_entry("@a", Entry::InstanceVariable, "/fake/path/foo.rb:2-4:2-6")
|
252
|
+
entry = @index["@a"]&.first #: as Entry::InstanceVariable
|
253
|
+
assert_equal("Documentation for @a", entry.comments)
|
254
|
+
|
255
|
+
assert_entry("@b", Entry::InstanceVariable, "/fake/path/foo.rb:3-4:3-6")
|
256
|
+
entry = @index["@b"]&.first #: as Entry::InstanceVariable
|
257
|
+
assert_empty(entry.comments)
|
258
|
+
|
259
|
+
assert_entry("@c", Entry::InstanceVariable, "/fake/path/foo.rb:4-4:4-6")
|
260
|
+
entry = @index["@c"]&.first #: as Entry::InstanceVariable
|
261
|
+
assert_empty(entry.comments)
|
262
|
+
end
|
239
263
|
end
|
240
264
|
end
|
@@ -954,10 +954,17 @@ module RubyIndexer
|
|
954
954
|
index(<<~RUBY)
|
955
955
|
class Foo
|
956
956
|
attr :bar
|
957
|
+
attr :baz, true
|
958
|
+
attr :qux, false
|
957
959
|
end
|
958
960
|
RUBY
|
959
961
|
|
960
962
|
assert_entry("bar", Entry::Accessor, "/fake/path/foo.rb:1-8:1-11")
|
963
|
+
assert_no_entry("bar=")
|
964
|
+
assert_entry("baz", Entry::Accessor, "/fake/path/foo.rb:2-8:2-11")
|
965
|
+
assert_entry("baz=", Entry::Accessor, "/fake/path/foo.rb:2-8:2-11")
|
966
|
+
assert_entry("qux", Entry::Accessor, "/fake/path/foo.rb:3-8:3-11")
|
967
|
+
assert_no_entry("qux=")
|
961
968
|
end
|
962
969
|
|
963
970
|
private
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -7,8 +7,6 @@ module RubyLsp
|
|
7
7
|
class Document
|
8
8
|
extend T::Generic
|
9
9
|
|
10
|
-
class LocationNotFoundError < StandardError; end
|
11
|
-
|
12
10
|
# This maximum number of characters for providing expensive features, like semantic highlighting and diagnostics.
|
13
11
|
# This is the same number used by the TypeScript extension in VS Code
|
14
12
|
MAXIMUM_CHARACTERS_FOR_EXPENSIVE_FEATURES = 100_000
|
@@ -176,7 +174,7 @@ module RubyLsp
|
|
176
174
|
def initialize(source, encoding)
|
177
175
|
@current_line = 0 #: Integer
|
178
176
|
@pos = 0 #: Integer
|
179
|
-
@
|
177
|
+
@bytes_or_codepoints = encoding == Encoding::UTF_8 ? source.bytes : source.codepoints #: Array[Integer]
|
180
178
|
@encoding = encoding
|
181
179
|
end
|
182
180
|
|
@@ -185,23 +183,40 @@ module RubyLsp
|
|
185
183
|
def find_char_position(position)
|
186
184
|
# Find the character index for the beginning of the requested line
|
187
185
|
until @current_line == position[:line]
|
188
|
-
until LINE_BREAK == @
|
189
|
-
|
186
|
+
@pos += 1 until LINE_BREAK == @bytes_or_codepoints[@pos]
|
187
|
+
@pos += 1
|
188
|
+
@current_line += 1
|
189
|
+
end
|
190
190
|
|
191
|
-
|
192
|
-
|
193
|
-
|
191
|
+
# For UTF-8, the code unit length is the same as bytes, but we want to return the character index
|
192
|
+
requested_position = if @encoding == Encoding::UTF_8
|
193
|
+
character_offset = 0
|
194
|
+
i = @pos
|
195
|
+
|
196
|
+
# Each group of bytes is a character. We advance based on the number of bytes to count how many full
|
197
|
+
# characters we have in the requested offset
|
198
|
+
while i < @pos + position[:character] && i < @bytes_or_codepoints.length
|
199
|
+
byte = @bytes_or_codepoints[i] #: as !nil
|
200
|
+
i += if byte < 0x80 # 1-byte character
|
201
|
+
1
|
202
|
+
elsif byte < 0xE0 # 2-byte character
|
203
|
+
2
|
204
|
+
elsif byte < 0xF0 # 3-byte character
|
205
|
+
3
|
206
|
+
else # 4-byte character
|
207
|
+
4
|
194
208
|
end
|
209
|
+
|
210
|
+
character_offset += 1
|
195
211
|
end
|
196
212
|
|
197
|
-
@pos
|
198
|
-
|
213
|
+
@pos + character_offset
|
214
|
+
else
|
215
|
+
@pos + position[:character]
|
199
216
|
end
|
200
217
|
|
201
218
|
# The final position is the beginning of the line plus the requested column. If the encoding is UTF-16, we also
|
202
219
|
# need to adjust for surrogate pairs
|
203
|
-
requested_position = @pos + position[:character]
|
204
|
-
|
205
220
|
if @encoding == Encoding::UTF_16LE
|
206
221
|
requested_position -= utf_16_character_position_correction(@pos, requested_position)
|
207
222
|
end
|
@@ -216,7 +231,7 @@ module RubyLsp
|
|
216
231
|
utf16_unicode_correction = 0
|
217
232
|
|
218
233
|
until current_position == requested_position
|
219
|
-
codepoint = @
|
234
|
+
codepoint = @bytes_or_codepoints[current_position]
|
220
235
|
utf16_unicode_correction += 1 if codepoint && codepoint > SURROGATE_PAIR_START
|
221
236
|
|
222
237
|
current_position += 1
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
-
#: [ParseResultType = Prism::
|
5
|
+
#: [ParseResultType = Prism::ParseLexResult]
|
6
6
|
class ERBDocument < Document
|
7
7
|
#: String
|
8
8
|
attr_reader :host_language_source
|
@@ -31,11 +31,16 @@ module RubyLsp
|
|
31
31
|
@host_language_source = scanner.host_language
|
32
32
|
# Use partial script to avoid syntax errors in ERB files where keywords may be used without the full context in
|
33
33
|
# which they will be evaluated
|
34
|
-
@parse_result = Prism.
|
34
|
+
@parse_result = Prism.parse_lex(scanner.ruby, partial_script: true)
|
35
35
|
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
36
36
|
true
|
37
37
|
end
|
38
38
|
|
39
|
+
#: -> Prism::ProgramNode
|
40
|
+
def ast
|
41
|
+
@parse_result.value.first
|
42
|
+
end
|
43
|
+
|
39
44
|
# @override
|
40
45
|
#: -> bool
|
41
46
|
def syntax_error?
|
@@ -53,7 +58,7 @@ module RubyLsp
|
|
53
58
|
char_position, _ = find_index_by_position(position)
|
54
59
|
|
55
60
|
RubyDocument.locate(
|
56
|
-
|
61
|
+
ast,
|
57
62
|
char_position,
|
58
63
|
code_units_cache: @code_units_cache,
|
59
64
|
node_types: node_types,
|
@@ -19,21 +19,20 @@ module RubyLsp
|
|
19
19
|
|
20
20
|
#: (ResponseBuilders::TestCollection, GlobalState, Prism::Dispatcher, URI::Generic) -> void
|
21
21
|
def initialize(response_builder, global_state, dispatcher, uri)
|
22
|
-
super
|
22
|
+
super(response_builder, global_state, uri)
|
23
23
|
|
24
24
|
@spec_group_id_stack = [] #: Array[Group?]
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
# Common handlers registered in parent class
|
26
|
+
register_events(
|
27
|
+
dispatcher,
|
29
28
|
:on_class_node_enter,
|
30
|
-
:on_call_node_enter,
|
29
|
+
:on_call_node_enter,
|
31
30
|
:on_call_node_leave,
|
32
31
|
)
|
33
32
|
end
|
34
33
|
|
35
34
|
#: (Prism::ClassNode) -> void
|
36
|
-
def on_class_node_enter(node)
|
35
|
+
def on_class_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
37
36
|
with_test_ancestor_tracking(node) do |name, ancestors|
|
38
37
|
@spec_group_id_stack << (ancestors.include?("Minitest::Spec") ? ClassGroup.new(name) : nil)
|
39
38
|
end
|
@@ -58,7 +57,7 @@ module RubyLsp
|
|
58
57
|
end
|
59
58
|
|
60
59
|
#: (Prism::CallNode) -> void
|
61
|
-
def on_call_node_enter(node)
|
60
|
+
def on_call_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
62
61
|
return unless in_spec_context?
|
63
62
|
|
64
63
|
case node.name
|
@@ -70,7 +69,7 @@ module RubyLsp
|
|
70
69
|
end
|
71
70
|
|
72
71
|
#: (Prism::CallNode) -> void
|
73
|
-
def on_call_node_leave(node)
|
72
|
+
def on_call_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
74
73
|
return unless node.name == :describe && !node.receiver
|
75
74
|
|
76
75
|
current_group = @spec_group_id_stack.last
|
@@ -9,24 +9,17 @@ module RubyLsp
|
|
9
9
|
|
10
10
|
DYNAMIC_REFERENCE_MARKER = "<dynamic_reference>"
|
11
11
|
|
12
|
-
#: (ResponseBuilders::TestCollection response_builder, GlobalState global_state,
|
13
|
-
def initialize(response_builder, global_state,
|
12
|
+
#: (ResponseBuilders::TestCollection response_builder, GlobalState global_state, URI::Generic uri) -> void
|
13
|
+
def initialize(response_builder, global_state, uri)
|
14
14
|
@response_builder = response_builder
|
15
15
|
@uri = uri
|
16
16
|
@index = global_state.index #: RubyIndexer::Index
|
17
17
|
@visibility_stack = [:public] #: Array[Symbol]
|
18
18
|
@nesting = [] #: Array[String]
|
19
|
-
|
20
|
-
dispatcher.register(
|
21
|
-
self,
|
22
|
-
:on_class_node_leave,
|
23
|
-
:on_module_node_enter,
|
24
|
-
:on_module_node_leave,
|
25
|
-
)
|
26
19
|
end
|
27
20
|
|
28
21
|
#: (Prism::ModuleNode node) -> void
|
29
|
-
def on_module_node_enter(node)
|
22
|
+
def on_module_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
30
23
|
@visibility_stack << :public
|
31
24
|
|
32
25
|
name = constant_name(node.constant_path)
|
@@ -36,19 +29,31 @@ module RubyLsp
|
|
36
29
|
end
|
37
30
|
|
38
31
|
#: (Prism::ModuleNode node) -> void
|
39
|
-
def on_module_node_leave(node)
|
32
|
+
def on_module_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
40
33
|
@visibility_stack.pop
|
41
34
|
@nesting.pop
|
42
35
|
end
|
43
36
|
|
44
37
|
#: (Prism::ClassNode node) -> void
|
45
|
-
def on_class_node_leave(node)
|
38
|
+
def on_class_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
46
39
|
@visibility_stack.pop
|
47
40
|
@nesting.pop
|
48
41
|
end
|
49
42
|
|
50
43
|
private
|
51
44
|
|
45
|
+
#: (Prism::Dispatcher, *Symbol) -> void
|
46
|
+
def register_events(dispatcher, *events)
|
47
|
+
unique_events = events.dup.push(
|
48
|
+
:on_class_node_leave,
|
49
|
+
:on_module_node_enter,
|
50
|
+
:on_module_node_leave,
|
51
|
+
)
|
52
|
+
|
53
|
+
unique_events.uniq!
|
54
|
+
dispatcher.register(self, *unique_events)
|
55
|
+
end
|
56
|
+
|
52
57
|
#: (String? name) -> String
|
53
58
|
def calc_fully_qualified_name(name)
|
54
59
|
RubyIndexer::Index.actual_nesting(@nesting, name).join("::")
|
@@ -153,14 +153,13 @@ module RubyLsp
|
|
153
153
|
|
154
154
|
#: (ResponseBuilders::TestCollection, GlobalState, Prism::Dispatcher, URI::Generic) -> void
|
155
155
|
def initialize(response_builder, global_state, dispatcher, uri)
|
156
|
-
super
|
156
|
+
super(response_builder, global_state, uri)
|
157
157
|
|
158
158
|
@framework = :minitest #: Symbol
|
159
159
|
@parent_stack = [@response_builder] #: Array[(Requests::Support::TestItem | ResponseBuilders::TestCollection)?]
|
160
160
|
|
161
|
-
|
162
|
-
|
163
|
-
# Common handlers registered in parent class
|
161
|
+
register_events(
|
162
|
+
dispatcher,
|
164
163
|
:on_class_node_enter,
|
165
164
|
:on_def_node_enter,
|
166
165
|
:on_call_node_enter,
|
@@ -169,7 +168,7 @@ module RubyLsp
|
|
169
168
|
end
|
170
169
|
|
171
170
|
#: (Prism::ClassNode node) -> void
|
172
|
-
def on_class_node_enter(node)
|
171
|
+
def on_class_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
173
172
|
with_test_ancestor_tracking(node) do |name, ancestors|
|
174
173
|
@framework = :test_unit if ancestors.include?("Test::Unit::TestCase")
|
175
174
|
|
@@ -210,7 +209,7 @@ module RubyLsp
|
|
210
209
|
end
|
211
210
|
|
212
211
|
#: (Prism::DefNode node) -> void
|
213
|
-
def on_def_node_enter(node)
|
212
|
+
def on_def_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
214
213
|
return if @visibility_stack.last != :public
|
215
214
|
|
216
215
|
name = node.name.to_s
|
@@ -232,7 +231,7 @@ module RubyLsp
|
|
232
231
|
end
|
233
232
|
|
234
233
|
#: (Prism::CallNode node) -> void
|
235
|
-
def on_call_node_enter(node)
|
234
|
+
def on_call_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
236
235
|
name = node.name
|
237
236
|
return unless ACCESS_MODIFIERS.include?(name)
|
238
237
|
|
@@ -240,7 +239,7 @@ module RubyLsp
|
|
240
239
|
end
|
241
240
|
|
242
241
|
#: (Prism::CallNode node) -> void
|
243
|
-
def on_call_node_leave(node)
|
242
|
+
def on_call_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
244
243
|
name = node.name
|
245
244
|
return unless ACCESS_MODIFIERS.include?(name)
|
246
245
|
return unless node.arguments&.arguments
|
@@ -100,7 +100,7 @@ module RubyLsp
|
|
100
100
|
|
101
101
|
# Find the closest statements node, so that we place the refactor in a valid position
|
102
102
|
node_context = RubyDocument
|
103
|
-
.locate(@document.
|
103
|
+
.locate(@document.ast,
|
104
104
|
start_index,
|
105
105
|
node_types: [
|
106
106
|
Prism::StatementsNode,
|
@@ -207,7 +207,7 @@ module RubyLsp
|
|
207
207
|
|
208
208
|
# Find the closest method declaration node, so that we place the refactor in a valid position
|
209
209
|
node_context = RubyDocument.locate(
|
210
|
-
@document.
|
210
|
+
@document.ast,
|
211
211
|
start_index,
|
212
212
|
node_types: [Prism::DefNode],
|
213
213
|
code_units_cache: @document.code_units_cache,
|
@@ -43,7 +43,7 @@ module RubyLsp
|
|
43
43
|
addon.create_discover_tests_listener(@response_builder, @dispatcher, @document.uri)
|
44
44
|
end
|
45
45
|
|
46
|
-
@dispatcher.visit(@document.
|
46
|
+
@dispatcher.visit(@document.ast)
|
47
47
|
else
|
48
48
|
@global_state.synchronize do
|
49
49
|
RubyIndexer::DeclarationListener.new(
|
@@ -64,7 +64,7 @@ module RubyLsp
|
|
64
64
|
# Dispatch the events both for indexing the test file and discovering the tests. The order here is
|
65
65
|
# important because we need the index to be aware of the existing classes/modules/methods before the test
|
66
66
|
# listeners can do their work
|
67
|
-
@dispatcher.visit(@document.
|
67
|
+
@dispatcher.visit(@document.ast)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -24,7 +24,7 @@ module RubyLsp
|
|
24
24
|
delegate_request_if_needed!(global_state, document, char_position)
|
25
25
|
|
26
26
|
node_context = RubyDocument.locate(
|
27
|
-
document.
|
27
|
+
document.ast,
|
28
28
|
char_position,
|
29
29
|
node_types: Listeners::Hover::ALLOWED_TARGETS,
|
30
30
|
code_units_cache: document.code_units_cache,
|
@@ -22,7 +22,7 @@ module RubyLsp
|
|
22
22
|
char_position, _ = @document.find_index_by_position(@position)
|
23
23
|
|
24
24
|
node_context = RubyDocument.locate(
|
25
|
-
@document.
|
25
|
+
@document.ast,
|
26
26
|
char_position,
|
27
27
|
node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
|
28
28
|
code_units_cache: @document.code_units_cache,
|
@@ -26,7 +26,7 @@ module RubyLsp
|
|
26
26
|
char_position, _ = @document.find_index_by_position(position)
|
27
27
|
|
28
28
|
node_context = RubyDocument.locate(
|
29
|
-
@document.
|
29
|
+
@document.ast,
|
30
30
|
char_position,
|
31
31
|
node_types: [
|
32
32
|
Prism::ConstantReadNode,
|
@@ -66,7 +66,7 @@ module RubyLsp
|
|
66
66
|
# of reading from disk
|
67
67
|
next if @store.key?(uri)
|
68
68
|
|
69
|
-
parse_result = Prism.
|
69
|
+
parse_result = Prism.parse_lex_file(path)
|
70
70
|
collect_references(reference_target, parse_result, uri)
|
71
71
|
rescue Errno::EISDIR, Errno::ENOENT
|
72
72
|
# If `path` is a directory, just ignore it and continue. If the file doesn't exist, then we also ignore it.
|
@@ -111,7 +111,7 @@ module RubyLsp
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
#: (RubyIndexer::ReferenceFinder::Target target, Prism::
|
114
|
+
#: (RubyIndexer::ReferenceFinder::Target target, Prism::LexResult parse_result, URI::Generic uri) -> void
|
115
115
|
def collect_references(target, parse_result, uri)
|
116
116
|
dispatcher = Prism::Dispatcher.new
|
117
117
|
finder = RubyIndexer::ReferenceFinder.new(
|
@@ -121,7 +121,7 @@ module RubyLsp
|
|
121
121
|
uri,
|
122
122
|
include_declarations: @params.dig(:context, :includeDeclaration) || true,
|
123
123
|
)
|
124
|
-
dispatcher.visit(parse_result.value)
|
124
|
+
dispatcher.visit(parse_result.value.first)
|
125
125
|
|
126
126
|
finder.references.each do |reference|
|
127
127
|
@locations << Interface::Location.new(
|
@@ -34,7 +34,7 @@ module RubyLsp
|
|
34
34
|
char_position, _ = @document.find_index_by_position(@position)
|
35
35
|
|
36
36
|
node_context = RubyDocument.locate(
|
37
|
-
@document.
|
37
|
+
@document.ast,
|
38
38
|
char_position,
|
39
39
|
node_types: [Prism::ConstantReadNode, Prism::ConstantPathNode, Prism::ConstantPathTargetNode],
|
40
40
|
code_units_cache: @document.code_units_cache,
|
@@ -136,25 +136,27 @@ module RubyLsp
|
|
136
136
|
next if @store.key?(uri)
|
137
137
|
|
138
138
|
parse_result = Prism.parse_file(path)
|
139
|
-
edits = collect_changes(target, parse_result, name, uri)
|
139
|
+
edits = collect_changes(target, parse_result.value, name, uri)
|
140
140
|
changes[uri.to_s] = edits unless edits.empty?
|
141
141
|
rescue Errno::EISDIR, Errno::ENOENT
|
142
142
|
# If `path` is a directory, just ignore it and continue. If the file doesn't exist, then we also ignore it.
|
143
143
|
end
|
144
144
|
|
145
145
|
@store.each do |uri, document|
|
146
|
-
|
146
|
+
next unless document.is_a?(RubyDocument) || document.is_a?(ERBDocument)
|
147
|
+
|
148
|
+
edits = collect_changes(target, document.ast, name, document.uri)
|
147
149
|
changes[uri] = edits unless edits.empty?
|
148
150
|
end
|
149
151
|
|
150
152
|
changes
|
151
153
|
end
|
152
154
|
|
153
|
-
#: (RubyIndexer::ReferenceFinder::Target target, Prism::
|
154
|
-
def collect_changes(target,
|
155
|
+
#: (RubyIndexer::ReferenceFinder::Target target, Prism::Node ast, String name, URI::Generic uri) -> Array[Interface::TextEdit]
|
156
|
+
def collect_changes(target, ast, name, uri)
|
155
157
|
dispatcher = Prism::Dispatcher.new
|
156
158
|
finder = RubyIndexer::ReferenceFinder.new(target, @global_state.index, dispatcher, uri)
|
157
|
-
dispatcher.visit(
|
159
|
+
dispatcher.visit(ast)
|
158
160
|
|
159
161
|
finder.references.map do |reference|
|
160
162
|
adjust_reference_for_edit(name, reference)
|
@@ -27,7 +27,7 @@ module RubyLsp
|
|
27
27
|
delegate_request_if_needed!(global_state, document, char_position)
|
28
28
|
|
29
29
|
node_context = RubyDocument.locate(
|
30
|
-
document.
|
30
|
+
document.ast,
|
31
31
|
char_position,
|
32
32
|
node_types: [Prism::CallNode],
|
33
33
|
code_units_cache: document.code_units_cache,
|
@@ -2,7 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
-
#: [ParseResultType = Prism::
|
5
|
+
#: [ParseResultType = Prism::ParseLexResult]
|
6
6
|
class RubyDocument < Document
|
7
7
|
METHODS_THAT_CHANGE_DECLARATIONS = [
|
8
8
|
:private_constant,
|
@@ -129,11 +129,16 @@ module RubyLsp
|
|
129
129
|
return false unless @needs_parsing
|
130
130
|
|
131
131
|
@needs_parsing = false
|
132
|
-
@parse_result = Prism.
|
132
|
+
@parse_result = Prism.parse_lex(@source)
|
133
133
|
@code_units_cache = @parse_result.code_units_cache(@encoding)
|
134
134
|
true
|
135
135
|
end
|
136
136
|
|
137
|
+
#: -> Prism::ProgramNode
|
138
|
+
def ast
|
139
|
+
@parse_result.value.first
|
140
|
+
end
|
141
|
+
|
137
142
|
# @override
|
138
143
|
#: -> bool
|
139
144
|
def syntax_error?
|
@@ -151,7 +156,7 @@ module RubyLsp
|
|
151
156
|
start_position, end_position = find_index_by_position(range[:start], range[:end])
|
152
157
|
|
153
158
|
desired_range = (start_position...end_position)
|
154
|
-
queue =
|
159
|
+
queue = ast.child_nodes.compact #: Array[Prism::Node?]
|
155
160
|
|
156
161
|
until queue.empty?
|
157
162
|
candidate = queue.shift
|
@@ -179,7 +184,7 @@ module RubyLsp
|
|
179
184
|
char_position, _ = find_index_by_position(position)
|
180
185
|
|
181
186
|
RubyDocument.locate(
|
182
|
-
|
187
|
+
ast,
|
183
188
|
char_position,
|
184
189
|
code_units_cache: @code_units_cache,
|
185
190
|
node_types: node_types,
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -121,24 +121,12 @@ module RubyLsp
|
|
121
121
|
# If a document is deleted before we are able to process all of its enqueued requests, we will try to read it
|
122
122
|
# from disk and it raise this error. This is expected, so we don't include the `data` attribute to avoid
|
123
123
|
# reporting these to our telemetry
|
124
|
-
|
125
|
-
when Store::NonExistingDocumentError
|
124
|
+
if e.is_a?(Store::NonExistingDocumentError)
|
126
125
|
send_message(Error.new(
|
127
126
|
id: message[:id],
|
128
127
|
code: Constant::ErrorCodes::INVALID_PARAMS,
|
129
128
|
message: e.full_message,
|
130
129
|
))
|
131
|
-
when Document::LocationNotFoundError
|
132
|
-
send_message(Error.new(
|
133
|
-
id: message[:id],
|
134
|
-
code: Constant::ErrorCodes::REQUEST_FAILED,
|
135
|
-
message: <<~MESSAGE,
|
136
|
-
Request #{message[:method]} failed to find the target position.
|
137
|
-
The file might have been modified while the server was in the middle of searching for the target.
|
138
|
-
If you experience this regularly, please report any findings and extra information on
|
139
|
-
https://github.com/Shopify/ruby-lsp/issues/2446
|
140
|
-
MESSAGE
|
141
|
-
))
|
142
130
|
else
|
143
131
|
send_message(Error.new(
|
144
132
|
id: message[:id],
|
@@ -504,12 +492,12 @@ module RubyLsp
|
|
504
492
|
index.delete(uri, skip_require_paths_tree: true)
|
505
493
|
RubyIndexer::DeclarationListener.new(index, dispatcher, parse_result, uri, collect_comments: true)
|
506
494
|
code_lens = Requests::CodeLens.new(@global_state, document, dispatcher)
|
507
|
-
dispatcher.dispatch(
|
495
|
+
dispatcher.dispatch(document.ast)
|
508
496
|
end
|
509
497
|
end
|
510
498
|
else
|
511
499
|
code_lens = Requests::CodeLens.new(@global_state, document, dispatcher)
|
512
|
-
dispatcher.dispatch(
|
500
|
+
dispatcher.dispatch(document.ast)
|
513
501
|
end
|
514
502
|
|
515
503
|
# Store all responses retrieve in this round of visits in the cache and then return the response for the request
|
@@ -548,7 +536,7 @@ module RubyLsp
|
|
548
536
|
|
549
537
|
dispatcher = Prism::Dispatcher.new
|
550
538
|
semantic_highlighting = Requests::SemanticHighlighting.new(@global_state, dispatcher, document, nil)
|
551
|
-
dispatcher.visit(document.
|
539
|
+
dispatcher.visit(document.ast)
|
552
540
|
|
553
541
|
send_message(Result.new(id: message[:id], response: semantic_highlighting.perform))
|
554
542
|
end
|
@@ -574,7 +562,7 @@ module RubyLsp
|
|
574
562
|
document,
|
575
563
|
message.dig(:params, :previousResultId),
|
576
564
|
)
|
577
|
-
dispatcher.visit(document.
|
565
|
+
dispatcher.visit(document.ast)
|
578
566
|
send_message(Result.new(id: message[:id], response: request.perform))
|
579
567
|
end
|
580
568
|
|
@@ -603,7 +591,7 @@ module RubyLsp
|
|
603
591
|
nil,
|
604
592
|
range: range.dig(:start, :line)..range.dig(:end, :line),
|
605
593
|
)
|
606
|
-
dispatcher.visit(document.
|
594
|
+
dispatcher.visit(document.ast)
|
607
595
|
send_message(Result.new(id: message[:id], response: request.perform))
|
608
596
|
end
|
609
597
|
|
@@ -695,7 +683,7 @@ module RubyLsp
|
|
695
683
|
end
|
696
684
|
|
697
685
|
request = Requests::DocumentHighlight.new(@global_state, document, params[:position], dispatcher)
|
698
|
-
dispatcher.dispatch(document.
|
686
|
+
dispatcher.dispatch(document.ast)
|
699
687
|
send_message(Result.new(id: message[:id], response: request.perform))
|
700
688
|
end
|
701
689
|
|
@@ -842,7 +830,7 @@ module RubyLsp
|
|
842
830
|
end
|
843
831
|
|
844
832
|
request = Requests::InlayHints.new(document, hints_configurations, dispatcher)
|
845
|
-
dispatcher.visit(document.
|
833
|
+
dispatcher.visit(document.ast)
|
846
834
|
result = request.perform
|
847
835
|
document.cache_set("textDocument/inlayHint", result)
|
848
836
|
|