Module: RubyLLM::Toolbox::RubyOutline::PrismBackend

Defined in:
lib/ruby_llm/toolbox/ruby_outline.rb

Overview

— Prism backend —————————————————-

Class Method Summary collapse

Class Method Details

.extract(source) ⇒ Object

Raises:



56
57
58
59
60
61
62
63
64
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 56

def extract(source)
  require "prism"
  result = Prism.parse(source)
  raise ParseError, "source is not valid Ruby (syntax error)" unless result.success?

  acc = []
  visit(result.value, 0, acc)
  acc
end

.visit(node, depth, acc) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 66

def visit(node, depth, acc)
  return if node.nil?

  case node
  when Prism::ClassNode
    acc << Entry.new(kind: :class, name: node.constant_path.slice,
                     line: node.constant_path.location.start_line, depth: depth)
    visit(node.body, depth + 1, acc)
  when Prism::ModuleNode
    acc << Entry.new(kind: :module, name: node.constant_path.slice,
                     line: node.constant_path.location.start_line, depth: depth)
    visit(node.body, depth + 1, acc)
  when Prism::SingletonClassNode
    acc << Entry.new(kind: :singleton_class, name: "<< #{node.expression.slice}",
                     line: node.location.start_line, depth: depth)
    visit(node.body, depth + 1, acc)
  when Prism::DefNode
    name = node.receiver ? "#{node.receiver.slice}.#{node.name}" : node.name.to_s
    acc << Entry.new(kind: :method, name: name, line: node.name_loc.start_line, depth: depth)
    # method bodies are not descended into
  when Prism::ConstantWriteNode
    acc << Entry.new(kind: :constant, name: node.name.to_s,
                     line: node.name_loc.start_line, depth: depth)
  else
    node.compact_child_nodes.each { |child| visit(child, depth, acc) }
  end
end