Skip to content

Commit

Permalink
Add support for class_methods do blocks in concerns
Browse files Browse the repository at this point in the history
  • Loading branch information
andyw8 committed Nov 19, 2024
1 parent ba74746 commit fcc6515
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
21 changes: 21 additions & 0 deletions lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ def on_call_node_enter(call_node)
handle_concern_extend(owner, call_node)
when :has_one, :has_many, :belongs_to, :has_and_belongs_to_many
handle_association(owner, call_node)
# for `class_methods do` blocks within concerns
when :class_methods
handle_class_methods(owner, call_node)
end
end

sig do
override.params(
call_node: Prism::CallNode,
).void
end
def on_call_node_leave(call_node)
if call_node.name == :class_methods && call_node.block
@listener.pop_namespace_stack
end
end

Expand Down Expand Up @@ -90,6 +104,13 @@ def handle_concern_extend(owner, call_node)
# Do nothing
end
end

sig { params(owner: RubyIndexer::Entry::Namespace, call_node: Prism::CallNode).void }
def handle_class_methods(owner, call_node)
return unless call_node.block

@listener.add_module("ClassMethods", call_node.location, call_node.location)
end
end
end
end
2 changes: 0 additions & 2 deletions test/dummy/app/models/concerns/verifiable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,3 @@ def all_unverified
end
end
end

user = User.new
56 changes: 52 additions & 4 deletions test/ruby_lsp_rails/indexing_enhancement_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,62 @@ def setup

test "ClassMethods module inside concerns are automatically extended" do
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
class Post < ActiveRecord::Base
module Verifiable
extend ActiveSupport::Concern
module ClassMethods
def all_verified; end
end
end
class Post
include Verifiable
end
RUBY

ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")
assert_includes(ancestors, "ActiveRecord::Associations::ClassMethods")
assert_includes(ancestors, "ActiveRecord::Store::ClassMethods")
assert_includes(ancestors, "ActiveRecord::AttributeMethods::ClassMethods")

assert_includes(ancestors, "Verifiable::ClassMethods")
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
end

test "class_methods blocks inside concerns are automatically extended via a ClassMethods module" do
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
module Verifiable
extend ActiveSupport::Concern
class_methods do
def all_verified; end
end
end
class Post
include Verifiable
end
RUBY

ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")

assert_includes(ancestors, "Verifiable::ClassMethods")
refute_nil(@index.resolve_method("all_verified", "Post::<Class:Post>"))
end

test "ignores `class_methods` calls without a block" do
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
module Verifiable
extend ActiveSupport::Concern
class_methods
end
class Post
include Verifiable
end
RUBY

ancestors = @index.linearized_ancestors_of("Post::<Class:Post>")

refute_includes(ancestors, "Verifiable::ClassMethods")
end

test "associations" do
Expand Down

0 comments on commit fcc6515

Please sign in to comment.