Module: RubyLLM::Toolbox::RubyOutline::RipperBackend
- Defined in:
- lib/ruby_llm/toolbox/ruby_outline.rb
Overview
— Ripper backend (stdlib) ——————————————
Class Method Summary collapse
- .const_name(node) ⇒ Object
- .dispatch(node, depth, acc) ⇒ Object
- .extract(source) ⇒ Object
- .find_name_leaf(node) ⇒ Object
- .handle_assign(node, depth, acc) ⇒ Object
- .ident_name(node) ⇒ Object
- .line_of(node) ⇒ Object
- .simple_name(node) ⇒ Object
- .walk(node, depth, acc) ⇒ Object
Class Method Details
.const_name(node) ⇒ Object
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 155 def const_name(node) case node && node[0] when :const_ref, :top_const_ref, :var_ref simple_name(node[1]) when :const_path_ref # Foo::Bar "#{const_name(node[1])}::#{simple_name(node[2])}" else simple_name(node) end end |
.dispatch(node, depth, acc) ⇒ Object
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 118 def dispatch(node, depth, acc) case node[0] when :program walk(node[1], depth, acc) when :class acc << Entry.new(kind: :class, name: const_name(node[1]), line: line_of(node[1]), depth: depth) walk(node[3], depth + 1, acc) # bodystmt when :module acc << Entry.new(kind: :module, name: const_name(node[1]), line: line_of(node[1]), depth: depth) walk(node[2], depth + 1, acc) when :sclass # class << self acc << Entry.new(kind: :singleton_class, name: "<< #{simple_name(node[1])}", line: line_of(node), depth: depth) walk(node[2], depth + 1, acc) when :def acc << Entry.new(kind: :method, name: ident_name(node[1]), line: line_of(node[1]), depth: depth) when :defs # def self.x / def Recv.x name = "#{simple_name(node[1])}.#{ident_name(node[3])}" acc << Entry.new(kind: :method, name: name, line: line_of(node[3]), depth: depth) when :bodystmt walk(node[1], depth, acc) when :assign handle_assign(node, depth, acc) else node[1..].each { |child| walk(child, depth, acc) } end end |
.extract(source) ⇒ Object
99 100 101 102 103 104 105 106 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 99 def extract(source) sexp = Ripper.sexp(source.to_s) raise ParseError, "source is not valid Ruby (syntax error)" if sexp.nil? acc = [] walk(sexp, 0, acc) acc end |
.find_name_leaf(node) ⇒ Object
200 201 202 203 204 205 206 207 208 209 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 200 def find_name_leaf(node) return nil unless node.is_a?(Array) return node if %i[@const @ident @kw].include?(node[0]) node.each do |child| found = find_name_leaf(child) return found if found end nil end |
.handle_assign(node, depth, acc) ⇒ Object
145 146 147 148 149 150 151 152 153 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 145 def handle_assign(node, depth, acc) target = node[1] return unless target.is_a?(Array) && target[0] == :var_field field = target[1] return unless field.is_a?(Array) && field[0] == :@const acc << Entry.new(kind: :constant, name: field[1], line: field[2]&.first, depth: depth) end |
.ident_name(node) ⇒ Object
179 180 181 182 183 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 179 def ident_name(node) return node.to_s unless node.is_a?(Array) node[0] == :@ident || node[0] == :@const || node[0] == :@kw ? node[1].to_s : simple_name(node) end |
.line_of(node) ⇒ Object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 185 def line_of(node) return nil unless node.is_a?(Array) if node.size == 3 && node[2].is_a?(Array) && node[2].size == 2 && node[2][0].is_a?(Integer) && node[0].is_a?(Symbol) return node[2][0] end node.each do |child| line = line_of(child) return line if line end nil end |
.simple_name(node) ⇒ Object
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 166 def simple_name(node) return node.to_s unless node.is_a?(Array) case node[0] when :@const, :@ident, :@ivar, :@gvar, :@kw then node[1].to_s when :const_ref, :var_ref, :var_field then simple_name(node[1]) when :const_path_ref then "#{simple_name(node[1])}::#{simple_name(node[2])}" else leaf = find_name_leaf(node) leaf ? leaf[1].to_s : "?" end end |
.walk(node, depth, acc) ⇒ Object
108 109 110 111 112 113 114 115 116 |
# File 'lib/ruby_llm/toolbox/ruby_outline.rb', line 108 def walk(node, depth, acc) return unless node.is_a?(Array) if node[0].is_a?(Symbol) dispatch(node, depth, acc) else node.each { |child| walk(child, depth, acc) } end end |