ruby-lsp-mongoid 0.1.1 → 0.1.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/CHANGELOG.md +24 -0
- data/lib/ruby_lsp/ruby_lsp_mongoid/addon.rb +94 -1
- data/lib/ruby_lsp/ruby_lsp_mongoid/hover.rb +44 -2
- data/lib/ruby_lsp/ruby_lsp_mongoid/indexing_enhancement.rb +142 -22
- data/lib/ruby_lsp/ruby_lsp_mongoid/signature_resolver.rb +78 -0
- data/lib/ruby_lsp/ruby_lsp_mongoid.rb +1 -0
- data/lib/ruby_lsp_mongoid/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 459274f7c2be280ff2e284869fcd8dc7e424dcce61799d881a27f7bc250edf75
|
|
4
|
+
data.tar.gz: 07ee1f8583968c5b01bc395df23e3b598967e9ae389b10100d4681eb5c592f9d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c946f9ee440c08d5620f074272c1f34376624b4cfb7251bf26d4e7342a76792bd625d86b78eda2015da57eccdaf4b38be838e97e82a39ead6e8d73c8fe890750
|
|
7
|
+
data.tar.gz: 2343c3b4a06ecd64abf51015cac50ce6f45380148a796777860474e025e446526892a2f2a486235a0f5e38906258b9c2b6b07044d12500b38468ad2cfc8adcde
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.1.2] - 2025-12-15
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Auto-index core instance methods when including `Mongoid::Document` or `ApplicationDocument`:
|
|
8
|
+
- ID accessors: `_id`, `_id=`, `id`, `id=` (always present in Mongoid documents)
|
|
9
|
+
- Persistence methods: `save`, `save!`, `update`, `update!`, `destroy`, `delete`, `upsert`, `reload`
|
|
10
|
+
- State methods: `new_record?`, `persisted?`, `valid?`, `changed?`
|
|
11
|
+
- Attribute methods: `attributes`, `attributes=`, `assign_attributes`, `read_attribute`, `write_attribute`, `changes`, `errors`
|
|
12
|
+
- Identity methods: `to_key`, `to_param`, `model_name`, `inspect`
|
|
13
|
+
- Auto-index core class methods when including `Mongoid::Document` or `ApplicationDocument`:
|
|
14
|
+
- Query methods: `all`, `where`, `find`, `find_by`, `find_by!`, `first`, `last`, `count`, `exists?`, `distinct`
|
|
15
|
+
- Creation methods: `create`, `create!`, `new`, `build`
|
|
16
|
+
- Modification methods: `update_all`, `delete_all`, `destroy_all`
|
|
17
|
+
- Database methods: `collection`, `database`
|
|
18
|
+
- Support for `ApplicationDocument` pattern (common Rails pattern where `ApplicationDocument` includes `Mongoid::Document`)
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- ID accessors (`_id`, `id`) are now indexed when including `Mongoid::Document`/`ApplicationDocument` instead of at the first DSL call
|
|
23
|
+
- Simplified internal implementation by removing `ensure_id_field_indexed` mechanism
|
|
24
|
+
|
|
25
|
+
## [0.1.1] - 2025-12-08
|
|
26
|
+
|
|
3
27
|
### Added
|
|
4
28
|
|
|
5
29
|
- Auto-index `_id` and `id` accessor methods for all Mongoid models that use any DSL (field, associations, scope)
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "../../ruby_lsp_mongoid/version"
|
|
4
|
+
require_relative "signature_resolver"
|
|
4
5
|
require_relative "indexing_enhancement"
|
|
5
6
|
require_relative "hover"
|
|
6
7
|
|
|
7
8
|
module RubyLsp
|
|
8
9
|
module Mongoid
|
|
9
10
|
class Addon < ::RubyLsp::Addon
|
|
11
|
+
include SignatureResolver
|
|
12
|
+
|
|
10
13
|
def activate(global_state, outgoing_queue)
|
|
11
14
|
@global_state = global_state
|
|
12
15
|
@outgoing_queue = outgoing_queue
|
|
13
16
|
@outgoing_queue << Notification.window_log_message("Activating Ruby LSP Mongoid add-on v#{VERSION}")
|
|
17
|
+
|
|
18
|
+
# Start background thread to update signatures after indexing completes
|
|
19
|
+
@signature_update_thread = Thread.new { wait_for_indexing_and_update_signatures }
|
|
14
20
|
end
|
|
15
21
|
|
|
16
|
-
def deactivate
|
|
22
|
+
def deactivate
|
|
23
|
+
@signature_update_thread&.kill
|
|
24
|
+
end
|
|
17
25
|
|
|
18
26
|
def name
|
|
19
27
|
"Ruby LSP Mongoid"
|
|
@@ -28,6 +36,91 @@ module RubyLsp
|
|
|
28
36
|
|
|
29
37
|
Hover.new(response_builder, node_context, @global_state.index, dispatcher)
|
|
30
38
|
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def wait_for_indexing_and_update_signatures
|
|
43
|
+
return unless @global_state
|
|
44
|
+
|
|
45
|
+
index = @global_state.index
|
|
46
|
+
|
|
47
|
+
# Wait for initial indexing to complete
|
|
48
|
+
sleep(0.1) until index.instance_variable_get(:@initial_indexing_completed)
|
|
49
|
+
|
|
50
|
+
update_mongoid_signatures(index)
|
|
51
|
+
rescue StandardError => e
|
|
52
|
+
@outgoing_queue << Notification.window_log_message(
|
|
53
|
+
"Ruby LSP Mongoid: Error updating signatures: #{e.message}",
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def update_mongoid_signatures(index)
|
|
58
|
+
updated_count = 0
|
|
59
|
+
|
|
60
|
+
# Update instance method signatures
|
|
61
|
+
CORE_INSTANCE_METHODS.each do |method_name|
|
|
62
|
+
mongoid_signatures = resolve_instance_method_signature(index, method_name)
|
|
63
|
+
next unless mongoid_signatures
|
|
64
|
+
|
|
65
|
+
updated_count += update_method_signatures_for_mongoid_models(index, method_name, mongoid_signatures)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Update class method signatures
|
|
69
|
+
CORE_CLASS_METHODS.each do |method_name|
|
|
70
|
+
mongoid_signatures = resolve_class_method_signature(index, method_name)
|
|
71
|
+
next unless mongoid_signatures
|
|
72
|
+
|
|
73
|
+
updated_count += update_singleton_method_signatures_for_mongoid_models(
|
|
74
|
+
index,
|
|
75
|
+
method_name,
|
|
76
|
+
mongoid_signatures,
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
if updated_count > 0
|
|
81
|
+
@outgoing_queue << Notification.window_log_message(
|
|
82
|
+
"Ruby LSP Mongoid: Updated #{updated_count} method signatures from Mongoid modules",
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def update_method_signatures_for_mongoid_models(index, method_name, new_signatures)
|
|
88
|
+
updated = 0
|
|
89
|
+
|
|
90
|
+
# Find all classes that have this method registered by our addon
|
|
91
|
+
# We look for methods that were registered with empty signatures
|
|
92
|
+
index.instance_variable_get(:@entries).each do |_name, entries|
|
|
93
|
+
entries.each do |entry|
|
|
94
|
+
next unless entry.is_a?(RubyIndexer::Entry::Method)
|
|
95
|
+
next unless entry.name == method_name
|
|
96
|
+
next unless entry.signatures.empty? || entry.signatures.first.parameters.empty?
|
|
97
|
+
|
|
98
|
+
# Update the signatures
|
|
99
|
+
entry.instance_variable_set(:@signatures, new_signatures)
|
|
100
|
+
updated += 1
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
updated
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def update_singleton_method_signatures_for_mongoid_models(index, method_name, new_signatures)
|
|
108
|
+
updated = 0
|
|
109
|
+
|
|
110
|
+
index.instance_variable_get(:@entries).each do |_name, entries|
|
|
111
|
+
entries.each do |entry|
|
|
112
|
+
next unless entry.is_a?(RubyIndexer::Entry::Method)
|
|
113
|
+
next unless entry.name == method_name
|
|
114
|
+
next unless entry.owner.is_a?(RubyIndexer::Entry::SingletonClass)
|
|
115
|
+
next unless entry.signatures.empty? || entry.signatures.first.parameters.empty?
|
|
116
|
+
|
|
117
|
+
entry.instance_variable_set(:@signatures, new_signatures)
|
|
118
|
+
updated += 1
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
updated
|
|
123
|
+
end
|
|
31
124
|
end
|
|
32
125
|
end
|
|
33
126
|
end
|
|
@@ -43,10 +43,21 @@ module RubyLsp
|
|
|
43
43
|
return unless entries&.any?
|
|
44
44
|
|
|
45
45
|
entry = entries.first
|
|
46
|
+
|
|
47
|
+
# Build hover content with signature and options
|
|
48
|
+
content_parts = []
|
|
49
|
+
|
|
50
|
+
# Add method signature
|
|
51
|
+
signature = format_signature(name.to_s, entry)
|
|
52
|
+
content_parts << signature if signature
|
|
53
|
+
|
|
54
|
+
# Add field options from comments
|
|
46
55
|
comments = entry.comments
|
|
47
|
-
|
|
56
|
+
content_parts << comments if comments && !comments.empty?
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
return if content_parts.empty?
|
|
59
|
+
|
|
60
|
+
@response_builder.push(content_parts.join("\n\n"), category: :documentation)
|
|
50
61
|
end
|
|
51
62
|
|
|
52
63
|
def handle_association(node)
|
|
@@ -128,6 +139,37 @@ module RubyLsp
|
|
|
128
139
|
|
|
129
140
|
@response_builder.push(content, category: :documentation)
|
|
130
141
|
end
|
|
142
|
+
|
|
143
|
+
def format_signature(method_name, entry)
|
|
144
|
+
return nil unless entry.respond_to?(:signatures) && entry.signatures.any?
|
|
145
|
+
|
|
146
|
+
sig = entry.signatures.first
|
|
147
|
+
return nil if sig.parameters.empty?
|
|
148
|
+
|
|
149
|
+
params = sig.parameters.map { |param| format_parameter(param) }.join(", ")
|
|
150
|
+
"```ruby\ndef #{method_name}(#{params})\n```"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def format_parameter(param)
|
|
154
|
+
case param
|
|
155
|
+
when RubyIndexer::Entry::RequiredParameter
|
|
156
|
+
param.name.to_s
|
|
157
|
+
when RubyIndexer::Entry::OptionalParameter
|
|
158
|
+
"#{param.name} = nil"
|
|
159
|
+
when RubyIndexer::Entry::KeywordParameter
|
|
160
|
+
"#{param.name}:"
|
|
161
|
+
when RubyIndexer::Entry::OptionalKeywordParameter
|
|
162
|
+
"#{param.name}: nil"
|
|
163
|
+
when RubyIndexer::Entry::RestParameter
|
|
164
|
+
"*#{param.name}"
|
|
165
|
+
when RubyIndexer::Entry::KeywordRestParameter
|
|
166
|
+
"**#{param.name}"
|
|
167
|
+
when RubyIndexer::Entry::BlockParameter
|
|
168
|
+
"&#{param.name}"
|
|
169
|
+
else
|
|
170
|
+
param.name.to_s
|
|
171
|
+
end
|
|
172
|
+
end
|
|
131
173
|
end
|
|
132
174
|
end
|
|
133
175
|
end
|
|
@@ -5,7 +5,6 @@ module RubyLsp
|
|
|
5
5
|
class IndexingEnhancement < RubyIndexer::Enhancement
|
|
6
6
|
def initialize(listener)
|
|
7
7
|
super
|
|
8
|
-
@id_indexed_owners = Set.new
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
def on_call_node_enter(call_node)
|
|
@@ -13,6 +12,8 @@ module RubyLsp
|
|
|
13
12
|
return unless owner
|
|
14
13
|
|
|
15
14
|
case call_node.name
|
|
15
|
+
when :include
|
|
16
|
+
handle_include(call_node)
|
|
16
17
|
when :field
|
|
17
18
|
handle_field(call_node)
|
|
18
19
|
when :embeds_many, :embedded_in
|
|
@@ -30,6 +31,58 @@ module RubyLsp
|
|
|
30
31
|
|
|
31
32
|
private
|
|
32
33
|
|
|
34
|
+
# Core instance methods automatically added by Mongoid::Document
|
|
35
|
+
CORE_INSTANCE_METHODS = %w[
|
|
36
|
+
save save! update update! destroy delete upsert reload
|
|
37
|
+
new_record? persisted? valid? changed?
|
|
38
|
+
attributes attributes= assign_attributes read_attribute write_attribute changes errors
|
|
39
|
+
to_key to_param model_name inspect
|
|
40
|
+
].freeze
|
|
41
|
+
|
|
42
|
+
# Class methods automatically added by Mongoid::Document
|
|
43
|
+
CORE_CLASS_METHODS = %w[
|
|
44
|
+
all where find find_by find_by! first last count exists? distinct
|
|
45
|
+
create create! new build
|
|
46
|
+
update_all delete_all destroy_all
|
|
47
|
+
collection database
|
|
48
|
+
].freeze
|
|
49
|
+
|
|
50
|
+
def handle_include(call_node)
|
|
51
|
+
arguments = call_node.arguments&.arguments
|
|
52
|
+
return unless arguments
|
|
53
|
+
|
|
54
|
+
# Check if including Mongoid::Document or ApplicationDocument
|
|
55
|
+
first_arg = arguments.first
|
|
56
|
+
module_name = case first_arg
|
|
57
|
+
when Prism::ConstantReadNode
|
|
58
|
+
first_arg.name.to_s
|
|
59
|
+
when Prism::ConstantPathNode
|
|
60
|
+
first_arg.full_name
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Support both Mongoid::Document and ApplicationDocument (common Rails pattern)
|
|
64
|
+
return unless module_name == "Mongoid::Document" || module_name == "ApplicationDocument"
|
|
65
|
+
|
|
66
|
+
owner = @listener.current_owner
|
|
67
|
+
return unless owner
|
|
68
|
+
|
|
69
|
+
loc = call_node.location
|
|
70
|
+
|
|
71
|
+
# Add _id and id accessor methods (always present in Mongoid documents)
|
|
72
|
+
add_accessor_methods("_id", loc)
|
|
73
|
+
add_accessor_methods("id", loc)
|
|
74
|
+
|
|
75
|
+
# Add core instance methods
|
|
76
|
+
CORE_INSTANCE_METHODS.each do |method_name|
|
|
77
|
+
add_core_method(method_name, loc)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Add core class methods
|
|
81
|
+
CORE_CLASS_METHODS.each do |method_name|
|
|
82
|
+
add_singleton_method(method_name, loc, owner)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
33
86
|
def handle_field(call_node)
|
|
34
87
|
name = extract_name(call_node)
|
|
35
88
|
return unless name
|
|
@@ -37,8 +90,6 @@ module RubyLsp
|
|
|
37
90
|
loc = call_node.location
|
|
38
91
|
comment = build_field_options_comment(call_node)
|
|
39
92
|
|
|
40
|
-
ensure_id_field_indexed(loc)
|
|
41
|
-
|
|
42
93
|
add_accessor_methods(name, loc, comments: comment)
|
|
43
94
|
|
|
44
95
|
# Handle as: option for field alias
|
|
@@ -51,7 +102,6 @@ module RubyLsp
|
|
|
51
102
|
return unless name
|
|
52
103
|
|
|
53
104
|
loc = call_node.location
|
|
54
|
-
ensure_id_field_indexed(loc)
|
|
55
105
|
|
|
56
106
|
add_accessor_methods(name, loc)
|
|
57
107
|
end
|
|
@@ -61,7 +111,6 @@ module RubyLsp
|
|
|
61
111
|
return unless name
|
|
62
112
|
|
|
63
113
|
loc = call_node.location
|
|
64
|
-
ensure_id_field_indexed(loc)
|
|
65
114
|
|
|
66
115
|
add_accessor_methods(name, loc)
|
|
67
116
|
|
|
@@ -74,7 +123,6 @@ module RubyLsp
|
|
|
74
123
|
return unless name
|
|
75
124
|
|
|
76
125
|
loc = call_node.location
|
|
77
|
-
ensure_id_field_indexed(loc)
|
|
78
126
|
|
|
79
127
|
add_accessor_methods(name, loc)
|
|
80
128
|
add_builder_methods(name, loc)
|
|
@@ -88,9 +136,17 @@ module RubyLsp
|
|
|
88
136
|
return unless owner
|
|
89
137
|
|
|
90
138
|
loc = call_node.location
|
|
91
|
-
ensure_id_field_indexed(loc)
|
|
92
139
|
|
|
93
|
-
|
|
140
|
+
# Extract lambda parameters if present
|
|
141
|
+
lambda_node = extract_lambda_node(call_node)
|
|
142
|
+
signatures = if lambda_node
|
|
143
|
+
params = extract_lambda_parameters(lambda_node)
|
|
144
|
+
[RubyIndexer::Entry::Signature.new(params)]
|
|
145
|
+
else
|
|
146
|
+
[RubyIndexer::Entry::Signature.new([])]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
add_singleton_method_with_signatures(name.to_s, loc, owner, signatures)
|
|
94
150
|
end
|
|
95
151
|
|
|
96
152
|
def extract_name(call_node)
|
|
@@ -175,21 +231,34 @@ module RubyLsp
|
|
|
175
231
|
@listener.add_method("#{name}=", location, writer_signatures, comments: comments)
|
|
176
232
|
end
|
|
177
233
|
|
|
234
|
+
def add_core_method(name, location)
|
|
235
|
+
signatures = [RubyIndexer::Entry::Signature.new([])]
|
|
236
|
+
@listener.add_method(name.to_s, location, signatures)
|
|
237
|
+
end
|
|
238
|
+
|
|
178
239
|
def add_builder_methods(name, location)
|
|
179
|
-
builder_signatures = [
|
|
240
|
+
builder_signatures = [
|
|
241
|
+
RubyIndexer::Entry::Signature.new([
|
|
242
|
+
RubyIndexer::Entry::OptionalParameter.new(name: :attributes),
|
|
243
|
+
]),
|
|
244
|
+
]
|
|
180
245
|
@listener.add_method("build_#{name}", location, builder_signatures)
|
|
181
246
|
@listener.add_method("create_#{name}", location, builder_signatures)
|
|
182
247
|
@listener.add_method("create_#{name}!", location, builder_signatures)
|
|
183
248
|
end
|
|
184
249
|
|
|
185
250
|
def add_singleton_method(name, node_location, owner)
|
|
251
|
+
signatures = [RubyIndexer::Entry::Signature.new([])]
|
|
252
|
+
add_singleton_method_with_signatures(name, node_location, owner, signatures)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def add_singleton_method_with_signatures(name, node_location, owner, signatures)
|
|
186
256
|
index = @listener.instance_variable_get(:@index)
|
|
187
257
|
code_units_cache = @listener.instance_variable_get(:@code_units_cache)
|
|
188
258
|
uri = @listener.instance_variable_get(:@uri)
|
|
189
259
|
|
|
190
260
|
location = RubyIndexer::Location.from_prism_location(node_location, code_units_cache)
|
|
191
261
|
singleton = index.existing_or_new_singleton_class(owner.name)
|
|
192
|
-
signatures = [RubyIndexer::Entry::Signature.new([])]
|
|
193
262
|
|
|
194
263
|
index.add(RubyIndexer::Entry::Method.new(
|
|
195
264
|
name,
|
|
@@ -203,6 +272,69 @@ module RubyLsp
|
|
|
203
272
|
))
|
|
204
273
|
end
|
|
205
274
|
|
|
275
|
+
def extract_lambda_node(call_node)
|
|
276
|
+
arguments = call_node.arguments&.arguments
|
|
277
|
+
return unless arguments
|
|
278
|
+
|
|
279
|
+
arguments.find { |arg| arg.is_a?(Prism::LambdaNode) }
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def extract_lambda_parameters(lambda_node)
|
|
283
|
+
return [] unless lambda_node.is_a?(Prism::LambdaNode)
|
|
284
|
+
|
|
285
|
+
params_node = lambda_node.parameters
|
|
286
|
+
return [] unless params_node
|
|
287
|
+
|
|
288
|
+
# Lambda parameters can be either BlockParametersNode or NumberedParametersNode
|
|
289
|
+
case params_node
|
|
290
|
+
when Prism::BlockParametersNode
|
|
291
|
+
extract_parameters_from_block_params(params_node)
|
|
292
|
+
else
|
|
293
|
+
[]
|
|
294
|
+
end
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def extract_parameters_from_block_params(block_params_node)
|
|
298
|
+
params = []
|
|
299
|
+
|
|
300
|
+
# BlockParametersNode has a `parameters` method that returns ParametersNode
|
|
301
|
+
inner_params = block_params_node.parameters
|
|
302
|
+
return params unless inner_params
|
|
303
|
+
|
|
304
|
+
# Required parameters
|
|
305
|
+
inner_params.requireds&.each do |param|
|
|
306
|
+
next unless param.respond_to?(:name)
|
|
307
|
+
|
|
308
|
+
params << RubyIndexer::Entry::RequiredParameter.new(name: param.name)
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Optional parameters
|
|
312
|
+
inner_params.optionals&.each do |param|
|
|
313
|
+
next unless param.respond_to?(:name)
|
|
314
|
+
|
|
315
|
+
params << RubyIndexer::Entry::OptionalParameter.new(name: param.name)
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Rest parameter
|
|
319
|
+
if inner_params.rest && inner_params.rest.respond_to?(:name)
|
|
320
|
+
name = inner_params.rest.name || :args
|
|
321
|
+
params << RubyIndexer::Entry::RestParameter.new(name: name)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Keyword parameters
|
|
325
|
+
inner_params.keywords&.each do |param|
|
|
326
|
+
next unless param.respond_to?(:name)
|
|
327
|
+
|
|
328
|
+
if param.respond_to?(:value) && param.value
|
|
329
|
+
params << RubyIndexer::Entry::OptionalKeywordParameter.new(name: param.name)
|
|
330
|
+
else
|
|
331
|
+
params << RubyIndexer::Entry::KeywordParameter.new(name: param.name)
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
params
|
|
336
|
+
end
|
|
337
|
+
|
|
206
338
|
def singularize(name)
|
|
207
339
|
name_str = name.to_s
|
|
208
340
|
if name_str.end_with?("ies")
|
|
@@ -213,18 +345,6 @@ module RubyLsp
|
|
|
213
345
|
name_str
|
|
214
346
|
end
|
|
215
347
|
end
|
|
216
|
-
|
|
217
|
-
def ensure_id_field_indexed(location)
|
|
218
|
-
owner = @listener.current_owner
|
|
219
|
-
return unless owner
|
|
220
|
-
return if @id_indexed_owners.include?(owner.name)
|
|
221
|
-
|
|
222
|
-
@id_indexed_owners.add(owner.name)
|
|
223
|
-
|
|
224
|
-
# Add _id and id (alias) accessor methods
|
|
225
|
-
add_accessor_methods("_id", location)
|
|
226
|
-
add_accessor_methods("id", location)
|
|
227
|
-
end
|
|
228
348
|
end
|
|
229
349
|
end
|
|
230
350
|
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLsp
|
|
4
|
+
module Mongoid
|
|
5
|
+
# Resolves method signatures from Mongoid modules in the Ruby LSP index.
|
|
6
|
+
# Used to update method signatures after initial indexing is complete.
|
|
7
|
+
module SignatureResolver
|
|
8
|
+
# Mongoid modules that provide instance methods
|
|
9
|
+
INSTANCE_METHOD_SOURCES = [
|
|
10
|
+
"Mongoid::Persistable::Savable",
|
|
11
|
+
"Mongoid::Persistable::Updatable",
|
|
12
|
+
"Mongoid::Persistable::Deletable",
|
|
13
|
+
"Mongoid::Persistable::Destroyable",
|
|
14
|
+
"Mongoid::Persistable::Upsertable",
|
|
15
|
+
"Mongoid::Attributes",
|
|
16
|
+
"Mongoid::Reloadable",
|
|
17
|
+
"Mongoid::Stateful",
|
|
18
|
+
"Mongoid::Changeable",
|
|
19
|
+
"Mongoid::Inspectable",
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
22
|
+
# Mongoid modules that provide class methods
|
|
23
|
+
CLASS_METHOD_SOURCES = [
|
|
24
|
+
"Mongoid::Findable",
|
|
25
|
+
"Mongoid::Criteria",
|
|
26
|
+
"Mongoid::Persistable::Creatable::ClassMethods",
|
|
27
|
+
"Mongoid::Clients::Sessions::ClassMethods",
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
# Core instance methods to look up signatures for
|
|
31
|
+
CORE_INSTANCE_METHODS = %w[
|
|
32
|
+
save save! update update! destroy delete upsert reload
|
|
33
|
+
new_record? persisted? valid? changed?
|
|
34
|
+
attributes attributes= assign_attributes read_attribute write_attribute
|
|
35
|
+
changes errors to_key to_param model_name inspect
|
|
36
|
+
].freeze
|
|
37
|
+
|
|
38
|
+
# Core class methods to look up signatures for
|
|
39
|
+
CORE_CLASS_METHODS = %w[
|
|
40
|
+
all where find find_by find_by! first last count exists? distinct
|
|
41
|
+
create create! new build update_all delete_all destroy_all
|
|
42
|
+
collection database
|
|
43
|
+
].freeze
|
|
44
|
+
|
|
45
|
+
# Resolve instance method signature from Mongoid modules
|
|
46
|
+
# @param index [RubyIndexer::Index] Ruby LSP index
|
|
47
|
+
# @param method_name [String] Method name to look up
|
|
48
|
+
# @return [Array<RubyIndexer::Entry::Signature>, nil] Signatures or nil if not found
|
|
49
|
+
def resolve_instance_method_signature(index, method_name)
|
|
50
|
+
INSTANCE_METHOD_SOURCES.each do |module_name|
|
|
51
|
+
entries = index.resolve_method(method_name, module_name)
|
|
52
|
+
next unless entries&.any?
|
|
53
|
+
|
|
54
|
+
entry = entries.first
|
|
55
|
+
return entry.signatures if entry.respond_to?(:signatures) && entry.signatures.any?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
nil
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Resolve class method signature from Mongoid modules
|
|
62
|
+
# @param index [RubyIndexer::Index] Ruby LSP index
|
|
63
|
+
# @param method_name [String] Method name to look up
|
|
64
|
+
# @return [Array<RubyIndexer::Entry::Signature>, nil] Signatures or nil if not found
|
|
65
|
+
def resolve_class_method_signature(index, method_name)
|
|
66
|
+
CLASS_METHOD_SOURCES.each do |module_name|
|
|
67
|
+
entries = index.resolve_method(method_name, module_name)
|
|
68
|
+
next unless entries&.any?
|
|
69
|
+
|
|
70
|
+
entry = entries.first
|
|
71
|
+
return entry.signatures if entry.respond_to?(:signatures) && entry.signatures.any?
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
nil
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-lsp-mongoid
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Shia
|
|
@@ -41,6 +41,7 @@ files:
|
|
|
41
41
|
- lib/ruby_lsp/ruby_lsp_mongoid/addon.rb
|
|
42
42
|
- lib/ruby_lsp/ruby_lsp_mongoid/hover.rb
|
|
43
43
|
- lib/ruby_lsp/ruby_lsp_mongoid/indexing_enhancement.rb
|
|
44
|
+
- lib/ruby_lsp/ruby_lsp_mongoid/signature_resolver.rb
|
|
44
45
|
- lib/ruby_lsp_mongoid/version.rb
|
|
45
46
|
homepage: https://github.com/riseshia/ruby-lsp-mongoid
|
|
46
47
|
licenses:
|