class Prism::RipperCompat

Note: This integration is not finished, and therefore still has many inconsistencies with Ripper. If you’d like to help out, pull requests would be greatly appreciated!

This class is meant to provide a compatibility layer between prism 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 prism. It is also meant as a test harness for the prism parser.

To use this class, you treat ‘Prism::RipperCompat` effectively as you would treat the `Ripper` class.

Attributes

column[R]

The current column number of the parser.

lineno[R]

The current line number of the parser.

source[R]

The source that is being parsed.

Public Class Methods

new(source) click to toggle source

Create a new RipperCompat object with the given source.

# File lib/prism/ripper_compat.rb, line 74
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 lib/prism/ripper_compat.rb, line 171
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 lib/prism/ripper_compat.rb, line 166
def self.sexp_raw(source)
  SexpBuilder.new(source).parse
end

Public Instance Methods

error?() click to toggle source

True if the parser encountered an error during parsing.

# File lib/prism/ripper_compat.rb, line 86
def error?
  result.failure?
end
parse() click to toggle source

Parse the source and return the result.

# File lib/prism/ripper_compat.rb, line 91
def parse
  result.magic_comments.each do |magic_comment|
    on_magic_comment(magic_comment.key, magic_comment.value)
  end

  if error?
    result.errors.each do |error|
      on_parse_error(error.message)
    end
  else
    result.value.accept(self)
  end
end
visit_call_node(node) click to toggle source

Visit a CallNode node.

# File lib/prism/ripper_compat.rb, line 110
def visit_call_node(node)
  if !node.message.match?(/^[[:alpha:]_]/) && node.opening_loc.nil? && node.arguments&.arguments&.length == 1
    left = visit(node.receiver)
    right = visit(node.arguments.arguments.first)

    bounds(node.location)
    on_binary(left, node.name, right)
  else
    raise NotImplementedError
  end
end
visit_float_node(node) click to toggle source

Visit a FloatNode node.

# File lib/prism/ripper_compat.rb, line 123
def visit_float_node(node)
  bounds(node.location)
  on_float(node.slice)
end
visit_imaginary_node(node) click to toggle source

Visit a ImaginaryNode node.

# File lib/prism/ripper_compat.rb, line 129
def visit_imaginary_node(node)
  bounds(node.location)
  on_imaginary(node.slice)
end
visit_integer_node(node) click to toggle source

Visit an IntegerNode node.

# File lib/prism/ripper_compat.rb, line 135
def visit_integer_node(node)
  bounds(node.location)
  on_int(node.slice)
end
visit_program_node(node) click to toggle source

Visit a ProgramNode node.

# File lib/prism/ripper_compat.rb, line 155
def visit_program_node(node)
  statements = visit(node.statements)
  bounds(node.location)
  on_program(statements)
end
visit_rational_node(node) click to toggle source

Visit a RationalNode node.

# File lib/prism/ripper_compat.rb, line 141
def visit_rational_node(node)
  bounds(node.location)
  on_rational(node.slice)
end
visit_statements_node(node) click to toggle source

Visit a StatementsNode node.

# File lib/prism/ripper_compat.rb, line 147
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

Private Instance Methods

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 lib/prism/ripper_compat.rb, line 182
def bounds(location)
  @lineno = location.start_line
  @column = location.start_column
end
result() click to toggle source

Lazily initialize the parse result.

# File lib/prism/ripper_compat.rb, line 188
def result
  @result ||= Prism.parse(source)
end