Skip to content

Commit fcc6515

Browse files
committed
Add support for class_methods do blocks in concerns
1 parent ba74746 commit fcc6515

File tree

3 files changed

+73
-6
lines changed

3 files changed

+73
-6
lines changed

lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,20 @@ def on_call_node_enter(call_node)
2727
handle_concern_extend(owner, call_node)
2828
when :has_one, :has_many, :belongs_to, :has_and_belongs_to_many
2929
handle_association(owner, call_node)
30+
# for `class_methods do` blocks within concerns
31+
when :class_methods
32+
handle_class_methods(owner, call_node)
33+
end
34+
end
35+
36+
sig do
37+
override.params(
38+
call_node: Prism::CallNode,
39+
).void
40+
end
41+
def on_call_node_leave(call_node)
42+
if call_node.name == :class_methods && call_node.block
43+
@listener.pop_namespace_stack
3044
end
3145
end
3246

@@ -90,6 +104,13 @@ def handle_concern_extend(owner, call_node)
90104
# Do nothing
91105
end
92106
end
107+
108+
sig { params(owner: RubyIndexer::Entry::Namespace, call_node: Prism::CallNode).void }
109+
def handle_class_methods(owner, call_node)
110+
return unless call_node.block
111+
112+
@listener.add_module("ClassMethods", call_node.location, call_node.location)
113+
end
93114
end
94115
end
95116
end

test/dummy/app/models/concerns/verifiable.rb

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,3 @@ def all_unverified
2020
end
2121
end
2222
end
23-
24-
user = User.new

test/ruby_lsp_rails/indexing_enhancement_test.rb

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,62 @@ def setup
2424

2525
test "ClassMethods module inside concerns are automatically extended" do
2626
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
27-
class Post < ActiveRecord::Base
27+
module Verifiable
28+
extend ActiveSupport::Concern
29+
30+
module ClassMethods
31+
def all_verified; end
32+
end
33+
end
34+
35+
class Post
36+
include Verifiable
2837
end
2938
RUBY
3039

3140
ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
32-
assert_includes(ancestors, "ActiveRecord::Associations::ClassMethods")
33-
assert_includes(ancestors, "ActiveRecord::Store::ClassMethods")
34-
assert_includes(ancestors, "ActiveRecord::AttributeMethods::ClassMethods")
41+
42+
assert_includes(ancestors, "Verifiable::ClassMethods")
43+
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
44+
end
45+
46+
test "class_methods blocks inside concerns are automatically extended via a ClassMethods module" do
47+
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
48+
module Verifiable
49+
extend ActiveSupport::Concern
50+
51+
class_methods do
52+
def all_verified; end
53+
end
54+
end
55+
56+
class Post
57+
include Verifiable
58+
end
59+
RUBY
60+
61+
ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
62+
63+
assert_includes(ancestors, "Verifiable::ClassMethods")
64+
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
65+
end
66+
67+
test "ignores `class_methods` calls without a block" do
68+
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
69+
module Verifiable
70+
extend ActiveSupport::Concern
71+
72+
class_methods
73+
end
74+
75+
class Post
76+
include Verifiable
77+
end
78+
RUBY
79+
80+
ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
81+
82+
refute_includes(ancestors, "Verifiable::ClassMethods")
3583
end
3684

3785
test "associations" do

0 commit comments

Comments
 (0)