ruby-lsp-rails 0.3.31 → 0.4.8
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 +74 -66
- data/lib/ruby_lsp/ruby_lsp_rails/code_lens.rb +39 -38
- data/lib/ruby_lsp/ruby_lsp_rails/completion.rb +7 -15
- data/lib/ruby_lsp/ruby_lsp_rails/definition.rb +14 -23
- data/lib/ruby_lsp/ruby_lsp_rails/document_symbol.rb +24 -30
- data/lib/ruby_lsp/ruby_lsp_rails/hover.rb +106 -32
- data/lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb +7 -20
- data/lib/ruby_lsp/ruby_lsp_rails/rails_test_style.rb +171 -0
- data/lib/ruby_lsp/ruby_lsp_rails/runner_client.rb +109 -78
- data/lib/ruby_lsp/ruby_lsp_rails/server.rb +254 -39
- 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 +54 -57
- data/lib/ruby_lsp/ruby_lsp_rails/support/location_builder.rb +1 -3
- data/lib/ruby_lsp_rails/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 03be48ffee8e42576471456d11c3ddd9b483d1795b09adce6faf768bc0c07b8e
|
|
4
|
+
data.tar.gz: 17a31e143ed3b32899004f74bd54d0feb9f8a1284669f5b3448c18e42f2fe6ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7332a6411c36903267d8bcb448513eb21636205ca13290d71c2eeee26efa326c40dca280d639332428e863638e9db0fe12ffbd35f0a5e517ccc1ed777ce6a59b
|
|
7
|
+
data.tar.gz: b1c3e40c0def28339e948db1d336754197e697d1aa483b83e87786fa834f83f3c0088cbf7c3699dc7783df1f20c3ad6a8b1d104ab63e60c7bfb6a4a6962e7fa3
|
data/Rakefile
CHANGED
|
@@ -13,126 +13,131 @@ require_relative "hover"
|
|
|
13
13
|
require_relative "code_lens"
|
|
14
14
|
require_relative "document_symbol"
|
|
15
15
|
require_relative "definition"
|
|
16
|
+
require_relative "rails_test_style"
|
|
16
17
|
require_relative "completion"
|
|
17
18
|
require_relative "indexing_enhancement"
|
|
18
19
|
|
|
19
20
|
module RubyLsp
|
|
20
21
|
module Rails
|
|
21
22
|
class Addon < ::RubyLsp::Addon
|
|
22
|
-
extend T::Sig
|
|
23
|
-
|
|
24
23
|
RUN_MIGRATIONS_TITLE = "Run Migrations"
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
#: -> void
|
|
27
26
|
def initialize
|
|
28
27
|
super
|
|
29
28
|
|
|
30
29
|
# We first initialize the client as a NullClient, so that we can start the server in a background thread. Until
|
|
31
30
|
# the real client is initialized, features that depend on it will not be blocked by using the NullClient
|
|
32
|
-
@rails_runner_client =
|
|
33
|
-
@global_state =
|
|
34
|
-
@outgoing_queue =
|
|
35
|
-
@
|
|
36
|
-
|
|
31
|
+
@rails_runner_client = NullClient.new #: RunnerClient
|
|
32
|
+
@global_state = nil #: GlobalState?
|
|
33
|
+
@outgoing_queue = nil #: Thread::Queue?
|
|
34
|
+
@settings = {
|
|
35
|
+
enablePendingMigrationsPrompt: true,
|
|
36
|
+
} #: Hash[Symbol, untyped],
|
|
37
|
+
|
|
38
|
+
@addon_mutex = Mutex.new #: Mutex
|
|
39
|
+
@client_mutex = Mutex.new #: Mutex
|
|
37
40
|
@client_mutex.lock
|
|
38
41
|
|
|
39
42
|
Thread.new do
|
|
40
43
|
@addon_mutex.synchronize do
|
|
41
44
|
# We need to ensure the Rails client is fully loaded before we activate the server addons
|
|
42
|
-
@client_mutex.synchronize
|
|
45
|
+
@client_mutex.synchronize do
|
|
46
|
+
@rails_runner_client = RunnerClient.create_client(
|
|
47
|
+
@outgoing_queue, #: as !nil
|
|
48
|
+
@global_state, #: as !nil
|
|
49
|
+
)
|
|
50
|
+
end
|
|
43
51
|
offer_to_run_pending_migrations
|
|
44
52
|
end
|
|
45
53
|
end
|
|
46
54
|
end
|
|
47
55
|
|
|
48
|
-
|
|
56
|
+
#: -> RunnerClient
|
|
49
57
|
def rails_runner_client
|
|
50
58
|
@addon_mutex.synchronize { @rails_runner_client }
|
|
51
59
|
end
|
|
52
60
|
|
|
53
|
-
|
|
61
|
+
# @override
|
|
62
|
+
#: (GlobalState global_state, Thread::Queue outgoing_queue) -> void
|
|
54
63
|
def activate(global_state, outgoing_queue)
|
|
55
64
|
@global_state = global_state
|
|
56
65
|
@outgoing_queue = outgoing_queue
|
|
57
66
|
@outgoing_queue << Notification.window_log_message("Activating Ruby LSP Rails add-on v#{VERSION}")
|
|
58
67
|
|
|
68
|
+
addon_settings = @global_state.settings_for_addon(name)
|
|
69
|
+
@settings.merge!(addon_settings) if addon_settings
|
|
70
|
+
|
|
59
71
|
register_additional_file_watchers(global_state: global_state, outgoing_queue: outgoing_queue)
|
|
60
72
|
|
|
61
73
|
# Start booting the real client in a background thread. Until this completes, the client will be a NullClient
|
|
62
74
|
@client_mutex.unlock
|
|
63
75
|
end
|
|
64
76
|
|
|
65
|
-
|
|
77
|
+
# @override
|
|
78
|
+
#: -> void
|
|
66
79
|
def deactivate
|
|
67
80
|
@rails_runner_client.shutdown
|
|
68
81
|
end
|
|
69
82
|
|
|
70
|
-
|
|
83
|
+
# @override
|
|
84
|
+
#: -> String
|
|
71
85
|
def version
|
|
72
86
|
VERSION
|
|
73
87
|
end
|
|
74
88
|
|
|
75
|
-
#
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
).void
|
|
89
|
+
# @override
|
|
90
|
+
#: (ResponseBuilders::TestCollection response_builder, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
|
91
|
+
def create_discover_tests_listener(response_builder, dispatcher, uri)
|
|
92
|
+
return unless @global_state
|
|
93
|
+
|
|
94
|
+
RailsTestStyle.new(response_builder, @global_state, dispatcher, uri)
|
|
82
95
|
end
|
|
83
|
-
|
|
84
|
-
|
|
96
|
+
|
|
97
|
+
# @override
|
|
98
|
+
#: (Array[Hash[Symbol, untyped]]) -> Array[String]
|
|
99
|
+
def resolve_test_commands(items)
|
|
100
|
+
RailsTestStyle.resolve_test_commands(items)
|
|
85
101
|
end
|
|
86
102
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
# Creates a new CodeLens listener. This method is invoked on every CodeLens request
|
|
104
|
+
# @override
|
|
105
|
+
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens] response_builder, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
|
|
106
|
+
def create_code_lens_listener(response_builder, uri, dispatcher)
|
|
107
|
+
return unless @global_state
|
|
108
|
+
|
|
109
|
+
CodeLens.new(@rails_runner_client, @global_state, response_builder, uri, dispatcher)
|
|
93
110
|
end
|
|
111
|
+
|
|
112
|
+
# @override
|
|
113
|
+
#: (ResponseBuilders::Hover response_builder, NodeContext node_context, Prism::Dispatcher dispatcher) -> void
|
|
94
114
|
def create_hover_listener(response_builder, node_context, dispatcher)
|
|
95
|
-
|
|
96
|
-
end
|
|
115
|
+
return unless @global_state
|
|
97
116
|
|
|
98
|
-
|
|
99
|
-
override.params(
|
|
100
|
-
response_builder: ResponseBuilders::DocumentSymbol,
|
|
101
|
-
dispatcher: Prism::Dispatcher,
|
|
102
|
-
).returns(Object)
|
|
117
|
+
Hover.new(@rails_runner_client, response_builder, node_context, @global_state, dispatcher)
|
|
103
118
|
end
|
|
119
|
+
|
|
120
|
+
# @override
|
|
121
|
+
#: (ResponseBuilders::DocumentSymbol response_builder, Prism::Dispatcher dispatcher) -> Object
|
|
104
122
|
def create_document_symbol_listener(response_builder, dispatcher)
|
|
105
123
|
DocumentSymbol.new(response_builder, dispatcher)
|
|
106
124
|
end
|
|
107
125
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
|
|
111
|
-
Interface::Location, Interface::LocationLink
|
|
112
|
-
)],
|
|
113
|
-
uri: URI::Generic,
|
|
114
|
-
node_context: NodeContext,
|
|
115
|
-
dispatcher: Prism::Dispatcher,
|
|
116
|
-
).void
|
|
117
|
-
end
|
|
126
|
+
# @override
|
|
127
|
+
#: (ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)] response_builder, URI::Generic uri, NodeContext node_context, Prism::Dispatcher dispatcher) -> void
|
|
118
128
|
def create_definition_listener(response_builder, uri, node_context, dispatcher)
|
|
119
|
-
|
|
120
|
-
Definition.new(@rails_runner_client, response_builder, node_context, index, dispatcher)
|
|
121
|
-
end
|
|
129
|
+
return unless @global_state
|
|
122
130
|
|
|
123
|
-
|
|
124
|
-
override.params(
|
|
125
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
|
126
|
-
node_context: NodeContext,
|
|
127
|
-
dispatcher: Prism::Dispatcher,
|
|
128
|
-
uri: URI::Generic,
|
|
129
|
-
).void
|
|
131
|
+
Definition.new(@rails_runner_client, response_builder, node_context, @global_state.index, dispatcher)
|
|
130
132
|
end
|
|
133
|
+
|
|
134
|
+
# @override
|
|
135
|
+
#: (ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, NodeContext node_context, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
|
131
136
|
def create_completion_listener(response_builder, node_context, dispatcher, uri)
|
|
132
137
|
Completion.new(@rails_runner_client, response_builder, node_context, dispatcher, uri)
|
|
133
138
|
end
|
|
134
139
|
|
|
135
|
-
|
|
140
|
+
#: (Array[{uri: String, type: Integer}] changes) -> void
|
|
136
141
|
def workspace_did_change_watched_files(changes)
|
|
137
142
|
if changes.any? { |c| c[:uri].end_with?("db/schema.rb") || c[:uri].end_with?("structure.sql") }
|
|
138
143
|
@rails_runner_client.trigger_reload
|
|
@@ -146,12 +151,14 @@ module RubyLsp
|
|
|
146
151
|
end
|
|
147
152
|
end
|
|
148
153
|
|
|
149
|
-
|
|
154
|
+
# @override
|
|
155
|
+
#: -> String
|
|
150
156
|
def name
|
|
151
157
|
"Ruby LSP Rails"
|
|
152
158
|
end
|
|
153
159
|
|
|
154
|
-
|
|
160
|
+
# @override
|
|
161
|
+
#: (String title) -> void
|
|
155
162
|
def handle_window_show_message_response(title)
|
|
156
163
|
if title == RUN_MIGRATIONS_TITLE
|
|
157
164
|
|
|
@@ -178,7 +185,7 @@ module RubyLsp
|
|
|
178
185
|
|
|
179
186
|
private
|
|
180
187
|
|
|
181
|
-
|
|
188
|
+
#: (String id, String title, ?percentage: Integer?, ?message: String?) -> void
|
|
182
189
|
def begin_progress(id, title, percentage: nil, message: nil)
|
|
183
190
|
return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue
|
|
184
191
|
|
|
@@ -196,21 +203,21 @@ module RubyLsp
|
|
|
196
203
|
)
|
|
197
204
|
end
|
|
198
205
|
|
|
199
|
-
|
|
200
|
-
def report_progress(id,
|
|
206
|
+
#: (String id, ?percentage: Integer?, ?message: String?) -> void
|
|
207
|
+
def report_progress(id, percentage: nil, message: nil)
|
|
201
208
|
return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue
|
|
202
209
|
|
|
203
210
|
@outgoing_queue << Notification.progress_report(id, percentage: percentage, message: message)
|
|
204
211
|
end
|
|
205
212
|
|
|
206
|
-
|
|
213
|
+
#: (String id) -> void
|
|
207
214
|
def end_progress(id)
|
|
208
215
|
return unless @global_state&.client_capabilities&.supports_progress && @outgoing_queue
|
|
209
216
|
|
|
210
217
|
@outgoing_queue << Notification.progress_end(id)
|
|
211
218
|
end
|
|
212
219
|
|
|
213
|
-
|
|
220
|
+
#: (global_state: GlobalState, outgoing_queue: Thread::Queue) -> void
|
|
214
221
|
def register_additional_file_watchers(global_state:, outgoing_queue:)
|
|
215
222
|
return unless global_state.client_capabilities.supports_watching_files
|
|
216
223
|
|
|
@@ -231,7 +238,7 @@ module RubyLsp
|
|
|
231
238
|
)
|
|
232
239
|
end
|
|
233
240
|
|
|
234
|
-
|
|
241
|
+
#: -> Interface::FileSystemWatcher
|
|
235
242
|
def structure_sql_file_watcher
|
|
236
243
|
Interface::FileSystemWatcher.new(
|
|
237
244
|
glob_pattern: "**/*structure.sql",
|
|
@@ -239,7 +246,7 @@ module RubyLsp
|
|
|
239
246
|
)
|
|
240
247
|
end
|
|
241
248
|
|
|
242
|
-
|
|
249
|
+
#: -> Interface::FileSystemWatcher
|
|
243
250
|
def fixture_file_watcher
|
|
244
251
|
Interface::FileSystemWatcher.new(
|
|
245
252
|
glob_pattern: "**/fixtures/**/*.{yml,yaml,yml.erb,yaml.erb}",
|
|
@@ -247,10 +254,11 @@ module RubyLsp
|
|
|
247
254
|
)
|
|
248
255
|
end
|
|
249
256
|
|
|
250
|
-
|
|
257
|
+
#: -> void
|
|
251
258
|
def offer_to_run_pending_migrations
|
|
252
259
|
return unless @outgoing_queue
|
|
253
260
|
return unless @global_state&.client_capabilities&.window_show_message_supports_extra_properties
|
|
261
|
+
return unless @settings[:enablePendingMigrationsPrompt]
|
|
254
262
|
|
|
255
263
|
migration_message = @rails_runner_client.pending_migrations_message
|
|
256
264
|
return unless migration_message
|
|
@@ -72,27 +72,18 @@ module RubyLsp
|
|
|
72
72
|
# Note: Complex routing configurations may not be supported.
|
|
73
73
|
#
|
|
74
74
|
class CodeLens
|
|
75
|
-
extend T::Sig
|
|
76
75
|
include Requests::Support::Common
|
|
77
76
|
include ActiveSupportTestCaseHelper
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
params(
|
|
81
|
-
client: RunnerClient,
|
|
82
|
-
global_state: GlobalState,
|
|
83
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens],
|
|
84
|
-
uri: URI::Generic,
|
|
85
|
-
dispatcher: Prism::Dispatcher,
|
|
86
|
-
).void
|
|
87
|
-
end
|
|
78
|
+
#: (RunnerClient, GlobalState, ResponseBuilders::CollectionResponseBuilder[Interface::CodeLens], URI::Generic, Prism::Dispatcher) -> void
|
|
88
79
|
def initialize(client, global_state, response_builder, uri, dispatcher)
|
|
89
80
|
@client = client
|
|
90
81
|
@global_state = global_state
|
|
91
82
|
@response_builder = response_builder
|
|
92
|
-
@path =
|
|
93
|
-
@group_id =
|
|
94
|
-
@group_id_stack =
|
|
95
|
-
@constant_name_stack =
|
|
83
|
+
@path = uri.to_standardized_path #: String?
|
|
84
|
+
@group_id = 1 #: Integer
|
|
85
|
+
@group_id_stack = [] #: Array[Integer]
|
|
86
|
+
@constant_name_stack = [] #: Array[[String, String?]]
|
|
96
87
|
|
|
97
88
|
dispatcher.register(
|
|
98
89
|
self,
|
|
@@ -105,10 +96,12 @@ module RubyLsp
|
|
|
105
96
|
)
|
|
106
97
|
end
|
|
107
98
|
|
|
108
|
-
|
|
99
|
+
#: (Prism::CallNode node) -> void
|
|
109
100
|
def on_call_node_enter(node)
|
|
110
|
-
|
|
101
|
+
# Remove this method once the rollout is complete
|
|
102
|
+
return if @global_state.enabled_feature?(:fullTestDiscovery)
|
|
111
103
|
|
|
104
|
+
content = extract_test_case_name(node)
|
|
112
105
|
return unless content
|
|
113
106
|
|
|
114
107
|
line_number = node.location.start_line
|
|
@@ -117,14 +110,17 @@ module RubyLsp
|
|
|
117
110
|
end
|
|
118
111
|
|
|
119
112
|
# Although uncommon, Rails tests can be written with the classic "def test_name" syntax.
|
|
120
|
-
|
|
113
|
+
#: (Prism::DefNode node) -> void
|
|
121
114
|
def on_def_node_enter(node)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
115
|
+
# Remove this entire unless block once the rollout is complete
|
|
116
|
+
unless @global_state.enabled_feature?(:fullTestDiscovery)
|
|
117
|
+
method_name = node.name.to_s
|
|
118
|
+
|
|
119
|
+
if method_name.start_with?("test_")
|
|
120
|
+
line_number = node.location.start_line
|
|
121
|
+
command = "#{test_command} #{@path}:#{line_number}"
|
|
122
|
+
add_test_code_lens(node, name: method_name, command: command, kind: :example)
|
|
123
|
+
end
|
|
128
124
|
end
|
|
129
125
|
|
|
130
126
|
if controller?
|
|
@@ -133,7 +129,7 @@ module RubyLsp
|
|
|
133
129
|
end
|
|
134
130
|
end
|
|
135
131
|
|
|
136
|
-
|
|
132
|
+
#: (Prism::ClassNode node) -> void
|
|
137
133
|
def on_class_node_enter(node)
|
|
138
134
|
class_name = node.constant_path.slice
|
|
139
135
|
superclass_name = node.superclass&.slice
|
|
@@ -143,7 +139,8 @@ module RubyLsp
|
|
|
143
139
|
# back in a controller context. This part is used in other places in the LSP
|
|
144
140
|
@constant_name_stack << [class_name, superclass_name]
|
|
145
141
|
|
|
146
|
-
if
|
|
142
|
+
# Remove this entire if block once the rollout is complete
|
|
143
|
+
if class_name.end_with?("Test") && !@global_state.enabled_feature?(:fullTestDiscovery)
|
|
147
144
|
fully_qualified_name = @constant_name_stack.map(&:first).join("::")
|
|
148
145
|
command = "#{test_command} #{@path} --name \"/#{Shellwords.escape(fully_qualified_name)}(#|::)/\""
|
|
149
146
|
add_test_code_lens(node, name: class_name, command: command, kind: :group)
|
|
@@ -157,30 +154,32 @@ module RubyLsp
|
|
|
157
154
|
end
|
|
158
155
|
end
|
|
159
156
|
|
|
160
|
-
|
|
157
|
+
#: (Prism::ClassNode node) -> void
|
|
161
158
|
def on_class_node_leave(node)
|
|
162
159
|
class_name = node.constant_path.slice
|
|
163
160
|
|
|
164
161
|
if class_name.end_with?("Test")
|
|
165
162
|
@group_id_stack.pop
|
|
166
163
|
end
|
|
164
|
+
# Remove everything but the `@constant_name_stack.pop` once the rollout is complete
|
|
165
|
+
return if @global_state.enabled_feature?(:fullTestDiscovery)
|
|
167
166
|
|
|
168
167
|
@constant_name_stack.pop
|
|
169
168
|
end
|
|
170
169
|
|
|
171
|
-
|
|
170
|
+
#: (Prism::ModuleNode node) -> void
|
|
172
171
|
def on_module_node_enter(node)
|
|
173
172
|
@constant_name_stack << [node.constant_path.slice, nil]
|
|
174
173
|
end
|
|
175
174
|
|
|
176
|
-
|
|
175
|
+
#: (Prism::ModuleNode node) -> void
|
|
177
176
|
def on_module_node_leave(node)
|
|
178
177
|
@constant_name_stack.pop
|
|
179
178
|
end
|
|
180
179
|
|
|
181
180
|
private
|
|
182
181
|
|
|
183
|
-
|
|
182
|
+
#: -> bool?
|
|
184
183
|
def controller?
|
|
185
184
|
class_name, superclass_name = @constant_name_stack.last
|
|
186
185
|
return false unless class_name && superclass_name
|
|
@@ -188,7 +187,7 @@ module RubyLsp
|
|
|
188
187
|
class_name.end_with?("Controller") && superclass_name.end_with?("Controller")
|
|
189
188
|
end
|
|
190
189
|
|
|
191
|
-
|
|
190
|
+
#: (Prism::DefNode node) -> void
|
|
192
191
|
def add_jump_to_view(node)
|
|
193
192
|
class_name = @constant_name_stack.map(&:first).join("::")
|
|
194
193
|
action_name = node.name
|
|
@@ -216,9 +215,9 @@ module RubyLsp
|
|
|
216
215
|
)
|
|
217
216
|
end
|
|
218
217
|
|
|
219
|
-
|
|
218
|
+
#: (Prism::DefNode node) -> void
|
|
220
219
|
def add_route_code_lens_to_action(node)
|
|
221
|
-
class_name, _ =
|
|
220
|
+
class_name, _ = @constant_name_stack.last #: as !nil
|
|
222
221
|
route = @client.route(controller: class_name, action: node.name.to_s)
|
|
223
222
|
return unless route
|
|
224
223
|
|
|
@@ -233,22 +232,24 @@ module RubyLsp
|
|
|
233
232
|
)
|
|
234
233
|
end
|
|
235
234
|
|
|
236
|
-
|
|
235
|
+
#: -> String
|
|
237
236
|
def test_command
|
|
238
237
|
"#{RbConfig.ruby} bin/rails test"
|
|
239
238
|
end
|
|
240
239
|
|
|
241
|
-
|
|
240
|
+
#: -> String
|
|
242
241
|
def migrate_command
|
|
243
242
|
"#{RbConfig.ruby} bin/rails db:migrate"
|
|
244
243
|
end
|
|
245
244
|
|
|
246
|
-
|
|
245
|
+
#: -> String?
|
|
247
246
|
def migration_version
|
|
248
|
-
File.basename(
|
|
247
|
+
File.basename(
|
|
248
|
+
@path, #: as !nil
|
|
249
|
+
).split("_").first
|
|
249
250
|
end
|
|
250
251
|
|
|
251
|
-
|
|
252
|
+
#: (Prism::Node node, name: String, command: String) -> void
|
|
252
253
|
def add_migrate_code_lens(node, name:, command:)
|
|
253
254
|
return unless @path
|
|
254
255
|
|
|
@@ -261,7 +262,7 @@ module RubyLsp
|
|
|
261
262
|
)
|
|
262
263
|
end
|
|
263
264
|
|
|
264
|
-
|
|
265
|
+
#: (Prism::Node node, name: String, command: String, kind: Symbol) -> void
|
|
265
266
|
def add_test_code_lens(node, name:, command:, kind:)
|
|
266
267
|
return unless @path
|
|
267
268
|
return unless @global_state.test_library == "rails"
|
|
@@ -4,18 +4,10 @@
|
|
|
4
4
|
module RubyLsp
|
|
5
5
|
module Rails
|
|
6
6
|
class Completion
|
|
7
|
-
extend T::Sig
|
|
8
7
|
include Requests::Support::Common
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
client: RunnerClient,
|
|
13
|
-
response_builder: ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem],
|
|
14
|
-
node_context: NodeContext,
|
|
15
|
-
dispatcher: Prism::Dispatcher,
|
|
16
|
-
uri: URI::Generic,
|
|
17
|
-
).void
|
|
18
|
-
end
|
|
9
|
+
# @override
|
|
10
|
+
#: (RunnerClient client, ResponseBuilders::CollectionResponseBuilder[Interface::CompletionItem] response_builder, NodeContext node_context, Prism::Dispatcher dispatcher, URI::Generic uri) -> void
|
|
19
11
|
def initialize(client, response_builder, node_context, dispatcher, uri)
|
|
20
12
|
@response_builder = response_builder
|
|
21
13
|
@client = client
|
|
@@ -26,7 +18,7 @@ module RubyLsp
|
|
|
26
18
|
)
|
|
27
19
|
end
|
|
28
20
|
|
|
29
|
-
|
|
21
|
+
#: (Prism::CallNode node) -> void
|
|
30
22
|
def on_call_node_enter(node)
|
|
31
23
|
call_node = @node_context.call_node
|
|
32
24
|
return unless call_node
|
|
@@ -39,13 +31,13 @@ module RubyLsp
|
|
|
39
31
|
|
|
40
32
|
private
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
#: (node: Prism::CallNode, receiver: Prism::ConstantReadNode) -> void
|
|
43
35
|
def handle_active_record_where_completions(node:, receiver:)
|
|
44
36
|
resolved_class = @client.model(receiver.name.to_s)
|
|
45
37
|
return if resolved_class.nil?
|
|
46
38
|
|
|
47
|
-
arguments =
|
|
48
|
-
indexed_call_node_args =
|
|
39
|
+
arguments = @node_context.call_node&.arguments&.arguments
|
|
40
|
+
indexed_call_node_args = {} #: Hash[String, Prism::Node]
|
|
49
41
|
|
|
50
42
|
if arguments
|
|
51
43
|
indexed_call_node_args = index_call_node_args(arguments: arguments)
|
|
@@ -70,7 +62,7 @@ module RubyLsp
|
|
|
70
62
|
end
|
|
71
63
|
end
|
|
72
64
|
|
|
73
|
-
|
|
65
|
+
#: (arguments: Array[Prism::Node]) -> Hash[String, Prism::Node]
|
|
74
66
|
def index_call_node_args(arguments:)
|
|
75
67
|
indexed_call_node_args = {}
|
|
76
68
|
arguments.each do |argument|
|
|
@@ -28,41 +28,30 @@ module RubyLsp
|
|
|
28
28
|
# - If using `constraints`, the route can only be found if the constraints are met.
|
|
29
29
|
# - Changes to routes won't be picked up until the server is restarted.
|
|
30
30
|
class Definition
|
|
31
|
-
extend T::Sig
|
|
32
31
|
include Requests::Support::Common
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
params(
|
|
36
|
-
client: RunnerClient,
|
|
37
|
-
response_builder: RubyLsp::ResponseBuilders::CollectionResponseBuilder[T.any(
|
|
38
|
-
Interface::Location, Interface::LocationLink
|
|
39
|
-
)],
|
|
40
|
-
node_context: NodeContext,
|
|
41
|
-
index: RubyIndexer::Index,
|
|
42
|
-
dispatcher: Prism::Dispatcher,
|
|
43
|
-
).void
|
|
44
|
-
end
|
|
33
|
+
#: (RunnerClient client, RubyLsp::ResponseBuilders::CollectionResponseBuilder[(Interface::Location | Interface::LocationLink)] response_builder, NodeContext node_context, RubyIndexer::Index index, Prism::Dispatcher dispatcher) -> void
|
|
45
34
|
def initialize(client, response_builder, node_context, index, dispatcher)
|
|
46
35
|
@client = client
|
|
47
36
|
@response_builder = response_builder
|
|
48
37
|
@node_context = node_context
|
|
49
|
-
@nesting =
|
|
38
|
+
@nesting = node_context.nesting #: Array[String]
|
|
50
39
|
@index = index
|
|
51
40
|
|
|
52
41
|
dispatcher.register(self, :on_call_node_enter, :on_symbol_node_enter, :on_string_node_enter)
|
|
53
42
|
end
|
|
54
43
|
|
|
55
|
-
|
|
44
|
+
#: (Prism::SymbolNode node) -> void
|
|
56
45
|
def on_symbol_node_enter(node)
|
|
57
46
|
handle_possible_dsl(node)
|
|
58
47
|
end
|
|
59
48
|
|
|
60
|
-
|
|
49
|
+
#: (Prism::StringNode node) -> void
|
|
61
50
|
def on_string_node_enter(node)
|
|
62
51
|
handle_possible_dsl(node)
|
|
63
52
|
end
|
|
64
53
|
|
|
65
|
-
|
|
54
|
+
#: ((Prism::SymbolNode | Prism::StringNode) node) -> void
|
|
66
55
|
def handle_possible_dsl(node)
|
|
67
56
|
node = @node_context.call_node
|
|
68
57
|
return unless node
|
|
@@ -79,7 +68,7 @@ module RubyLsp
|
|
|
79
68
|
end
|
|
80
69
|
end
|
|
81
70
|
|
|
82
|
-
|
|
71
|
+
#: (Prism::CallNode node) -> void
|
|
83
72
|
def on_call_node_enter(node)
|
|
84
73
|
return unless self_receiver?(node)
|
|
85
74
|
|
|
@@ -94,7 +83,7 @@ module RubyLsp
|
|
|
94
83
|
|
|
95
84
|
private
|
|
96
85
|
|
|
97
|
-
|
|
86
|
+
#: (Prism::CallNode node) -> void
|
|
98
87
|
def handle_callback(node)
|
|
99
88
|
arguments = node.arguments&.arguments
|
|
100
89
|
return unless arguments&.any?
|
|
@@ -113,14 +102,14 @@ module RubyLsp
|
|
|
113
102
|
end
|
|
114
103
|
end
|
|
115
104
|
|
|
116
|
-
|
|
105
|
+
#: (Prism::CallNode node) -> void
|
|
117
106
|
def handle_association(node)
|
|
118
107
|
first_argument = node.arguments&.arguments&.first
|
|
119
108
|
return unless first_argument.is_a?(Prism::SymbolNode)
|
|
120
109
|
|
|
121
110
|
association_name = first_argument.unescaped
|
|
122
111
|
|
|
123
|
-
result = @client.
|
|
112
|
+
result = @client.association_target(
|
|
124
113
|
model_name: @nesting.join("::"),
|
|
125
114
|
association_name: association_name,
|
|
126
115
|
)
|
|
@@ -130,15 +119,17 @@ module RubyLsp
|
|
|
130
119
|
@response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location))
|
|
131
120
|
end
|
|
132
121
|
|
|
133
|
-
|
|
122
|
+
#: (Prism::CallNode node) -> void
|
|
134
123
|
def handle_route(node)
|
|
135
|
-
result = @client.route_location(
|
|
124
|
+
result = @client.route_location(
|
|
125
|
+
node.message, #: as !nil
|
|
126
|
+
)
|
|
136
127
|
return unless result
|
|
137
128
|
|
|
138
129
|
@response_builder << Support::LocationBuilder.line_location_from_s(result.fetch(:location))
|
|
139
130
|
end
|
|
140
131
|
|
|
141
|
-
|
|
132
|
+
#: (String name) -> void
|
|
142
133
|
def collect_definitions(name)
|
|
143
134
|
methods = @index.resolve_method(name, @nesting.join("::"))
|
|
144
135
|
return unless methods
|