Class: YARP::RipperCompat

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

Overview

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.

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

Returns a new instance of RipperCompat.



59
60
61
62
63
64
# File 'lib/yarp/ripper_compat.rb', line 59

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

Instance Attribute Details

#columnObject (readonly)

Returns the value of attribute column.



57
58
59
# File 'lib/yarp/ripper_compat.rb', line 57

def column
  @column
end

#linenoObject (readonly)

Returns the value of attribute lineno.



57
58
59
# File 'lib/yarp/ripper_compat.rb', line 57

def lineno
  @lineno
end

#sourceObject (readonly)

Returns the value of attribute source.



57
58
59
# File 'lib/yarp/ripper_compat.rb', line 57

def source
  @source
end

Class Method Details

.sexp(source) ⇒ Object

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



140
141
142
# File 'lib/yarp/ripper_compat.rb', line 140

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

.sexp_raw(source) ⇒ Object

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



135
136
137
# File 'lib/yarp/ripper_compat.rb', line 135

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

Instance Method Details

#error?Boolean

Public interface

Returns:

  • (Boolean)


70
71
72
# File 'lib/yarp/ripper_compat.rb', line 70

def error?
  result.errors.any?
end

#parseObject



74
75
76
# File 'lib/yarp/ripper_compat.rb', line 74

def parse
  result.value.accept(self) unless error?
end

#visit(node) ⇒ Object

Visitor methods



82
83
84
# File 'lib/yarp/ripper_compat.rb', line 82

def visit(node)
  node&.accept(self)
end

#visit_call_node(node) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/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) ⇒ Object



100
101
102
103
# File 'lib/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) ⇒ Object



125
126
127
128
# File 'lib/yarp/ripper_compat.rb', line 125

def visit_program_node(node)
  bounds(node.location)
  on_program(visit(node.statements))
end

#visit_statements_node(node) ⇒ Object



105
106
107
108
109
110
# File 'lib/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) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/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