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
@@ -1,4 +1,4 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "json"
|
@@ -7,14 +7,17 @@ require "delegate"
|
|
7
7
|
|
8
8
|
module RubyLsp
|
9
9
|
module Rails
|
10
|
+
# @requires_ancestor: ServerComponent
|
10
11
|
module Common
|
11
12
|
class Progress
|
13
|
+
#: (IO | StringIO, String, bool) -> void
|
12
14
|
def initialize(stderr, id, supports_progress)
|
13
15
|
@stderr = stderr
|
14
16
|
@id = id
|
15
17
|
@supports_progress = supports_progress
|
16
18
|
end
|
17
19
|
|
20
|
+
#: (percentage: Integer?, message: String?) -> void
|
18
21
|
def report(percentage: nil, message: nil)
|
19
22
|
return unless @supports_progress
|
20
23
|
return unless percentage || message
|
@@ -37,23 +40,27 @@ module RubyLsp
|
|
37
40
|
|
38
41
|
# Log a message to the editor's output panel. The type is the number of the message type, which can be found in
|
39
42
|
# the specification https://microsoft.github.io/language-server-protocol/specification/#messageType
|
43
|
+
#: (String, type: Integer) -> void
|
40
44
|
def log_message(message, type: 4)
|
41
45
|
send_notification({ method: "window/logMessage", params: { type: type, message: message } })
|
42
46
|
end
|
43
47
|
|
44
48
|
# Sends an error result to a request, if the request failed. DO NOT INVOKE THIS METHOD FOR NOTIFICATIONS! Use
|
45
49
|
# `log_message` instead, otherwise the client/server communication will go out of sync
|
50
|
+
#: (String) -> void
|
46
51
|
def send_error_response(message)
|
47
52
|
send_message({ error: message })
|
48
53
|
end
|
49
54
|
|
50
55
|
# Sends a result back to the client
|
56
|
+
#: (Hash[Symbol | String, untyped]?) -> void
|
51
57
|
def send_result(result)
|
52
58
|
send_message({ result: result })
|
53
59
|
end
|
54
60
|
|
55
61
|
# Handle possible errors for a request. This should only be used for requests, which means messages that return a
|
56
62
|
# response back to the client. Errors are returned as an error object back to the client
|
63
|
+
#: (String) { () -> void } -> void
|
57
64
|
def with_request_error_handling(request_name, &block)
|
58
65
|
block.call
|
59
66
|
rescue ActiveRecord::ConnectionNotEstablished
|
@@ -67,6 +74,7 @@ module RubyLsp
|
|
67
74
|
|
68
75
|
# Handle possible errors for a notification. This should only be used for notifications, which means messages that
|
69
76
|
# do not return a response back to the client. Errors are logged to the editor's output panel
|
77
|
+
#: (String) { () -> void } -> void
|
70
78
|
def with_notification_error_handling(notification_name, &block)
|
71
79
|
block.call
|
72
80
|
rescue ActiveRecord::ConnectionNotEstablished
|
@@ -78,8 +86,9 @@ module RubyLsp
|
|
78
86
|
log_message("Request #{notification_name} failed:\n#{e.full_message(highlight: false)}")
|
79
87
|
end
|
80
88
|
|
89
|
+
#: (String, String, percentage: Integer?, message: String?) -> void
|
81
90
|
def begin_progress(id, title, percentage: nil, message: nil)
|
82
|
-
return unless
|
91
|
+
return unless capabilities[:supports_progress]
|
83
92
|
|
84
93
|
# This is actually a request, but it is sent asynchronously and we do not return the response back to the
|
85
94
|
# server, so we consider it a notification from the perspective of the client/runtime server dynamic
|
@@ -103,8 +112,9 @@ module RubyLsp
|
|
103
112
|
})
|
104
113
|
end
|
105
114
|
|
115
|
+
#: (String, percentage: Integer?, message: String?) -> void
|
106
116
|
def report_progress(id, percentage: nil, message: nil)
|
107
|
-
return unless
|
117
|
+
return unless capabilities[:supports_progress]
|
108
118
|
|
109
119
|
send_notification({
|
110
120
|
method: "$/progress",
|
@@ -119,8 +129,9 @@ module RubyLsp
|
|
119
129
|
})
|
120
130
|
end
|
121
131
|
|
132
|
+
#: (String) -> void
|
122
133
|
def end_progress(id)
|
123
|
-
return unless
|
134
|
+
return unless capabilities[:supports_progress]
|
124
135
|
|
125
136
|
send_notification({
|
126
137
|
method: "$/progress",
|
@@ -131,9 +142,10 @@ module RubyLsp
|
|
131
142
|
})
|
132
143
|
end
|
133
144
|
|
145
|
+
#: (String, String, percentage: Integer?, message: String?) { (Progress) -> void } -> void
|
134
146
|
def with_progress(id, title, percentage: nil, message: nil, &block)
|
135
|
-
progress_block = Progress.new(
|
136
|
-
return block.call(progress_block) unless
|
147
|
+
progress_block = Progress.new(stderr, id, capabilities[:supports_progress])
|
148
|
+
return block.call(progress_block) unless capabilities[:supports_progress]
|
137
149
|
|
138
150
|
begin_progress(id, title, percentage: percentage, message: message)
|
139
151
|
block.call(progress_block)
|
@@ -143,86 +155,113 @@ module RubyLsp
|
|
143
155
|
private
|
144
156
|
|
145
157
|
# Write a response message back to the client
|
158
|
+
#: (Hash[String | Symbol, untyped]) -> void
|
146
159
|
def send_message(message)
|
147
160
|
json_message = message.to_json
|
148
|
-
|
161
|
+
stdout.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
149
162
|
end
|
150
163
|
|
151
164
|
# Write a notification to the client to be transmitted to the editor
|
165
|
+
#: (Hash[String | Symbol, untyped]) -> void
|
152
166
|
def send_notification(message)
|
153
167
|
json_message = message.to_json
|
154
|
-
|
168
|
+
stderr.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
155
169
|
end
|
156
170
|
end
|
157
171
|
|
158
|
-
class
|
172
|
+
class ServerComponent
|
173
|
+
#: IO | StringIO
|
174
|
+
attr_reader :stdout
|
175
|
+
|
176
|
+
#: IO | StringIO
|
177
|
+
attr_reader :stderr
|
178
|
+
|
179
|
+
#: Hash[Symbol | String, untyped]
|
180
|
+
attr_reader :capabilities
|
181
|
+
|
182
|
+
#: (IO | StringIO, IO | StringIO, Hash[Symbol | String, untyped]) -> void
|
183
|
+
def initialize(stdout, stderr, capabilities)
|
184
|
+
@stdout = stdout
|
185
|
+
@stderr = stderr
|
186
|
+
@capabilities = capabilities
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class ServerAddon < ServerComponent
|
159
191
|
include Common
|
160
192
|
|
161
|
-
@server_addon_classes = []
|
162
|
-
@server_addons = {}
|
193
|
+
@server_addon_classes = [] #: Array[singleton(ServerAddon)]
|
194
|
+
@server_addons = {} #: Hash[String, ServerAddon]
|
163
195
|
|
164
196
|
class << self
|
165
197
|
# We keep track of runtime server add-ons the same way we track other add-ons, by storing classes that inherit
|
166
198
|
# from the base one
|
199
|
+
#: (singleton(ServerAddon)) -> void
|
167
200
|
def inherited(child)
|
168
201
|
@server_addon_classes << child
|
169
202
|
super
|
170
203
|
end
|
171
204
|
|
172
205
|
# Delegate `request` with `params` to the server add-on with the given `name`
|
206
|
+
#: (String, String, Hash[Symbol | String, untyped]) -> void
|
173
207
|
def delegate(name, request, params)
|
174
208
|
@server_addons[name]&.execute(request, params)
|
175
209
|
end
|
176
210
|
|
177
211
|
# Instantiate all server addons and store them in a hash for easy access after we have discovered the classes
|
212
|
+
#: (IO | StringIO, IO | StringIO, Hash[Symbol | String, untyped]) -> void
|
178
213
|
def finalize_registrations!(stdout, stderr, capabilities)
|
179
214
|
until @server_addon_classes.empty?
|
180
|
-
addon = @server_addon_classes.shift
|
215
|
+
addon = @server_addon_classes.shift #: as !nil
|
216
|
+
.new(stdout, stderr, capabilities)
|
181
217
|
@server_addons[addon.name] = addon
|
182
218
|
end
|
183
219
|
end
|
184
220
|
end
|
185
221
|
|
186
|
-
|
187
|
-
@stdout = stdout
|
188
|
-
@stderr = stderr
|
189
|
-
@capabilities = capabilities
|
190
|
-
end
|
191
|
-
|
222
|
+
#: -> String
|
192
223
|
def name
|
193
224
|
raise NotImplementedError, "Not implemented!"
|
194
225
|
end
|
195
226
|
|
227
|
+
#: (String, Hash[String | Symbol, untyped]) -> untyped
|
196
228
|
def execute(request, params)
|
197
229
|
raise NotImplementedError, "Not implemented!"
|
198
230
|
end
|
199
231
|
end
|
200
232
|
|
201
233
|
class IOWrapper < SimpleDelegator
|
234
|
+
#: (untyped) -> void
|
202
235
|
def puts(*args)
|
203
236
|
args.each { |arg| log("#{arg}\n") }
|
204
237
|
end
|
205
238
|
|
239
|
+
#: (untyped) -> void
|
206
240
|
def print(*args)
|
207
241
|
args.each { |arg| log(arg.to_s) }
|
208
242
|
end
|
209
243
|
|
210
244
|
private
|
211
245
|
|
246
|
+
#: (untyped) -> void
|
212
247
|
def log(message)
|
213
248
|
json_message = { method: "window/logMessage", params: { type: 4, message: message } }.to_json
|
214
|
-
|
249
|
+
|
250
|
+
self #: as untyped # rubocop:disable Style/RedundantSelf
|
251
|
+
.write("Content-Length: #{json_message.bytesize}\r\n\r\n#{json_message}")
|
215
252
|
end
|
216
253
|
end
|
217
254
|
|
218
|
-
class Server
|
255
|
+
class Server < ServerComponent
|
219
256
|
include Common
|
220
257
|
|
258
|
+
#: (IO | StringIO, IO | StringIO, bool, Hash[Symbol | String, untyped]) -> void
|
221
259
|
def initialize(stdout: $stdout, stderr: $stderr, override_default_output_device: true, capabilities: {})
|
222
260
|
# Grab references to the original pipes so that we can change the default output device further down
|
223
|
-
|
224
|
-
@
|
225
|
-
|
261
|
+
|
262
|
+
@stdin = $stdin #: IO
|
263
|
+
super(stdout, stderr, capabilities)
|
264
|
+
|
226
265
|
@stdin.sync = true
|
227
266
|
@stdout.sync = true
|
228
267
|
@stderr.sync = true
|
@@ -230,31 +269,31 @@ module RubyLsp
|
|
230
269
|
@stdout.binmode
|
231
270
|
@stderr.binmode
|
232
271
|
|
233
|
-
# A hash containing the capabilities of the editor that may be relevant for the runtime server
|
234
|
-
@capabilities = capabilities
|
235
|
-
|
236
272
|
# # Set the default output device to be $stderr. This means that using `puts` by itself will default to printing
|
237
273
|
# # to $stderr and only explicit `$stdout.puts` will go to $stdout. This reduces the chance that output coming
|
238
274
|
# # from the Rails app will be accidentally sent to the client
|
239
275
|
$> = IOWrapper.new(@stderr) if override_default_output_device
|
240
276
|
|
241
|
-
@running = true
|
277
|
+
@running = true #: bool
|
278
|
+
@database_supports_indexing = nil #: bool?
|
242
279
|
end
|
243
280
|
|
281
|
+
#: -> void
|
244
282
|
def start
|
245
283
|
load_routes
|
246
284
|
clear_file_system_resolver_hooks
|
247
285
|
send_result({ message: "ok", root: ::Rails.root.to_s })
|
248
286
|
|
249
287
|
while @running
|
250
|
-
headers = @stdin.gets("\r\n\r\n")
|
251
|
-
json = @stdin.read(headers[/Content-Length: (\d+)/i, 1].to_i)
|
288
|
+
headers = @stdin.gets("\r\n\r\n") #: as String
|
289
|
+
json = @stdin.read(headers[/Content-Length: (\d+)/i, 1].to_i) #: as String
|
252
290
|
|
253
291
|
request = JSON.parse(json, symbolize_names: true)
|
254
292
|
execute(request.fetch(:method), request[:params])
|
255
293
|
end
|
256
294
|
end
|
257
295
|
|
296
|
+
#: (String, Hash[Symbol | String, untyped]) -> void
|
258
297
|
def execute(request, params)
|
259
298
|
case request
|
260
299
|
when "shutdown"
|
@@ -306,6 +345,7 @@ module RubyLsp
|
|
306
345
|
|
307
346
|
private
|
308
347
|
|
348
|
+
#: (Hash[Symbol | String, untyped]) -> Hash[Symbol | String, untyped]?
|
309
349
|
def resolve_route_info(requirements)
|
310
350
|
if requirements[:controller]
|
311
351
|
requirements[:controller] = requirements.fetch(:controller).underscore.delete_suffix("_controller")
|
@@ -334,6 +374,7 @@ module RubyLsp
|
|
334
374
|
# We also check that it's enabled.
|
335
375
|
if ActionDispatch::Routing::Mapper.respond_to?(:route_source_locations) &&
|
336
376
|
ActionDispatch::Routing::Mapper.route_source_locations
|
377
|
+
#: (String) -> Hash[Symbol | String, untyped]?
|
337
378
|
def route_location(name)
|
338
379
|
# In Rails 8, Rails.application.routes.named_routes is not populated by default
|
339
380
|
if ::Rails.application.respond_to?(:reload_routes_unless_loaded)
|
@@ -352,11 +393,13 @@ module RubyLsp
|
|
352
393
|
{ location: ::Rails.root.join(route.source_location).to_s }
|
353
394
|
end
|
354
395
|
else
|
396
|
+
#: (String) -> Hash[Symbol | String, untyped]?
|
355
397
|
def route_location(name)
|
356
398
|
nil
|
357
399
|
end
|
358
400
|
end
|
359
401
|
|
402
|
+
#: (String) -> Hash[Symbol | String, untyped]?
|
360
403
|
def resolve_database_info_from_model(model_name)
|
361
404
|
const = ActiveSupport::Inflector.safe_constantize(model_name)
|
362
405
|
return unless active_record_model?(const)
|
@@ -364,6 +407,8 @@ module RubyLsp
|
|
364
407
|
info = {
|
365
408
|
columns: const.columns.map { |column| [column.name, column.type, column.default, column.null] },
|
366
409
|
primary_keys: Array(const.primary_key),
|
410
|
+
foreign_keys: collect_model_foreign_keys(const),
|
411
|
+
indexes: collect_model_indexes(const),
|
367
412
|
}
|
368
413
|
|
369
414
|
if ActiveRecord::Tasks::DatabaseTasks.respond_to?(:schema_dump_path)
|
@@ -373,28 +418,33 @@ module RubyLsp
|
|
373
418
|
info
|
374
419
|
end
|
375
420
|
|
421
|
+
#: (Hash[Symbol | String, untyped]) -> Hash[Symbol | String, untyped]?
|
376
422
|
def resolve_association_target(params)
|
377
423
|
const = ActiveSupport::Inflector.safe_constantize(params[:model_name])
|
378
424
|
return unless active_record_model?(const)
|
379
425
|
|
380
426
|
association_klass = const.reflect_on_association(params[:association_name].intern).klass
|
381
427
|
source_location = Object.const_source_location(association_klass.to_s)
|
428
|
+
return unless source_location
|
382
429
|
|
383
|
-
{ location: source_location
|
430
|
+
{ location: "#{source_location[0]}:#{source_location[1]}" }
|
384
431
|
rescue NameError
|
385
432
|
nil
|
386
433
|
end
|
387
434
|
|
435
|
+
#: (Module?) -> bool
|
388
436
|
def active_record_model?(const)
|
389
437
|
!!(
|
390
438
|
const &&
|
391
439
|
defined?(ActiveRecord) &&
|
392
440
|
const.is_a?(Class) &&
|
393
441
|
ActiveRecord::Base > const && # We do this 'backwards' in case the class overwrites `<`
|
394
|
-
!const
|
442
|
+
!const #: as singleton(ActiveRecord::Base)
|
443
|
+
.abstract_class?
|
395
444
|
)
|
396
445
|
end
|
397
446
|
|
447
|
+
#: -> String?
|
398
448
|
def pending_migrations_message
|
399
449
|
# `check_all_pending!` is only available since Rails 7.1
|
400
450
|
return unless defined?(ActiveRecord) && ActiveRecord::Migration.respond_to?(:check_all_pending!)
|
@@ -405,6 +455,7 @@ module RubyLsp
|
|
405
455
|
e.message
|
406
456
|
end
|
407
457
|
|
458
|
+
#: -> Hash[Symbol | String, untyped]
|
408
459
|
def run_migrations
|
409
460
|
# Running migrations invokes `load` which will repeatedly load the same files. It's not designed to be invoked
|
410
461
|
# multiple times within the same process. To avoid any memory bloat, we run migrations in a separate process
|
@@ -416,6 +467,7 @@ module RubyLsp
|
|
416
467
|
{ message: stdout, status: status.exitstatus }
|
417
468
|
end
|
418
469
|
|
470
|
+
#: -> void
|
419
471
|
def load_routes
|
420
472
|
with_notification_error_handling("initial_load_routes") do
|
421
473
|
# Load routes if they haven't been loaded yet (see https://github.com/rails/rails/pull/51614).
|
@@ -428,6 +480,7 @@ module RubyLsp
|
|
428
480
|
# watches files. Since the Rails application is already booted by the time we reach this script, we can't no-op
|
429
481
|
# the file watcher implementation. Instead, we clear the hooks to prevent the registered file watchers from being
|
430
482
|
# instantiated
|
483
|
+
#: -> void
|
431
484
|
def clear_file_system_resolver_hooks
|
432
485
|
return unless defined?(::ActionView::PathRegistry)
|
433
486
|
|
@@ -435,6 +488,39 @@ module RubyLsp
|
|
435
488
|
::ActionView::PathRegistry.file_system_resolver_hooks.clear
|
436
489
|
end
|
437
490
|
end
|
491
|
+
|
492
|
+
#: (singleton(ActiveRecord::Base)) -> Array[String]
|
493
|
+
def collect_model_foreign_keys(model)
|
494
|
+
return [] unless model.connection.respond_to?(:supports_foreign_keys?) &&
|
495
|
+
model.connection.supports_foreign_keys?
|
496
|
+
|
497
|
+
model.connection.foreign_keys(model.table_name).map do |key_definition|
|
498
|
+
key_definition.options[:column]
|
499
|
+
end
|
500
|
+
end
|
501
|
+
|
502
|
+
#: (singleton(ActiveRecord::Base)) -> Array[Hash[Symbol, untyped]]
|
503
|
+
def collect_model_indexes(model)
|
504
|
+
return [] unless database_supports_indexing?(model)
|
505
|
+
|
506
|
+
model.connection.indexes(model.table_name).map do |index_definition|
|
507
|
+
{
|
508
|
+
name: index_definition.name,
|
509
|
+
columns: index_definition.columns,
|
510
|
+
unique: index_definition.unique,
|
511
|
+
}
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
#: (singleton(ActiveRecord::Base)) -> bool
|
516
|
+
def database_supports_indexing?(model)
|
517
|
+
return @database_supports_indexing unless @database_supports_indexing.nil?
|
518
|
+
|
519
|
+
model.connection.indexes(model.table_name)
|
520
|
+
@database_supports_indexing = true
|
521
|
+
rescue NotImplementedError
|
522
|
+
@database_supports_indexing = false
|
523
|
+
end
|
438
524
|
end
|
439
525
|
end
|
440
526
|
end
|
@@ -4,9 +4,7 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Rails
|
6
6
|
module ActiveSupportTestCaseHelper
|
7
|
-
|
8
|
-
|
9
|
-
sig { params(node: Prism::CallNode).returns(T.nilable(String)) }
|
7
|
+
#: (Prism::CallNode node) -> String?
|
10
8
|
def extract_test_case_name(node)
|
11
9
|
message_value = node.message
|
12
10
|
return unless message_value == "test" || message_value == "it"
|
@@ -21,7 +19,8 @@ module RubyLsp
|
|
21
19
|
parts = first_argument.parts
|
22
20
|
|
23
21
|
if parts.all? { |part| part.is_a?(Prism::StringNode) }
|
24
|
-
|
22
|
+
parts #: as Array[Prism::StringNode]
|
23
|
+
.map(&:content).join
|
25
24
|
end
|
26
25
|
when Prism::StringNode
|
27
26
|
first_argument.content
|
@@ -5,15 +5,12 @@ module RubyLsp
|
|
5
5
|
module Rails
|
6
6
|
module Support
|
7
7
|
module Associations
|
8
|
-
ALL =
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
].freeze,
|
15
|
-
T::Array[String],
|
16
|
-
)
|
8
|
+
ALL = [
|
9
|
+
"belongs_to",
|
10
|
+
"has_many",
|
11
|
+
"has_one",
|
12
|
+
"has_and_belongs_to_many",
|
13
|
+
].freeze
|
17
14
|
end
|
18
15
|
end
|
19
16
|
end
|
@@ -5,66 +5,57 @@ module RubyLsp
|
|
5
5
|
module Rails
|
6
6
|
module Support
|
7
7
|
module Callbacks
|
8
|
-
MODELS =
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
].freeze,
|
34
|
-
T::Array[String],
|
35
|
-
)
|
8
|
+
MODELS = [
|
9
|
+
"before_validation",
|
10
|
+
"after_validation",
|
11
|
+
"before_save",
|
12
|
+
"around_save",
|
13
|
+
"after_save",
|
14
|
+
"before_create",
|
15
|
+
"around_create",
|
16
|
+
"after_create",
|
17
|
+
"after_commit",
|
18
|
+
"after_create_commit",
|
19
|
+
"after_update_commit",
|
20
|
+
"after_destroy_commit",
|
21
|
+
"after_save_commit",
|
22
|
+
"after_rollback",
|
23
|
+
"before_update",
|
24
|
+
"around_update",
|
25
|
+
"after_update",
|
26
|
+
"before_destroy",
|
27
|
+
"around_destroy",
|
28
|
+
"after_destroy",
|
29
|
+
"after_initialize",
|
30
|
+
"after_find",
|
31
|
+
"after_touch",
|
32
|
+
].freeze
|
36
33
|
|
37
|
-
CONTROLLERS =
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
].freeze,
|
52
|
-
T::Array[String],
|
53
|
-
)
|
34
|
+
CONTROLLERS = [
|
35
|
+
"after_action",
|
36
|
+
"append_after_action",
|
37
|
+
"append_around_action",
|
38
|
+
"append_before_action",
|
39
|
+
"around_action",
|
40
|
+
"before_action",
|
41
|
+
"prepend_after_action",
|
42
|
+
"prepend_around_action",
|
43
|
+
"prepend_before_action",
|
44
|
+
"skip_after_action",
|
45
|
+
"skip_around_action",
|
46
|
+
"skip_before_action",
|
47
|
+
].freeze
|
54
48
|
|
55
|
-
JOBS =
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
].freeze,
|
64
|
-
T::Array[String],
|
65
|
-
)
|
49
|
+
JOBS = [
|
50
|
+
"after_enqueue",
|
51
|
+
"after_perform",
|
52
|
+
"around_enqueue",
|
53
|
+
"around_perform",
|
54
|
+
"before_enqueue",
|
55
|
+
"before_perform",
|
56
|
+
].freeze
|
66
57
|
|
67
|
-
ALL =
|
58
|
+
ALL = (MODELS + CONTROLLERS + JOBS).freeze #: Array[String]
|
68
59
|
end
|
69
60
|
end
|
70
61
|
end
|
@@ -6,9 +6,7 @@ module RubyLsp
|
|
6
6
|
module Support
|
7
7
|
class LocationBuilder
|
8
8
|
class << self
|
9
|
-
|
10
|
-
|
11
|
-
sig { params(location_string: String).returns(Interface::Location) }
|
9
|
+
#: (String location_string) -> Interface::Location
|
12
10
|
def line_location_from_s(location_string)
|
13
11
|
*file_parts, line = location_string.split(":")
|
14
12
|
raise ArgumentError, "Invalid location string given" if file_parts.empty?
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: ruby-lsp
|
@@ -15,7 +15,7 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.23.
|
18
|
+
version: 0.23.16
|
19
19
|
- - "<"
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: 0.24.0
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.23.
|
28
|
+
version: 0.23.16
|
29
29
|
- - "<"
|
30
30
|
- !ruby/object:Gem::Version
|
31
31
|
version: 0.24.0
|
@@ -47,6 +47,7 @@ files:
|
|
47
47
|
- lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb
|
48
48
|
- lib/ruby_lsp/ruby_lsp_rails/hover.rb
|
49
49
|
- lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb
|
50
|
+
- lib/ruby_lsp/ruby_lsp_rails/rails_test_style.rb
|
50
51
|
- lib/ruby_lsp/ruby_lsp_rails/runner_client.rb
|
51
52
|
- lib/ruby_lsp/ruby_lsp_rails/server.rb
|
52
53
|
- lib/ruby_lsp/ruby_lsp_rails/support/active_support_test_case_helper.rb
|
@@ -78,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
78
79
|
- !ruby/object:Gem::Version
|
79
80
|
version: '0'
|
80
81
|
requirements: []
|
81
|
-
rubygems_version: 3.6.
|
82
|
+
rubygems_version: 3.6.8
|
82
83
|
specification_version: 4
|
83
84
|
summary: A Ruby LSP addon for Rails
|
84
85
|
test_files: []
|