Skip to content

Commit

Permalink
Add associations enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
vinistock committed Aug 8, 2024
1 parent c99069c commit 41f4227
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
50 changes: 50 additions & 0 deletions lib/ruby_lsp/ruby_lsp_rails/indexing_enhancement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,61 @@ def on_call_node(index, owner, node, file_path)
case name
when :extend
handle_concern_extend(index, owner, node)
when :has_one, :has_many, :belongs_to, :has_and_belongs_to_many
handle_association(index, owner, node, file_path)
end
end

private

sig do
params(
index: RubyIndexer::Index,
owner: RubyIndexer::Entry::Namespace,
node: Prism::CallNode,
file_path: String,
).void
end
def handle_association(index, owner, node, file_path)
arguments = node.arguments&.arguments
return unless arguments

name_arg = arguments.first

name = case name_arg
when Prism::StringNode
name_arg.content
when Prism::SymbolNode
name_arg.value
end

return unless name

# Reader
index.add(RubyIndexer::Entry::Method.new(
name,
file_path,
name_arg.location,
name_arg.location,
[],
[RubyIndexer::Entry::Signature.new([])],
RubyIndexer::Entry::Visibility::PUBLIC,
owner,
))

# Writer
index.add(RubyIndexer::Entry::Method.new(
"#{name}=",
file_path,
name_arg.location,
name_arg.location,
[],
[RubyIndexer::Entry::Signature.new([RubyIndexer::Entry::RequiredParameter.new(name: name.to_sym)])],
RubyIndexer::Entry::Visibility::PUBLIC,
owner,
))
end

sig do
params(
index: RubyIndexer::Index,
Expand Down
33 changes: 33 additions & 0 deletions test/ruby_lsp_rails/indexing_enhancement_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@ class Post < ActiveRecord::Base
assert_includes(ancestors, "ActiveRecord::Store::ClassMethods")
assert_includes(ancestors, "ActiveRecord::AttributeMethods::ClassMethods")
end

test "associations" do
@index.index_single(RubyIndexer::IndexablePath.new(nil, "/fake.rb"), <<~RUBY)
class Post < ActiveRecord::Base
has_one :content
belongs_to :author
has_many :comments
has_and_belongs_to_many :tags
end
RUBY

assert_declaration_on_line("content", "Post", 2)
assert_declaration_on_line("content=", "Post", 2)

assert_declaration_on_line("author", "Post", 3)
assert_declaration_on_line("author=", "Post", 3)

assert_declaration_on_line("comments", "Post", 4)
assert_declaration_on_line("comments=", "Post", 4)

assert_declaration_on_line("tags", "Post", 5)
assert_declaration_on_line("tags=", "Post", 5)
end

private

def assert_declaration_on_line(method_name, class_name, line)
association_entries = @index.resolve_method(method_name, class_name)
refute_nil(association_entries)

association = association_entries.first
assert_equal(line, association.location.start_line)
end
end
end
end

0 comments on commit 41f4227

Please sign in to comment.