ruby-lsp 0.21.3 → 0.22.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/exe/ruby-lsp +1 -1
- data/exe/ruby-lsp-launcher +0 -3
- data/lib/ruby_indexer/lib/ruby_indexer/configuration.rb +6 -0
- data/lib/ruby_indexer/lib/ruby_indexer/declaration_listener.rb +179 -59
- data/lib/ruby_indexer/lib/ruby_indexer/enhancement.rb +31 -28
- data/lib/ruby_indexer/lib/ruby_indexer/index.rb +10 -10
- data/lib/ruby_indexer/test/classes_and_modules_test.rb +2 -2
- data/lib/ruby_indexer/test/configuration_test.rb +10 -0
- data/lib/ruby_indexer/test/constant_test.rb +8 -8
- data/lib/ruby_indexer/test/enhancements_test.rb +134 -38
- data/lib/ruby_indexer/test/index_test.rb +39 -0
- data/lib/ruby_indexer/test/method_test.rb +114 -1
- data/lib/ruby_lsp/global_state.rb +2 -4
- data/lib/ruby_lsp/internal.rb +1 -0
- data/lib/ruby_lsp/listeners/document_symbol.rb +37 -4
- data/lib/ruby_lsp/requests/definition.rb +2 -0
- data/lib/ruby_lsp/requests/hover.rb +2 -0
- data/lib/ruby_lsp/requests/support/rubocop_runner.rb +1 -0
- data/lib/ruby_lsp/server.rb +13 -0
- data/lib/ruby_lsp/setup_bundler.rb +43 -25
- metadata +3 -3
@@ -5,24 +5,28 @@ require_relative "test_case"
|
|
5
5
|
|
6
6
|
module RubyIndexer
|
7
7
|
class EnhancementTest < TestCase
|
8
|
+
def teardown
|
9
|
+
super
|
10
|
+
Enhancement.clear
|
11
|
+
end
|
12
|
+
|
8
13
|
def test_enhancing_indexing_included_hook
|
9
|
-
|
10
|
-
def on_call_node_enter(
|
14
|
+
Class.new(Enhancement) do
|
15
|
+
def on_call_node_enter(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
16
|
+
owner = @listener.current_owner
|
11
17
|
return unless owner
|
12
|
-
return unless
|
18
|
+
return unless call_node.name == :extend
|
13
19
|
|
14
|
-
arguments =
|
20
|
+
arguments = call_node.arguments&.arguments
|
15
21
|
return unless arguments
|
16
22
|
|
17
|
-
location = Location.from_prism_location(node.location, code_units_cache)
|
18
|
-
|
19
23
|
arguments.each do |node|
|
20
24
|
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
|
21
25
|
|
22
26
|
module_name = node.full_name
|
23
27
|
next unless module_name == "ActiveSupport::Concern"
|
24
28
|
|
25
|
-
@
|
29
|
+
@listener.register_included_hook do |index, base|
|
26
30
|
class_methods_name = "#{owner.name}::ClassMethods"
|
27
31
|
|
28
32
|
if index.indexed?(class_methods_name)
|
@@ -31,16 +35,11 @@ module RubyIndexer
|
|
31
35
|
end
|
32
36
|
end
|
33
37
|
|
34
|
-
@
|
38
|
+
@listener.add_method(
|
35
39
|
"new_method",
|
36
|
-
|
37
|
-
location,
|
38
|
-
location,
|
39
|
-
nil,
|
40
|
+
call_node.location,
|
40
41
|
[Entry::Signature.new([Entry::RequiredParameter.new(name: :a)])],
|
41
|
-
|
42
|
-
owner,
|
43
|
-
))
|
42
|
+
)
|
44
43
|
rescue Prism::ConstantPathNode::DynamicPartsInConstantPathError,
|
45
44
|
Prism::ConstantPathNode::MissingNodesInConstantPathError
|
46
45
|
# Do nothing
|
@@ -48,7 +47,6 @@ module RubyIndexer
|
|
48
47
|
end
|
49
48
|
end
|
50
49
|
|
51
|
-
@index.register_enhancement(enhancement_class.new(@index))
|
52
50
|
index(<<~RUBY)
|
53
51
|
module ActiveSupport
|
54
52
|
module Concern
|
@@ -96,9 +94,9 @@ module RubyIndexer
|
|
96
94
|
end
|
97
95
|
|
98
96
|
def test_enhancing_indexing_configuration_dsl
|
99
|
-
|
100
|
-
def on_call_node_enter(
|
101
|
-
return unless
|
97
|
+
Class.new(Enhancement) do
|
98
|
+
def on_call_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
99
|
+
return unless @listener.current_owner
|
102
100
|
|
103
101
|
name = node.name
|
104
102
|
return unless name == :has_many
|
@@ -109,22 +107,14 @@ module RubyIndexer
|
|
109
107
|
association_name = arguments.first
|
110
108
|
return unless association_name.is_a?(Prism::SymbolNode)
|
111
109
|
|
112
|
-
|
113
|
-
|
114
|
-
@index.add(Entry::Method.new(
|
110
|
+
@listener.add_method(
|
115
111
|
T.must(association_name.value),
|
116
|
-
|
117
|
-
location,
|
118
|
-
location,
|
119
|
-
nil,
|
112
|
+
association_name.location,
|
120
113
|
[],
|
121
|
-
|
122
|
-
owner,
|
123
|
-
))
|
114
|
+
)
|
124
115
|
end
|
125
116
|
end
|
126
117
|
|
127
|
-
@index.register_enhancement(enhancement_class.new(@index))
|
128
118
|
index(<<~RUBY)
|
129
119
|
module ActiveSupport
|
130
120
|
module Concern
|
@@ -157,8 +147,8 @@ module RubyIndexer
|
|
157
147
|
end
|
158
148
|
|
159
149
|
def test_error_handling_in_on_call_node_enter_enhancement
|
160
|
-
|
161
|
-
def on_call_node_enter(
|
150
|
+
Class.new(Enhancement) do
|
151
|
+
def on_call_node_enter(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
162
152
|
raise "Error"
|
163
153
|
end
|
164
154
|
|
@@ -169,8 +159,6 @@ module RubyIndexer
|
|
169
159
|
end
|
170
160
|
end
|
171
161
|
|
172
|
-
@index.register_enhancement(enhancement_class.new(@index))
|
173
|
-
|
174
162
|
_stdout, stderr = capture_io do
|
175
163
|
index(<<~RUBY)
|
176
164
|
module ActiveSupport
|
@@ -192,8 +180,8 @@ module RubyIndexer
|
|
192
180
|
end
|
193
181
|
|
194
182
|
def test_error_handling_in_on_call_node_leave_enhancement
|
195
|
-
|
196
|
-
def on_call_node_leave(
|
183
|
+
Class.new(Enhancement) do
|
184
|
+
def on_call_node_leave(node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
197
185
|
raise "Error"
|
198
186
|
end
|
199
187
|
|
@@ -204,8 +192,6 @@ module RubyIndexer
|
|
204
192
|
end
|
205
193
|
end
|
206
194
|
|
207
|
-
@index.register_enhancement(enhancement_class.new(@index))
|
208
|
-
|
209
195
|
_stdout, stderr = capture_io do
|
210
196
|
index(<<~RUBY)
|
211
197
|
module ActiveSupport
|
@@ -225,5 +211,115 @@ module RubyIndexer
|
|
225
211
|
# The module should still be indexed
|
226
212
|
assert_entry("ActiveSupport::Concern", Entry::Module, "/fake/path/foo.rb:1-2:5-5")
|
227
213
|
end
|
214
|
+
|
215
|
+
def test_advancing_namespace_stack_from_enhancement
|
216
|
+
Class.new(Enhancement) do
|
217
|
+
def on_call_node_enter(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
218
|
+
owner = @listener.current_owner
|
219
|
+
return unless owner
|
220
|
+
|
221
|
+
case call_node.name
|
222
|
+
when :class_methods
|
223
|
+
@listener.add_module("ClassMethods", call_node.location, call_node.location)
|
224
|
+
when :extend
|
225
|
+
arguments = call_node.arguments&.arguments
|
226
|
+
return unless arguments
|
227
|
+
|
228
|
+
arguments.each do |node|
|
229
|
+
next unless node.is_a?(Prism::ConstantReadNode) || node.is_a?(Prism::ConstantPathNode)
|
230
|
+
|
231
|
+
module_name = node.full_name
|
232
|
+
next unless module_name == "ActiveSupport::Concern"
|
233
|
+
|
234
|
+
@listener.register_included_hook do |index, base|
|
235
|
+
class_methods_name = "#{owner.name}::ClassMethods"
|
236
|
+
|
237
|
+
if index.indexed?(class_methods_name)
|
238
|
+
singleton = index.existing_or_new_singleton_class(base.name)
|
239
|
+
singleton.mixin_operations << Entry::Include.new(class_methods_name)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def on_call_node_leave(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
247
|
+
return unless call_node.name == :class_methods
|
248
|
+
|
249
|
+
@listener.pop_namespace_stack
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
index(<<~RUBY)
|
254
|
+
module ActiveSupport
|
255
|
+
module Concern
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
module MyConcern
|
260
|
+
extend ActiveSupport::Concern
|
261
|
+
|
262
|
+
class_methods do
|
263
|
+
def foo; end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
class User
|
268
|
+
include MyConcern
|
269
|
+
end
|
270
|
+
RUBY
|
271
|
+
|
272
|
+
assert_equal(
|
273
|
+
[
|
274
|
+
"User::<Class:User>",
|
275
|
+
"MyConcern::ClassMethods",
|
276
|
+
"Object::<Class:Object>",
|
277
|
+
"BasicObject::<Class:BasicObject>",
|
278
|
+
"Class",
|
279
|
+
"Module",
|
280
|
+
"Object",
|
281
|
+
"Kernel",
|
282
|
+
"BasicObject",
|
283
|
+
],
|
284
|
+
@index.linearized_ancestors_of("User::<Class:User>"),
|
285
|
+
)
|
286
|
+
|
287
|
+
refute_nil(@index.resolve_method("foo", "User::<Class:User>"))
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_creating_anonymous_classes_from_enhancement
|
291
|
+
Class.new(Enhancement) do
|
292
|
+
def on_call_node_enter(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
293
|
+
case call_node.name
|
294
|
+
when :context
|
295
|
+
arguments = call_node.arguments&.arguments
|
296
|
+
first_argument = arguments&.first
|
297
|
+
return unless first_argument.is_a?(Prism::StringNode)
|
298
|
+
|
299
|
+
@listener.add_class(
|
300
|
+
"<RSpec:#{first_argument.content}>",
|
301
|
+
call_node.location,
|
302
|
+
first_argument.location,
|
303
|
+
)
|
304
|
+
when :subject
|
305
|
+
@listener.add_method("subject", call_node.location, [])
|
306
|
+
end
|
307
|
+
end
|
308
|
+
|
309
|
+
def on_call_node_leave(call_node) # rubocop:disable RubyLsp/UseRegisterWithHandlerMethod
|
310
|
+
return unless call_node.name == :context
|
311
|
+
|
312
|
+
@listener.pop_namespace_stack
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
index(<<~RUBY)
|
317
|
+
context "does something" do
|
318
|
+
subject { call_whatever }
|
319
|
+
end
|
320
|
+
RUBY
|
321
|
+
|
322
|
+
refute_nil(@index.resolve_method("subject", "<RSpec:does something>"))
|
323
|
+
end
|
228
324
|
end
|
229
325
|
end
|
@@ -1672,6 +1672,38 @@ module RubyIndexer
|
|
1672
1672
|
)
|
1673
1673
|
end
|
1674
1674
|
|
1675
|
+
def test_extend_self
|
1676
|
+
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1677
|
+
module Foo
|
1678
|
+
def bar
|
1679
|
+
end
|
1680
|
+
|
1681
|
+
extend self
|
1682
|
+
|
1683
|
+
def baz
|
1684
|
+
end
|
1685
|
+
end
|
1686
|
+
RUBY
|
1687
|
+
|
1688
|
+
["bar", "baz"].product(["Foo", "Foo::<Class:Foo>"]).each do |method, receiver|
|
1689
|
+
entry = @index.resolve_method(method, receiver)&.first
|
1690
|
+
refute_nil(entry)
|
1691
|
+
assert_equal(method, T.must(entry).name)
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
assert_equal(
|
1695
|
+
[
|
1696
|
+
"Foo::<Class:Foo>",
|
1697
|
+
"Foo",
|
1698
|
+
"Module",
|
1699
|
+
"Object",
|
1700
|
+
"Kernel",
|
1701
|
+
"BasicObject",
|
1702
|
+
],
|
1703
|
+
@index.linearized_ancestors_of("Foo::<Class:Foo>"),
|
1704
|
+
)
|
1705
|
+
end
|
1706
|
+
|
1675
1707
|
def test_linearizing_singleton_ancestors
|
1676
1708
|
@index.index_single(IndexablePath.new(nil, "/fake/path/foo.rb"), <<~RUBY)
|
1677
1709
|
module First
|
@@ -2023,5 +2055,12 @@ module RubyIndexer
|
|
2023
2055
|
),
|
2024
2056
|
)
|
2025
2057
|
end
|
2058
|
+
|
2059
|
+
def test_prevents_multiple_calls_to_index_all
|
2060
|
+
# For this test class, `index_all` is already called once in `setup`.
|
2061
|
+
assert_raises(Index::IndexNotEmptyError) do
|
2062
|
+
@index.index_all
|
2063
|
+
end
|
2064
|
+
end
|
2026
2065
|
end
|
2027
2066
|
end
|
@@ -141,7 +141,7 @@ module RubyIndexer
|
|
141
141
|
# The first entry points to the location of the module_function call
|
142
142
|
assert_equal("Test", first_entry.owner.name)
|
143
143
|
assert_instance_of(Entry::Module, first_entry.owner)
|
144
|
-
|
144
|
+
assert_predicate(first_entry, :private?)
|
145
145
|
# The second entry points to the public singleton method
|
146
146
|
assert_equal("Test::<Class:Test>", second_entry.owner.name)
|
147
147
|
assert_instance_of(Entry::SingletonClass, second_entry.owner)
|
@@ -149,6 +149,119 @@ module RubyIndexer
|
|
149
149
|
end
|
150
150
|
end
|
151
151
|
|
152
|
+
def test_private_class_method_visibility_tracking_string_symbol_arguments
|
153
|
+
index(<<~RUBY)
|
154
|
+
class Test
|
155
|
+
def self.foo
|
156
|
+
end
|
157
|
+
|
158
|
+
def self.bar
|
159
|
+
end
|
160
|
+
|
161
|
+
private_class_method("foo", :bar)
|
162
|
+
|
163
|
+
def self.baz
|
164
|
+
end
|
165
|
+
end
|
166
|
+
RUBY
|
167
|
+
|
168
|
+
["foo", "bar"].each do |keyword|
|
169
|
+
entries = T.must(@index[keyword])
|
170
|
+
assert_equal(1, entries.size)
|
171
|
+
entry = entries.first
|
172
|
+
assert_predicate(entry, :private?)
|
173
|
+
end
|
174
|
+
|
175
|
+
entries = T.must(@index["baz"])
|
176
|
+
assert_equal(1, entries.size)
|
177
|
+
entry = entries.first
|
178
|
+
assert_predicate(entry, :public?)
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_private_class_method_visibility_tracking_array_argument
|
182
|
+
index(<<~RUBY)
|
183
|
+
class Test
|
184
|
+
def self.foo
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.bar
|
188
|
+
end
|
189
|
+
|
190
|
+
private_class_method(["foo", :bar])
|
191
|
+
|
192
|
+
def self.baz
|
193
|
+
end
|
194
|
+
end
|
195
|
+
RUBY
|
196
|
+
|
197
|
+
["foo", "bar"].each do |keyword|
|
198
|
+
entries = T.must(@index[keyword])
|
199
|
+
assert_equal(1, entries.size)
|
200
|
+
entry = entries.first
|
201
|
+
assert_predicate(entry, :private?)
|
202
|
+
end
|
203
|
+
|
204
|
+
entries = T.must(@index["baz"])
|
205
|
+
assert_equal(1, entries.size)
|
206
|
+
entry = entries.first
|
207
|
+
assert_predicate(entry, :public?)
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_private_class_method_visibility_tracking_method_argument
|
211
|
+
index(<<~RUBY)
|
212
|
+
class Test
|
213
|
+
private_class_method def self.foo
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.bar
|
217
|
+
end
|
218
|
+
end
|
219
|
+
RUBY
|
220
|
+
|
221
|
+
entries = T.must(@index["foo"])
|
222
|
+
assert_equal(1, entries.size)
|
223
|
+
entry = entries.first
|
224
|
+
assert_predicate(entry, :private?)
|
225
|
+
|
226
|
+
entries = T.must(@index["bar"])
|
227
|
+
assert_equal(1, entries.size)
|
228
|
+
entry = entries.first
|
229
|
+
assert_predicate(entry, :public?)
|
230
|
+
end
|
231
|
+
|
232
|
+
def test_comments_documentation
|
233
|
+
index(<<~RUBY)
|
234
|
+
# Documentation for Foo
|
235
|
+
|
236
|
+
class Foo
|
237
|
+
# ####################
|
238
|
+
# Documentation for bar
|
239
|
+
# ####################
|
240
|
+
#
|
241
|
+
def bar
|
242
|
+
end
|
243
|
+
|
244
|
+
# test
|
245
|
+
|
246
|
+
# Documentation for baz
|
247
|
+
def baz; end
|
248
|
+
def ban; end
|
249
|
+
end
|
250
|
+
RUBY
|
251
|
+
|
252
|
+
foo_comment = @index["Foo"].first.comments
|
253
|
+
assert_equal("Documentation for Foo", foo_comment)
|
254
|
+
|
255
|
+
bar_comment = @index["bar"].first.comments
|
256
|
+
assert_equal("####################\nDocumentation for bar\n####################\n", bar_comment)
|
257
|
+
|
258
|
+
baz_comment = @index["baz"].first.comments
|
259
|
+
assert_equal("Documentation for baz", baz_comment)
|
260
|
+
|
261
|
+
ban_comment = @index["ban"].first.comments
|
262
|
+
assert_empty(ban_comment)
|
263
|
+
end
|
264
|
+
|
152
265
|
def test_method_with_parameters
|
153
266
|
index(<<~RUBY)
|
154
267
|
class Foo
|
@@ -21,7 +21,7 @@ module RubyLsp
|
|
21
21
|
attr_reader :encoding
|
22
22
|
|
23
23
|
sig { returns(T::Boolean) }
|
24
|
-
attr_reader :
|
24
|
+
attr_reader :top_level_bundle
|
25
25
|
|
26
26
|
sig { returns(TypeInferrer) }
|
27
27
|
attr_reader :type_inferrer
|
@@ -40,7 +40,6 @@ module RubyLsp
|
|
40
40
|
@has_type_checker = T.let(true, T::Boolean)
|
41
41
|
@index = T.let(RubyIndexer::Index.new, RubyIndexer::Index)
|
42
42
|
@supported_formatters = T.let({}, T::Hash[String, Requests::Support::Formatter])
|
43
|
-
@experimental_features = T.let(false, T::Boolean)
|
44
43
|
@type_inferrer = T.let(TypeInferrer.new(@index), TypeInferrer)
|
45
44
|
@addon_settings = T.let({}, T::Hash[String, T.untyped])
|
46
45
|
@top_level_bundle = T.let(
|
@@ -131,7 +130,6 @@ module RubyLsp
|
|
131
130
|
end
|
132
131
|
@index.configuration.encoding = @encoding
|
133
132
|
|
134
|
-
@experimental_features = options.dig(:initializationOptions, :experimentalFeaturesEnabled) || false
|
135
133
|
@client_capabilities.apply_client_capabilities(options[:capabilities]) if options[:capabilities]
|
136
134
|
|
137
135
|
addon_settings = options.dig(:initializationOptions, :addonSettings)
|
@@ -148,7 +146,7 @@ module RubyLsp
|
|
148
146
|
|
149
147
|
sig { params(flag: Symbol).returns(T.nilable(T::Boolean)) }
|
150
148
|
def enabled_feature?(flag)
|
151
|
-
@enabled_feature_flags[flag]
|
149
|
+
@enabled_feature_flags[:all] || @enabled_feature_flags[flag]
|
152
150
|
end
|
153
151
|
|
154
152
|
sig { returns(String) }
|
data/lib/ruby_lsp/internal.rb
CHANGED
@@ -41,6 +41,9 @@ module RubyLsp
|
|
41
41
|
:on_module_node_enter,
|
42
42
|
:on_module_node_leave,
|
43
43
|
:on_instance_variable_write_node_enter,
|
44
|
+
:on_instance_variable_operator_write_node_enter,
|
45
|
+
:on_instance_variable_or_write_node_enter,
|
46
|
+
:on_instance_variable_and_write_node_enter,
|
44
47
|
:on_class_variable_write_node_enter,
|
45
48
|
:on_singleton_class_node_enter,
|
46
49
|
:on_singleton_class_node_leave,
|
@@ -249,21 +252,51 @@ module RubyLsp
|
|
249
252
|
@response_builder.pop
|
250
253
|
end
|
251
254
|
|
255
|
+
sig { params(node: Prism::ClassVariableWriteNode).void }
|
256
|
+
def on_class_variable_write_node_enter(node)
|
257
|
+
create_document_symbol(
|
258
|
+
name: node.name.to_s,
|
259
|
+
kind: Constant::SymbolKind::VARIABLE,
|
260
|
+
range_location: node.name_loc,
|
261
|
+
selection_range_location: node.name_loc,
|
262
|
+
)
|
263
|
+
end
|
264
|
+
|
252
265
|
sig { params(node: Prism::InstanceVariableWriteNode).void }
|
253
266
|
def on_instance_variable_write_node_enter(node)
|
254
267
|
create_document_symbol(
|
255
268
|
name: node.name.to_s,
|
256
|
-
kind: Constant::SymbolKind::
|
269
|
+
kind: Constant::SymbolKind::FIELD,
|
257
270
|
range_location: node.name_loc,
|
258
271
|
selection_range_location: node.name_loc,
|
259
272
|
)
|
260
273
|
end
|
261
274
|
|
262
|
-
sig { params(node: Prism::
|
263
|
-
def
|
275
|
+
sig { params(node: Prism::InstanceVariableOperatorWriteNode).void }
|
276
|
+
def on_instance_variable_operator_write_node_enter(node)
|
264
277
|
create_document_symbol(
|
265
278
|
name: node.name.to_s,
|
266
|
-
kind: Constant::SymbolKind::
|
279
|
+
kind: Constant::SymbolKind::FIELD,
|
280
|
+
range_location: node.name_loc,
|
281
|
+
selection_range_location: node.name_loc,
|
282
|
+
)
|
283
|
+
end
|
284
|
+
|
285
|
+
sig { params(node: Prism::InstanceVariableOrWriteNode).void }
|
286
|
+
def on_instance_variable_or_write_node_enter(node)
|
287
|
+
create_document_symbol(
|
288
|
+
name: node.name.to_s,
|
289
|
+
kind: Constant::SymbolKind::FIELD,
|
290
|
+
range_location: node.name_loc,
|
291
|
+
selection_range_location: node.name_loc,
|
292
|
+
)
|
293
|
+
end
|
294
|
+
|
295
|
+
sig { params(node: Prism::InstanceVariableAndWriteNode).void }
|
296
|
+
def on_instance_variable_and_write_node_enter(node)
|
297
|
+
create_document_symbol(
|
298
|
+
name: node.name.to_s,
|
299
|
+
kind: Constant::SymbolKind::FIELD,
|
267
300
|
range_location: node.name_loc,
|
268
301
|
selection_range_location: node.name_loc,
|
269
302
|
)
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -216,6 +216,13 @@ module RubyLsp
|
|
216
216
|
Hash.new(true)
|
217
217
|
end
|
218
218
|
|
219
|
+
bundle_env_path = File.join(".ruby-lsp", "bundle_env")
|
220
|
+
bundle_env = if File.exist?(bundle_env_path)
|
221
|
+
env = File.readlines(bundle_env_path).to_h { |line| T.cast(line.chomp.split("=", 2), [String, String]) }
|
222
|
+
FileUtils.rm(bundle_env_path)
|
223
|
+
env
|
224
|
+
end
|
225
|
+
|
219
226
|
document_symbol_provider = Requests::DocumentSymbol.provider if enabled_features["documentSymbols"]
|
220
227
|
document_link_provider = Requests::DocumentLink.provider if enabled_features["documentLink"]
|
221
228
|
code_lens_provider = Requests::CodeLens.provider if enabled_features["codeLens"]
|
@@ -269,6 +276,7 @@ module RubyLsp
|
|
269
276
|
},
|
270
277
|
formatter: @global_state.formatter,
|
271
278
|
degraded_mode: !!(@install_error || @setup_error),
|
279
|
+
bundle_env: bundle_env,
|
272
280
|
}
|
273
281
|
|
274
282
|
send_message(Result.new(id: message[:id], response: response))
|
@@ -604,6 +612,11 @@ module RubyLsp
|
|
604
612
|
# don't want to format it
|
605
613
|
path = uri.to_standardized_path
|
606
614
|
unless path.nil? || path.start_with?(@global_state.workspace_path)
|
615
|
+
send_log_message(<<~MESSAGE)
|
616
|
+
Ignoring formatting request for file outside of the workspace.
|
617
|
+
Workspace path was set by editor as #{@global_state.workspace_path}.
|
618
|
+
File path requested for formatting was #{path}
|
619
|
+
MESSAGE
|
607
620
|
send_empty_response(message[:id])
|
608
621
|
return
|
609
622
|
end
|