class YARP::RipperCompat
This class is meant to provide a compatibility layer between YARP
and Ripper. It functions by parsing the entire tree first and then walking it and executing each of the Ripper callbacks as it goes.
This class is going to necessarily be slower than the native Ripper API. It is meant as a stopgap until developers migrate to using YARP
. It is also meant as a test harness for the YARP
parser.
Attributes
Public Class Methods
# File yarp/ripper_compat.rb, line 59 def initialize(source) @source = source @result = nil @lineno = nil @column = nil end
This is a convenience method that runs the SexpBuilderPP
subclass parser.
# File yarp/ripper_compat.rb, line 140 def self.sexp(source) SexpBuilderPP.new(source).parse end
This is a convenience method that runs the SexpBuilder
subclass parser.
# File yarp/ripper_compat.rb, line 135 def self.sexp_raw(source) SexpBuilder.new(source).parse end
Public Instance Methods
Public interface
# File yarp/ripper_compat.rb, line 70 def error? result.errors.any? end
# File yarp/ripper_compat.rb, line 74 def parse result.value.accept(self) unless error? end
Visitor
methods
# File yarp/ripper_compat.rb, line 82 def visit(node) node&.accept(self) end
# File yarp/ripper_compat.rb, line 86 def visit_call_node(node) if !node.opening_loc && node.arguments.arguments.length == 1 bounds(node.receiver.location) left = visit(node.receiver) bounds(node.arguments.arguments.first.location) right = visit(node.arguments.arguments.first) on_binary(left, source[node.message_loc.start_offset...node.message_loc.end_offset].to_sym, right) else raise NotImplementedError end end
# File yarp/ripper_compat.rb, line 100 def visit_integer_node(node) bounds(node.location) on_int(source[node.location.start_offset...node.location.end_offset]) end
# File yarp/ripper_compat.rb, line 125 def visit_program_node(node) bounds(node.location) on_program(visit(node.statements)) end
# File yarp/ripper_compat.rb, line 105 def visit_statements_node(node) bounds(node.location) node.body.inject(on_stmts_new) do |stmts, stmt| on_stmts_add(stmts, visit(stmt)) end end
# File yarp/ripper_compat.rb, line 112 def visit_token(node) bounds(node.location) case node.type when :MINUS on_op(node.value) when :PLUS on_op(node.value) else raise NotImplementedError, "Unknown token: #{node.type}" end end
Private Instance Methods
# File yarp/ripper_compat.rb, line 162 def _dispatch0; end
# File yarp/ripper_compat.rb, line 163 def _dispatch1(_); end
# File yarp/ripper_compat.rb, line 164 def _dispatch2(_, _); end
# File yarp/ripper_compat.rb, line 165 def _dispatch3(_, _, _); end
# File yarp/ripper_compat.rb, line 166 def _dispatch4(_, _, _, _); end
# File yarp/ripper_compat.rb, line 167 def _dispatch5(_, _, _, _, _); end
# File yarp/ripper_compat.rb, line 168 def _dispatch7(_, _, _, _, _, _, _); end
This method is responsible for updating lineno and column information to reflect the current node.
This method could be drastically improved with some caching on the start of every line, but for now it’s good enough.
# File yarp/ripper_compat.rb, line 151 def bounds(location) start_offset = location.start_offset @lineno = source[0..start_offset].count("\n") + 1 @column = start_offset - (source.rindex("\n", start_offset) || 0) end
# File yarp/ripper_compat.rb, line 158 def result @result ||= YARP.parse(source) end