ruby-lsp 0.21.3 → 0.22.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|