ruby-lsp-rails 0.4.0 → 0.4.2
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/Rakefile +1 -1
- data/lib/ruby_lsp/ruby_lsp_rails/addon.rb +59 -68
- data/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb +23 -30
- data/lib/ruby_lsp/ruby_lsp_rails/completion.rb +7 -15
- data/lib/ruby_lsp/ruby_lsp_rails/definition.rb +13 -22
- data/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb +24 -30
- data/lib/ruby_lsp/ruby_lsp_rails/hover.rb +41 -29
- data/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb +7 -20
- data/lib/ruby_lsp/ruby_lsp_rails/rails_test_style.rb +150 -0
- data/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +64 -79
- data/lib/ruby_lsp/ruby_lsp_rails/server.rb +117 -31
- data/lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb +3 -4
- data/lib/ruby_lsp/ruby_lsp_rails/support/associations.rb +6 -9
- data/lib/ruby_lsp/ruby_lsp_rails/support/callbacks.rb +48 -57
- data/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb +1 -3
- data/lib/ruby_lsp_rails/version.rb +1 -1
- metadata +6 -5
@@ -8,9 +8,7 @@ module RubyLsp
|
|
8
8
|
module Rails
|
9
9
|
class RunnerClient
|
10
10
|
class << self
|
11
|
-
|
12
|
-
|
13
|
-
sig { params(outgoing_queue: Thread::Queue, global_state: RubyLsp::GlobalState).returns(RunnerClient) }
|
11
|
+
#: (Thread::Queue outgoing_queue, RubyLsp::GlobalState global_state) -> RunnerClient
|
14
12
|
def create_client(outgoing_queue, global_state)
|
15
13
|
if File.exist?("bin/rails")
|
16
14
|
new(outgoing_queue, global_state)
|
@@ -46,15 +44,13 @@ module RubyLsp
|
|
46
44
|
class MessageError < StandardError; end
|
47
45
|
class EmptyMessageError < MessageError; end
|
48
46
|
|
49
|
-
|
50
|
-
|
51
|
-
sig { returns(String) }
|
47
|
+
#: String
|
52
48
|
attr_reader :rails_root
|
53
49
|
|
54
|
-
|
50
|
+
#: (Thread::Queue outgoing_queue, RubyLsp::GlobalState global_state) -> void
|
55
51
|
def initialize(outgoing_queue, global_state)
|
56
|
-
@outgoing_queue =
|
57
|
-
@mutex =
|
52
|
+
@outgoing_queue = outgoing_queue #: Thread::Queue
|
53
|
+
@mutex = Mutex.new #: Mutex
|
58
54
|
# Spring needs a Process session ID. It uses this ID to "attach" itself to the parent process, so that when the
|
59
55
|
# parent ends, the spring process ends as well. If this is not set, Spring will throw an error while trying to
|
60
56
|
# set its own session ID
|
@@ -82,21 +78,21 @@ module RubyLsp
|
|
82
78
|
)
|
83
79
|
end
|
84
80
|
|
85
|
-
@stdin =
|
86
|
-
@stdout =
|
87
|
-
@stderr =
|
81
|
+
@stdin = stdin #: IO
|
82
|
+
@stdout = stdout #: IO
|
83
|
+
@stderr = stderr #: IO
|
88
84
|
@stdin.sync = true
|
89
85
|
@stdout.sync = true
|
90
86
|
@stderr.sync = true
|
91
|
-
@wait_thread =
|
87
|
+
@wait_thread = wait_thread #: Process::Waiter
|
92
88
|
|
93
89
|
# We set binmode for Windows compatibility
|
94
90
|
@stdin.binmode
|
95
91
|
@stdout.binmode
|
96
92
|
@stderr.binmode
|
97
93
|
|
98
|
-
initialize_response =
|
99
|
-
@rails_root =
|
94
|
+
initialize_response = read_response #: as !nil
|
95
|
+
@rails_root = initialize_response[:root] #: String
|
100
96
|
log_message("Finished booting Ruby LSP Rails server")
|
101
97
|
|
102
98
|
unless ENV["RAILS_ENV"] == "test"
|
@@ -110,25 +106,22 @@ module RubyLsp
|
|
110
106
|
|
111
107
|
# Responsible for transmitting notifications coming from the server to the outgoing queue, so that we can do
|
112
108
|
# things such as showing progress notifications initiated by the server
|
113
|
-
@notifier_thread =
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
@outgoing_queue << notification
|
120
|
-
end
|
109
|
+
@notifier_thread = Thread.new do
|
110
|
+
until @stderr.closed?
|
111
|
+
notification = read_notification
|
112
|
+
|
113
|
+
unless @outgoing_queue.closed? || !notification
|
114
|
+
@outgoing_queue << notification
|
121
115
|
end
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
)
|
116
|
+
end
|
117
|
+
rescue IOError
|
118
|
+
# The server was shutdown and stderr is already closed
|
119
|
+
end #: Thread
|
127
120
|
rescue StandardError
|
128
121
|
raise InitializationError, @stderr.read
|
129
122
|
end
|
130
123
|
|
131
|
-
|
124
|
+
#: (String server_addon_path) -> void
|
132
125
|
def register_server_addon(server_addon_path)
|
133
126
|
send_notification("server_addon/register", server_addon_path: server_addon_path)
|
134
127
|
rescue MessageError
|
@@ -139,7 +132,7 @@ module RubyLsp
|
|
139
132
|
nil
|
140
133
|
end
|
141
134
|
|
142
|
-
|
135
|
+
#: (String name) -> Hash[Symbol, untyped]?
|
143
136
|
def model(name)
|
144
137
|
make_request("model", name: name)
|
145
138
|
rescue MessageError
|
@@ -150,12 +143,7 @@ module RubyLsp
|
|
150
143
|
nil
|
151
144
|
end
|
152
145
|
|
153
|
-
|
154
|
-
params(
|
155
|
-
model_name: String,
|
156
|
-
association_name: String,
|
157
|
-
).returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
158
|
-
end
|
146
|
+
#: (model_name: String, association_name: String) -> Hash[Symbol, untyped]?
|
159
147
|
def association_target_location(model_name:, association_name:)
|
160
148
|
make_request(
|
161
149
|
"association_target_location",
|
@@ -170,7 +158,7 @@ module RubyLsp
|
|
170
158
|
nil
|
171
159
|
end
|
172
160
|
|
173
|
-
|
161
|
+
#: (String name) -> Hash[Symbol, untyped]?
|
174
162
|
def route_location(name)
|
175
163
|
make_request("route_location", name: name)
|
176
164
|
rescue MessageError
|
@@ -181,7 +169,7 @@ module RubyLsp
|
|
181
169
|
nil
|
182
170
|
end
|
183
171
|
|
184
|
-
|
172
|
+
#: (controller: String, action: String) -> Hash[Symbol, untyped]?
|
185
173
|
def route(controller:, action:)
|
186
174
|
make_request("route_info", controller: controller, action: action)
|
187
175
|
rescue MessageError
|
@@ -193,7 +181,7 @@ module RubyLsp
|
|
193
181
|
end
|
194
182
|
|
195
183
|
# Delegates a notification to a server add-on
|
196
|
-
|
184
|
+
#: (server_addon_name: String, request_name: String, **untyped params) -> void
|
197
185
|
def delegate_notification(server_addon_name:, request_name:, **params)
|
198
186
|
send_notification(
|
199
187
|
"server_addon/delegate",
|
@@ -203,7 +191,7 @@ module RubyLsp
|
|
203
191
|
)
|
204
192
|
end
|
205
193
|
|
206
|
-
|
194
|
+
#: -> String?
|
207
195
|
def pending_migrations_message
|
208
196
|
response = make_request("pending_migrations_message")
|
209
197
|
response[:pending_migrations_message] if response
|
@@ -215,7 +203,7 @@ module RubyLsp
|
|
215
203
|
nil
|
216
204
|
end
|
217
205
|
|
218
|
-
|
206
|
+
#: -> Hash[Symbol, untyped]?
|
219
207
|
def run_migrations
|
220
208
|
make_request("run_migrations")
|
221
209
|
rescue MessageError
|
@@ -227,13 +215,7 @@ module RubyLsp
|
|
227
215
|
end
|
228
216
|
|
229
217
|
# Delegates a request to a server add-on
|
230
|
-
|
231
|
-
params(
|
232
|
-
server_addon_name: String,
|
233
|
-
request_name: String,
|
234
|
-
params: T.untyped,
|
235
|
-
).returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
236
|
-
end
|
218
|
+
#: (server_addon_name: String, request_name: String, **untyped params) -> Hash[Symbol, untyped]?
|
237
219
|
def delegate_request(server_addon_name:, request_name:, **params)
|
238
220
|
make_request(
|
239
221
|
"server_addon/delegate",
|
@@ -245,7 +227,7 @@ module RubyLsp
|
|
245
227
|
nil
|
246
228
|
end
|
247
229
|
|
248
|
-
|
230
|
+
#: -> void
|
249
231
|
def trigger_reload
|
250
232
|
log_message("Reloading Rails application")
|
251
233
|
send_notification("reload")
|
@@ -257,7 +239,7 @@ module RubyLsp
|
|
257
239
|
nil
|
258
240
|
end
|
259
241
|
|
260
|
-
|
242
|
+
#: -> void
|
261
243
|
def shutdown
|
262
244
|
log_message("Ruby LSP Rails shutting down server")
|
263
245
|
send_message("shutdown")
|
@@ -268,34 +250,30 @@ module RubyLsp
|
|
268
250
|
force_kill
|
269
251
|
end
|
270
252
|
|
271
|
-
|
253
|
+
#: -> bool
|
272
254
|
def stopped?
|
273
255
|
[@stdin, @stdout, @stderr].all?(&:closed?) && !@wait_thread.alive?
|
274
256
|
end
|
275
257
|
|
276
|
-
|
258
|
+
#: -> bool
|
277
259
|
def connected?
|
278
260
|
true
|
279
261
|
end
|
280
262
|
|
281
263
|
private
|
282
264
|
|
283
|
-
|
284
|
-
params(
|
285
|
-
request: String,
|
286
|
-
params: T.untyped,
|
287
|
-
).returns(T.nilable(T::Hash[Symbol, T.untyped]))
|
288
|
-
end
|
265
|
+
#: (String request, **untyped params) -> Hash[Symbol, untyped]?
|
289
266
|
def make_request(request, **params)
|
290
267
|
send_message(request, **params)
|
291
268
|
read_response
|
292
269
|
end
|
293
270
|
|
294
271
|
# Notifications are like messages, but one-way, with no response sent back.
|
295
|
-
|
272
|
+
#: (String request, **untyped params) -> void
|
296
273
|
def send_notification(request, **params) = send_message(request, **params)
|
297
274
|
|
298
|
-
|
275
|
+
# @overridable
|
276
|
+
#: (String request, **untyped params) -> void
|
299
277
|
def send_message(request, **params)
|
300
278
|
message = { method: request }
|
301
279
|
message[:params] = params
|
@@ -308,7 +286,8 @@ module RubyLsp
|
|
308
286
|
# The server connection died
|
309
287
|
end
|
310
288
|
|
311
|
-
|
289
|
+
# @overridable
|
290
|
+
#: -> Hash[Symbol, untyped]?
|
312
291
|
def read_response
|
313
292
|
raw_response = @mutex.synchronize do
|
314
293
|
content_length = read_content_length
|
@@ -316,9 +295,9 @@ module RubyLsp
|
|
316
295
|
raise EmptyMessageError unless content_length
|
317
296
|
|
318
297
|
@stdout.read(content_length)
|
319
|
-
end
|
298
|
+
end #: as !nil
|
320
299
|
|
321
|
-
response = JSON.parse(
|
300
|
+
response = JSON.parse(raw_response, symbolize_names: true)
|
322
301
|
|
323
302
|
if response[:error]
|
324
303
|
log_message(
|
@@ -334,20 +313,23 @@ module RubyLsp
|
|
334
313
|
nil
|
335
314
|
end
|
336
315
|
|
337
|
-
|
316
|
+
#: -> void
|
338
317
|
def force_kill
|
339
318
|
# Windows does not support the `TERM` signal, so we're forced to use `KILL` here
|
340
|
-
Process.kill(
|
319
|
+
Process.kill(
|
320
|
+
Signal.list["KILL"], #: as !nil
|
321
|
+
@wait_thread.pid,
|
322
|
+
)
|
341
323
|
end
|
342
324
|
|
343
|
-
|
325
|
+
#: (::String message, ?type: ::Integer) -> void
|
344
326
|
def log_message(message, type: RubyLsp::Constant::MessageType::LOG)
|
345
327
|
return if @outgoing_queue.closed?
|
346
328
|
|
347
329
|
@outgoing_queue << RubyLsp::Notification.window_log_message(message, type: type)
|
348
330
|
end
|
349
331
|
|
350
|
-
|
332
|
+
#: -> Integer?
|
351
333
|
def read_content_length
|
352
334
|
headers = @stdout.gets("\r\n\r\n")
|
353
335
|
return unless headers
|
@@ -359,7 +341,7 @@ module RubyLsp
|
|
359
341
|
end
|
360
342
|
|
361
343
|
# Read a server notification from stderr. Only intended to be used by notifier thread
|
362
|
-
|
344
|
+
#: -> Hash[Symbol, untyped]?
|
363
345
|
def read_notification
|
364
346
|
headers = @stderr.gets("\r\n\r\n")
|
365
347
|
return unless headers
|
@@ -373,7 +355,7 @@ module RubyLsp
|
|
373
355
|
JSON.parse(raw_content, symbolize_names: true)
|
374
356
|
end
|
375
357
|
|
376
|
-
|
358
|
+
#: (GlobalState global_state) -> String
|
377
359
|
def server_relevant_capabilities(global_state)
|
378
360
|
{
|
379
361
|
supports_progress: global_state.client_capabilities.supports_progress,
|
@@ -382,45 +364,48 @@ module RubyLsp
|
|
382
364
|
end
|
383
365
|
|
384
366
|
class NullClient < RunnerClient
|
385
|
-
|
386
|
-
|
387
|
-
sig { void }
|
367
|
+
#: -> void
|
388
368
|
def initialize # rubocop:disable Lint/MissingSuper
|
389
369
|
end
|
390
370
|
|
391
|
-
|
371
|
+
# @override
|
372
|
+
#: -> void
|
392
373
|
def shutdown
|
393
374
|
# no-op
|
394
375
|
end
|
395
376
|
|
396
|
-
|
377
|
+
# @override
|
378
|
+
#: -> bool
|
397
379
|
def stopped?
|
398
380
|
true
|
399
381
|
end
|
400
382
|
|
401
|
-
|
383
|
+
# @override
|
384
|
+
#: -> String
|
402
385
|
def rails_root
|
403
386
|
Dir.pwd
|
404
387
|
end
|
405
388
|
|
406
|
-
|
389
|
+
#: -> bool
|
407
390
|
def connected?
|
408
391
|
false
|
409
392
|
end
|
410
393
|
|
411
394
|
private
|
412
395
|
|
413
|
-
|
396
|
+
#: (::String message, ?type: ::Integer) -> void
|
414
397
|
def log_message(message, type: RubyLsp::Constant::MessageType::LOG)
|
415
398
|
# no-op
|
416
399
|
end
|
417
400
|
|
418
|
-
|
401
|
+
# @override
|
402
|
+
#: (String request, **untyped params) -> void
|
419
403
|
def send_message(request, **params)
|
420
404
|
# no-op
|
421
405
|
end
|
422
406
|
|
423
|
-
|
407
|
+
# @override
|
408
|
+
#: -> Hash[Symbol, untyped]?
|
424
409
|
def read_response
|
425
410
|
# no-op
|
426
411
|
end
|