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

column[R]
lineno[R]
source[R]

Public Class Methods

new(source) click to toggle source
# File yarp/ripper_compat.rb, line 59
def initialize(source)
  @source = source
  @result = nil
  @lineno = nil
  @column = nil
end
sexp(source) click to toggle source

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
sexp_raw(source) click to toggle source

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

error?() click to toggle source

Public interface

# File yarp/ripper_compat.rb, line 70
def error?
  result.errors.any?
end
parse() click to toggle source
# File yarp/ripper_compat.rb, line 74
def parse
  result.value.accept(self) unless error?
end
visit(node) click to toggle source

Visitor methods

# File yarp/ripper_compat.rb, line 82
def visit(node)
  node&.accept(self)
end
visit_call_node(node) click to toggle source
# 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
visit_integer_node(node) click to toggle source
# 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
visit_program_node(node) click to toggle source
# File yarp/ripper_compat.rb, line 125
def visit_program_node(node)
  bounds(node.location)
  on_program(visit(node.statements))
end
visit_statements_node(node) click to toggle source
# 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
visit_token(node) click to toggle source
# 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

_dispatch0() click to toggle source
# File yarp/ripper_compat.rb, line 162
def _dispatch0; end
_dispatch1(_) click to toggle source
# File yarp/ripper_compat.rb, line 163
def _dispatch1(_); end
_dispatch2(_, _) click to toggle source
# File yarp/ripper_compat.rb, line 164
def _dispatch2(_, _); end
_dispatch3(_, _, _) click to toggle source
# File yarp/ripper_compat.rb, line 165
def _dispatch3(_, _, _); end
_dispatch4(_, _, _, _) click to toggle source
# File yarp/ripper_compat.rb, line 166
def _dispatch4(_, _, _, _); end
_dispatch5(_, _, _, _, _) click to toggle source
# File yarp/ripper_compat.rb, line 167
def _dispatch5(_, _, _, _, _); end
_dispatch7(_, _, _, _, _, _, _) click to toggle source
# File yarp/ripper_compat.rb, line 168
def _dispatch7(_, _, _, _, _, _, _); end
bounds(location) click to toggle source

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
result() click to toggle source
# File yarp/ripper_compat.rb, line 158
def result
  @result ||= YARP.parse(source)
end