Class: Prism::RipperCompat

Inherits:
Visitor
  • Object
show all
Defined in:
lib/prism/ripper_compat.rb

Overview

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.

Direct Known Subclasses

SexpBuilder

Defined Under Namespace

Classes: SexpBuilder, SexpBuilderPP

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source) ⇒ RipperCompat

Create a new RipperCompat object with the given source.



74
75
76
77
78
79
# File 'lib/prism/ripper_compat.rb', line 74

def initialize(source)
  @source = source
  @result = nil
  @lineno = nil
  @column = nil
end

Instance Attribute Details

#columnObject (readonly)

The current column number of the parser.



71
72
73
# File 'lib/prism/ripper_compat.rb', line 71

def column
  @column
end

#linenoObject (readonly)

The current line number of the parser.



68
69
70
# File 'lib/prism/ripper_compat.rb', line 68

def lineno
  @lineno
end

#sourceObject (readonly)

The source that is being parsed.



65
66
67
# File 'lib/prism/ripper_compat.rb', line 65

def source
  @source
end

Class Method Details

.sexp(source) ⇒ Object

This is a convenience method that runs the SexpBuilderPP subclass parser.



171
172
173
# File 'lib/prism/ripper_compat.rb', line 171

def self.sexp(source)
  SexpBuilderPP.new(source).parse
end

.sexp_raw(source) ⇒ Object

This is a convenience method that runs the SexpBuilder subclass parser.



166
167
168
# File 'lib/prism/ripper_compat.rb', line 166

def self.sexp_raw(source)
  SexpBuilder.new(source).parse
end

Instance Method Details

#error?Boolean

True if the parser encountered an error during parsing.

Returns:

  • (Boolean)


86
87
88
# File 'lib/prism/ripper_compat.rb', line 86

def error?
  result.failure?
end

#parseObject

Parse the source and return the result.



91
92
93
94
95
96
97
98
99
100
101
102
103
# 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) ⇒ Object

Visit a CallNode node.



110
111
112
113
114
115
116
117
118
119
120
# 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) ⇒ Object

Visit a FloatNode node.



123
124
125
126
# 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) ⇒ Object

Visit a ImaginaryNode node.



129
130
131
132
# 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) ⇒ Object

Visit an IntegerNode node.



135
136
137
138
# 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) ⇒ Object

Visit a ProgramNode node.



155
156
157
158
159
# 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) ⇒ Object

Visit a RationalNode node.



141
142
143
144
# 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) ⇒ Object

Visit a StatementsNode node.



147
148
149
150
151
152
# 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