Skip to content
33 changes: 33 additions & 0 deletions lib/ruby_lsp/ruby_lsp_rails/schema_collector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# typed: strict
# frozen_string_literal: true

module RubyLsp
module Rails
class SchemaCollector < Prism::Visitor
extend T::Sig

sig { returns(T::Hash[String, Prism::Location]) }
attr_reader :tables

sig { void }
def initialize
@tables = {}

super
end

sig { params(node: Prism::CallNode).void }
def visit_call_node(node)
return if node.block.nil?

node.block.body.child_nodes.each do |child_node|
next unless child_node.is_a?(Prism::CallNode)
next unless child_node.name == :create_table

table_name = child_node.arguments.child_nodes.first.content
@tables[table_name.classify] = child_node.location
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not necessary to traverse the nodes directly within a Prism::Visitor. Per the documentation:

  def visit_call_node(node)
    if node.name == "foo"
      # Do something with the node
    end

    # Call super so that the visitor continues walking the tree
    super
  end

So this could be restructured to look like:

def visit_call_node(node)
  if node.name == 'create_table'
    # ensure the first argument is a string node and store the location
  end

  super
end

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @wbhouston! Thank you for these changes, they look great to me! Feel free to commit these changes to this PR

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@faraazahmad it won't be possible for @wbhouston to push to your branch.

end
end
end
end