Skip to content

Commit bae514c

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

File tree

3 files changed

+78
-6
lines changed

3 files changed

+78
-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: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,67 @@ 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
37+
end
38+
RUBY
39+
40+
ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
41+
42+
assert_includes(ancestors, "Verifiable::ClassMethods")
43+
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
44+
end
45+
46+
# TODO:
47+
#
48+
# Rails::Command::Behavior - why?
49+
# RDoc::RI::Driver ('class_methods' method)
50+
51+
test "class_methods blocks inside concerns are automatically extended via a ClassMethods module" do
52+
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
53+
module Verifiable
54+
extend ActiveSupport::Concern
55+
56+
class_methods do
57+
def all_verified; end
58+
end
59+
end
60+
61+
class Post
62+
include Verifiable
63+
end
64+
RUBY
65+
66+
ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
67+
68+
assert_includes(ancestors, "Verifiable::ClassMethods")
69+
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
70+
end
71+
72+
test "ignores `class_method` calls without a block" do
73+
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
74+
module Verifiable
75+
extend ActiveSupport::Concern
76+
77+
class_methods
78+
end
79+
80+
class Post
81+
include Verifiable
2882
end
2983
RUBY
3084

3185
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")
86+
87+
refute_includes(ancestors, "Verifiable::ClassMethods")
3588
end
3689

3790
test "associations" do

0 commit comments

Comments
 (0)