class Prism::Translation::Ripper
This class provides 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. To use this class, you treat Prism::Translation::Ripper
effectively as you would treat the Ripper
class.
Note that this class will serve the most common use cases, but Ripper’s API is extensive and undocumented. It relies on reporting the state of the parser at any given time. We do our best to replicate that here, but because it is a different architecture it is not possible to perfectly replicate the behavior of Ripper
.
The main known difference is that we may omit dispatching some events in some cases. This impacts the following events:
-
on_assign_error
-
on_comma
-
on_ignored_nl
-
on_ignored_sp
-
on_kw
-
on_label_end
-
on_lbrace
-
on_lbracket
-
on_lparen
-
on_nl
-
on_op
-
on_operator_ambiguous
-
on_rbrace
-
on_rbracket
-
on_rparen
-
on_semicolon
-
on_sp
-
on_symbeg
-
on_tstring_beg
-
on_tstring_end
Constants
- BINARY_OPERATORS
-
A list of all of the Ruby binary operators.
- EVENTS
-
This array contains name of all ripper events.
- KEYWORDS
-
A list of all of the Ruby keywords.
- PARSER_EVENTS
-
This array contains name of parser events.
- PARSER_EVENT_TABLE
-
This contains a table of all of the parser events and their corresponding arity.
- SCANNER_EVENTS
-
This array contains name of scanner events.
- SCANNER_EVENT_TABLE
-
This contains a table of all of the scanner events and their corresponding arity.
Attributes
The current column number of the parser.
The filename of the source being parsed.
The current line number of the parser.
The source that is being parsed.
Public Class Methods
Source
# File lib/prism/translation/ripper.rb, line 73 def self.lex(src, filename = "-", lineno = 1, raise_errors: false) result = Prism.lex_compat(src, filepath: filename, line: lineno) if result.failure? && raise_errors raise SyntaxError, result.errors.first.message else result.value end end
Tokenizes the Ruby program and returns an array of an array, which is formatted like [[lineno, column], type, token, state]
. The filename
argument is mostly ignored. By default, this method does not handle syntax errors in src
, use the raise_errors
keyword to raise a SyntaxError
for an error in src
.
require "ripper" require "pp" pp Ripper.lex("def m(a) nil end") #=> [[[1, 0], :on_kw, "def", FNAME ], [[1, 3], :on_sp, " ", FNAME ], [[1, 4], :on_ident, "m", ENDFN ], [[1, 5], :on_lparen, "(", BEG|LABEL], [[1, 6], :on_ident, "a", ARG ], [[1, 7], :on_rparen, ")", ENDFN ], [[1, 8], :on_sp, " ", BEG ], [[1, 9], :on_kw, "nil", END ], [[1, 12], :on_sp, " ", END ], [[1, 13], :on_kw, "end", END ]]
Source
# File lib/prism/translation/ripper.rb, line 445 def initialize(source, filename = "(ripper)", lineno = 1) @source = source @filename = filename @lineno = lineno @column = 0 @result = nil end
Create a new Translation::Ripper
object with the given source.
Source
Source
# File lib/prism/translation/ripper.rb, line 382 def self.sexp(src, filename = "-", lineno = 1, raise_errors: false) builder = SexpBuilderPP.new(src, filename, lineno) sexp = builder.parse if builder.error? if raise_errors raise SyntaxError, builder.error end else sexp end end
Parses src
and create S-exp tree. Returns more readable tree rather than Ripper.sexp_raw
. This method is mainly for developer use. The filename
argument is mostly ignored. By default, this method does not handle syntax errors in src
, returning nil
in such cases. Use the raise_errors
keyword to raise a SyntaxError
for an error in src
.
require "ripper" require "pp" pp Ripper.sexp("def m(a) nil end") #=> [:program, [[:def, [:@ident, "m", [1, 4]], [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil, nil, nil]], [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
Source
# File lib/prism/translation/ripper.rb, line 417 def self.sexp_raw(src, filename = "-", lineno = 1, raise_errors: false) builder = SexpBuilder.new(src, filename, lineno) sexp = builder.parse if builder.error? if raise_errors raise SyntaxError, builder.error end else sexp end end
Parses src
and create S-exp tree. This method is mainly for developer use. The filename
argument is mostly ignored. By default, this method does not handle syntax errors in src
, returning nil
in such cases. Use the raise_errors
keyword to raise a SyntaxError
for an error in src
.
require "ripper" require "pp" pp Ripper.sexp_raw("def m(a) nil end") #=> [:program, [:stmts_add, [:stmts_new], [:def, [:@ident, "m", [1, 4]], [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil]], [:bodystmt, [:stmts_add, [:stmts_new], [:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]
Public Instance Methods
Source
# File lib/prism/translation/ripper.rb, line 458 def error? result.failure? end
True if the parser encountered an error during parsing.
Source
# File lib/prism/translation/ripper.rb, line 463 def parse result.comments.each do |comment| location = comment.location bounds(location) if comment.is_a?(InlineComment) on_comment(comment.slice) else offset = location.start_offset lines = comment.slice.lines lines.each_with_index do |line, index| bounds(location.copy(start_offset: offset)) if index == 0 on_embdoc_beg(line) elsif index == lines.size - 1 on_embdoc_end(line) else on_embdoc(line) end offset += line.bytesize end end end result.magic_comments.each do |magic_comment| on_magic_comment(magic_comment.key, magic_comment.value) end unless result.data_loc.nil? on___end__(result.data_loc.slice.each_line.first) end result.warnings.each do |warning| bounds(warning.location) if warning.level == :default warning(warning.message) else case warning.type when :ambiguous_first_argument_plus on_arg_ambiguous("+") when :ambiguous_first_argument_minus on_arg_ambiguous("-") when :ambiguous_slash on_arg_ambiguous("/") else warn(warning.message) end end end if error? result.errors.each do |error| location = error.location bounds(location) case error.type when :alias_argument on_alias_error("can't make alias for the number variables", location.slice) when :argument_formal_class on_param_error("formal argument cannot be a class variable", location.slice) when :argument_format_constant on_param_error("formal argument cannot be a constant", location.slice) when :argument_formal_global on_param_error("formal argument cannot be a global variable", location.slice) when :argument_formal_ivar on_param_error("formal argument cannot be an instance variable", location.slice) when :class_name, :module_name on_class_name_error("class/module name must be CONSTANT", location.slice) else on_parse_error(error.message) end end nil else result.value.accept(self) end end
Parse the source and return the result.
Source
# File lib/prism/translation/ripper.rb, line 562 def visit_alias_global_variable_node(node) new_name = visit_alias_global_variable_node_value(node.new_name) old_name = visit_alias_global_variable_node_value(node.old_name) bounds(node.location) on_var_alias(new_name, old_name) end
alias $foo $bar ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 552 def visit_alias_method_node(node) new_name = visit(node.new_name) old_name = visit(node.old_name) bounds(node.location) on_alias(new_name, old_name) end
alias foo bar ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 586 def visit_alternation_pattern_node(node) left = visit_pattern_node(node.left) right = visit_pattern_node(node.right) bounds(node.location) on_binary(left, :|, right) end
foo => bar | baz ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 606 def visit_and_node(node) left = visit(node.left) right = visit(node.right) bounds(node.location) on_binary(left, node.operator.to_sym, right) end
a and b ^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 797 def visit_arguments_node(node) arguments, _ = visit_call_node_arguments(node, nil, false) arguments end
foo(bar) ^^^
Source
# File lib/prism/translation/ripper.rb, line 616 def visit_array_node(node) case (opening = node.opening) when /^%w/ opening_loc = node.opening_loc bounds(opening_loc) on_qwords_beg(opening) elements = on_qwords_new previous = nil node.elements.each do |element| visit_words_sep(opening_loc, previous, element) bounds(element.location) elements = on_qwords_add(elements, on_tstring_content(element.content)) previous = element end bounds(node.closing_loc) on_tstring_end(node.closing) when /^%i/ opening_loc = node.opening_loc bounds(opening_loc) on_qsymbols_beg(opening) elements = on_qsymbols_new previous = nil node.elements.each do |element| visit_words_sep(opening_loc, previous, element) bounds(element.location) elements = on_qsymbols_add(elements, on_tstring_content(element.value)) previous = element end bounds(node.closing_loc) on_tstring_end(node.closing) when /^%W/ opening_loc = node.opening_loc bounds(opening_loc) on_words_beg(opening) elements = on_words_new previous = nil node.elements.each do |element| visit_words_sep(opening_loc, previous, element) bounds(element.location) elements = on_words_add( elements, if element.is_a?(StringNode) on_word_add(on_word_new, on_tstring_content(element.content)) else element.parts.inject(on_word_new) do |word, part| word_part = if part.is_a?(StringNode) bounds(part.location) on_tstring_content(part.content) else visit(part) end on_word_add(word, word_part) end end ) previous = element end bounds(node.closing_loc) on_tstring_end(node.closing) when /^%I/ opening_loc = node.opening_loc bounds(opening_loc) on_symbols_beg(opening) elements = on_symbols_new previous = nil node.elements.each do |element| visit_words_sep(opening_loc, previous, element) bounds(element.location) elements = on_symbols_add( elements, if element.is_a?(SymbolNode) on_word_add(on_word_new, on_tstring_content(element.value)) else element.parts.inject(on_word_new) do |word, part| word_part = if part.is_a?(StringNode) bounds(part.location) on_tstring_content(part.content) else visit(part) end on_word_add(word, word_part) end end ) previous = element end bounds(node.closing_loc) on_tstring_end(node.closing) else bounds(node.opening_loc) on_lbracket(opening) elements = visit_arguments(node.elements) unless node.elements.empty? bounds(node.closing_loc) on_rbracket(node.closing) end bounds(node.location) on_array(elements) end
[] ^^
Source
# File lib/prism/translation/ripper.rb, line 776 def visit_array_pattern_node(node) constant = visit(node.constant) requireds = visit_all(node.requireds) if node.requireds.any? rest = if (rest_node = node.rest).is_a?(SplatNode) if rest_node.expression.nil? bounds(rest_node.location) on_var_field(nil) else visit(rest_node.expression) end end posts = visit_all(node.posts) if node.posts.any? bounds(node.location) on_aryptn(constant, requireds, rest, posts) end
foo => [bar] ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 804 def visit_assoc_node(node) key = visit(node.key) value = visit(node.value) bounds(node.location) on_assoc_new(key, value) end
{ a: 1 } ^^^^
Source
# File lib/prism/translation/ripper.rb, line 817 def visit_assoc_splat_node(node) value = visit(node.value) bounds(node.location) on_assoc_splat(value) end
def foo(); bar(); end ^^
{ **foo } ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 826 def visit_back_reference_read_node(node) bounds(node.location) on_backref(node.slice) end
$+ ^^
Source
# File lib/prism/translation/ripper.rb, line 833 def visit_begin_node(node) clauses = visit_begin_node_clauses(node.begin_keyword_loc, node, false) bounds(node.location) on_begin(clauses) end
begin end ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 897 def visit_block_argument_node(node) visit(node.expression) end
foo(&bar) ^^^^
Source
# File lib/prism/translation/ripper.rb, line 903 def visit_block_local_variable_node(node) bounds(node.location) on_ident(node.name.to_s) end
foo { |; bar| } ^^^
Source
# File lib/prism/translation/ripper.rb, line 909 def visit_block_node(node) braces = node.opening == "{" parameters = visit(node.parameters) body = case node.body when nil bounds(node.location) stmts = on_stmts_add(on_stmts_new, on_void_stmt) bounds(node.location) braces ? stmts : on_bodystmt(stmts, nil, nil, nil) when StatementsNode stmts = node.body.body stmts.unshift(nil) if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false) stmts = visit_statements_node_body(stmts) bounds(node.body.location) braces ? stmts : on_bodystmt(stmts, nil, nil, nil) when BeginNode visit_body_node(node.parameters&.location || node.opening_loc, node.body) else raise end if braces bounds(node.location) on_brace_block(parameters, body) else bounds(node.location) on_do_block(parameters, body) end end
Visit a BlockNode
.
Source
# File lib/prism/translation/ripper.rb, line 945 def visit_block_parameter_node(node) if node.name_loc.nil? bounds(node.location) on_blockarg(nil) else bounds(node.name_loc) name = visit_token(node.name.to_s) bounds(node.location) on_blockarg(name) end end
def foo(&bar); end ^^^^
Source
# File lib/prism/translation/ripper.rb, line 959 def visit_block_parameters_node(node) parameters = if node.parameters.nil? on_params(nil, nil, nil, nil, nil, nil, nil) else visit(node.parameters) end locals = if node.locals.any? visit_all(node.locals) else false end bounds(node.location) on_block_var(parameters, locals) end
A block’s parameters.
Source
# File lib/prism/translation/ripper.rb, line 983 def visit_break_node(node) if node.arguments.nil? bounds(node.location) on_break(on_args_new) else arguments = visit(node.arguments) bounds(node.location) on_break(arguments) end end
break ^^^^^
break foo ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1205 def visit_call_and_write_node(node) receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) bounds(node.message_loc) message = visit_token(node.message) bounds(node.location) target = on_field(receiver, call_operator, message) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo.bar &&= baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1003 def visit_call_node(node) if node.call_operator_loc.nil? case node.name when :[] receiver = visit(node.receiver) arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) bounds(node.location) call = on_aref(receiver, arguments) if block.nil? call else bounds(node.location) on_method_add_block(call, block) end when :[]= receiver = visit(node.receiver) *arguments, last_argument = node.arguments.arguments arguments << node.block if !node.block.nil? arguments = if arguments.any? args = visit_arguments(arguments) if !node.block.nil? args else bounds(arguments.first.location) on_args_add_block(args, false) end end bounds(node.location) call = on_aref_field(receiver, arguments) value = visit_write_value(last_argument) bounds(last_argument.location) on_assign(call, value) when :-@, :+@, :~ receiver = visit(node.receiver) bounds(node.location) on_unary(node.name, receiver) when :! if node.message == "not" receiver = if !node.receiver.is_a?(ParenthesesNode) || !node.receiver.body.nil? visit(node.receiver) end bounds(node.location) on_unary(:not, receiver) else receiver = visit(node.receiver) bounds(node.location) on_unary(:!, receiver) end when *BINARY_OPERATORS receiver = visit(node.receiver) value = visit(node.arguments.arguments.first) bounds(node.location) on_binary(receiver, node.name, value) else bounds(node.message_loc) message = visit_token(node.message, false) if node.variable_call? on_vcall(message) else arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location)) call = if node.opening_loc.nil? && arguments&.any? bounds(node.location) on_command(message, arguments) elsif !node.opening_loc.nil? bounds(node.location) on_method_add_arg(on_fcall(message), on_arg_paren(arguments)) else bounds(node.location) on_method_add_arg(on_fcall(message), on_args_new) end if block.nil? call else bounds(node.block.location) on_method_add_block(call, block) end end end else receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) message = if node.message_loc.nil? :call else bounds(node.message_loc) visit_token(node.message, false) end if node.name.end_with?("=") && !node.message.end_with?("=") && !node.arguments.nil? && node.block.nil? value = visit_write_value(node.arguments.arguments.first) bounds(node.location) on_assign(on_field(receiver, call_operator, message), value) else arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location)) call = if node.opening_loc.nil? bounds(node.location) if node.arguments.nil? && !node.block.is_a?(BlockArgumentNode) on_call(receiver, call_operator, message) else on_command_call(receiver, call_operator, message, arguments) end else bounds(node.opening_loc) arguments = on_arg_paren(arguments) bounds(node.location) on_method_add_arg(on_call(receiver, call_operator, message), arguments) end if block.nil? call else bounds(node.block.location) on_method_add_block(call, block) end end end end
foo ^^^
foo.bar ^^^^^^^
foo.bar() {} ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1183 def visit_call_operator_write_node(node) receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) bounds(node.message_loc) message = visit_token(node.message) bounds(node.location) target = on_field(receiver, call_operator, message) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo.bar += baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1227 def visit_call_or_write_node(node) receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) bounds(node.message_loc) message = visit_token(node.message) bounds(node.location) target = on_field(receiver, call_operator, message) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo.bar ||= baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1249 def visit_call_target_node(node) if node.call_operator == "::" receiver = visit(node.receiver) bounds(node.message_loc) message = visit_token(node.message) bounds(node.location) on_const_path_field(receiver, message) else receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) bounds(node.message_loc) message = visit_token(node.message) bounds(node.location) on_field(receiver, call_operator, message) end end
foo.bar, = 1 ^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1274 def visit_capture_pattern_node(node) value = visit(node.value) target = visit(node.target) bounds(node.location) on_binary(value, :"=>", target) end
foo => bar => baz ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1297 def visit_case_match_node(node) predicate = visit(node.predicate) clauses = node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition| on_in(*visit(condition), current) end bounds(node.location) on_case(predicate, clauses) end
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1284 def visit_case_node(node) predicate = visit(node.predicate) clauses = node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition| on_when(*visit(condition), current) end bounds(node.location) on_case(predicate, clauses) end
case foo; when bar; end ^^^^^^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1310 def visit_class_node(node) constant_path = if node.constant_path.is_a?(ConstantReadNode) bounds(node.constant_path.location) on_const_ref(on_const(node.constant_path.name.to_s)) else visit(node.constant_path) end superclass = visit(node.superclass) bodystmt = visit_body_node(node.superclass&.location || node.constant_path.location, node.body, node.superclass.nil?) bounds(node.location) on_class(constant_path, superclass, bodystmt) end
class Foo; end ^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1363 def visit_class_variable_and_write_node(node) bounds(node.name_loc) target = on_var_field(on_cvar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@@foo &&= bar ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1349 def visit_class_variable_operator_write_node(node) bounds(node.name_loc) target = on_var_field(on_cvar(node.name.to_s)) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@@foo += bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1377 def visit_class_variable_or_write_node(node) bounds(node.name_loc) target = on_var_field(on_cvar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@@foo ||= bar ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1328 def visit_class_variable_read_node(node) bounds(node.location) on_var_ref(on_cvar(node.slice)) end
@@foo ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1391 def visit_class_variable_target_node(node) bounds(node.location) on_var_field(on_cvar(node.name.to_s)) end
@@foo, = bar ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1338 def visit_class_variable_write_node(node) bounds(node.name_loc) target = on_var_field(on_cvar(node.name.to_s)) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
@@foo = 1 ^^^^^^^^^
@@foo, @@bar = 1 ^^^^^ ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1433 def visit_constant_and_write_node(node) bounds(node.name_loc) target = on_var_field(on_const(node.name.to_s)) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo &&= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1419 def visit_constant_operator_write_node(node) bounds(node.name_loc) target = on_var_field(on_const(node.name.to_s)) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo += bar ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1447 def visit_constant_or_write_node(node) bounds(node.name_loc) target = on_var_field(on_const(node.name.to_s)) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo ||= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1534 def visit_constant_path_and_write_node(node) target = visit_constant_path_write_node_target(node.target) value = visit(node.value) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo::Bar &&= baz ^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1468 def visit_constant_path_node(node) if node.parent.nil? bounds(node.name_loc) child = on_const(node.name.to_s) bounds(node.location) on_top_const_ref(child) else parent = visit(node.parent) bounds(node.name_loc) child = on_const(node.name.to_s) bounds(node.location) on_const_path_ref(parent, child) end end
Foo::Bar ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1520 def visit_constant_path_operator_write_node(node) target = visit_constant_path_write_node_target(node.target) value = visit(node.value) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo::Bar += baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1548 def visit_constant_path_or_write_node(node) target = visit_constant_path_write_node_target(node.target) value = visit(node.value) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
Foo::Bar ||= baz ^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1562 def visit_constant_path_target_node(node) visit_constant_path_write_node_target(node) end
Foo::Bar, = baz ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1491 def visit_constant_path_write_node(node) target = visit_constant_path_write_node_target(node.target) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
Foo::Bar = 1 ^^^^^^^^^^^^
Foo::Foo, Bar::Bar = 1 ^^^^^^^^ ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1398 def visit_constant_read_node(node) bounds(node.location) on_var_ref(on_const(node.name.to_s)) end
Foo ^^^
Source
# File lib/prism/translation/ripper.rb, line 1461 def visit_constant_target_node(node) bounds(node.location) on_var_field(on_const(node.name.to_s)) end
Foo, = bar ^^^
Source
# File lib/prism/translation/ripper.rb, line 1408 def visit_constant_write_node(node) bounds(node.name_loc) target = on_var_field(on_const(node.name.to_s)) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
Foo = 1 ^^^^^^^
Foo, Bar = 1 ^^^ ^^^
Source
# File lib/prism/translation/ripper.rb, line 1571 def visit_def_node(node) receiver = visit(node.receiver) operator = if !node.operator_loc.nil? bounds(node.operator_loc) visit_token(node.operator) end bounds(node.name_loc) name = visit_token(node.name_loc.slice) parameters = if node.parameters.nil? bounds(node.location) on_params(nil, nil, nil, nil, nil, nil, nil) else visit(node.parameters) end if !node.lparen_loc.nil? bounds(node.lparen_loc) parameters = on_paren(parameters) end bodystmt = if node.equal_loc.nil? visit_body_node(node.rparen_loc || node.end_keyword_loc, node.body) else body = visit(node.body.body.first) bounds(node.body.location) on_bodystmt(body, nil, nil, nil) end bounds(node.location) if receiver.nil? on_def(name, parameters, bodystmt) else on_defs(receiver, operator, name, parameters, bodystmt) end end
def foo; end ^^^^^^^^^^^^
def self.foo; end ^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1618 def visit_defined_node(node) expression = visit(node.value) # Very weird circumstances here where something like: # # defined? # (1) # # gets parsed in Ruby as having only the `1` expression but in Ripper it # gets parsed as having a parentheses node. In this case we need to # synthesize that node to match Ripper's behavior. if node.lparen_loc && node.keyword_loc.join(node.lparen_loc).slice.include?("\n") bounds(node.lparen_loc.join(node.rparen_loc)) expression = on_paren(on_stmts_add(on_stmts_new, expression)) end bounds(node.location) on_defined(expression) end
defined? a ^^^^^^^^^^
defined?(a) ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1640 def visit_else_node(node) statements = if node.statements.nil? [nil] else body = node.statements.body body.unshift(nil) if void_stmt?(node.else_keyword_loc, node.statements.body[0].location, false) body end bounds(node.location) on_else(visit_statements_node_body(statements)) end
if foo then bar else baz end ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1656 def visit_embedded_statements_node(node) bounds(node.opening_loc) on_embexpr_beg(node.opening) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.closing_loc) on_embexpr_end(node.closing) bounds(node.location) on_string_embexpr(statements) end
“foo #{bar}” ^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1677 def visit_embedded_variable_node(node) bounds(node.operator_loc) on_embvar(node.operator) variable = visit(node.variable) bounds(node.location) on_string_dvar(variable) end
“foo #@bar” ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1688 def visit_ensure_node(node) statements = if node.statements.nil? [nil] else body = node.statements.body body.unshift(nil) if void_stmt?(node.ensure_keyword_loc, body[0].location, false) body end statements = visit_statements_node_body(statements) bounds(node.location) on_ensure(statements) end
Visit an EnsureNode
node.
Source
# File lib/prism/translation/ripper.rb, line 1706 def visit_false_node(node) bounds(node.location) on_var_ref(on_kw("false")) end
false ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1713 def visit_find_pattern_node(node) constant = visit(node.constant) left = if node.left.expression.nil? bounds(node.left.location) on_var_field(nil) else visit(node.left.expression) end requireds = visit_all(node.requireds) if node.requireds.any? right = if node.right.expression.nil? bounds(node.right.location) on_var_field(nil) else visit(node.right.expression) end bounds(node.location) on_fndptn(constant, left, requireds, right) end
foo => [, bar, ] ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1738 def visit_flip_flop_node(node) left = visit(node.left) right = visit(node.right) bounds(node.location) if node.exclude_end? on_dot3(left, right) else on_dot2(left, right) end end
if foo .. bar; end ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1752 def visit_float_node(node) visit_number_node(node) { |text| on_float(text) } end
1.0 ^^^
Source
# File lib/prism/translation/ripper.rb, line 1758 def visit_for_node(node) index = visit(node.index) collection = visit(node.collection) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.location) on_for(index, collection, statements) end
for foo in bar do end ^^^^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1775 def visit_forwarding_arguments_node(node) bounds(node.location) on_args_forward end
def foo(…); bar(…); end ^^^
Source
# File lib/prism/translation/ripper.rb, line 1782 def visit_forwarding_parameter_node(node) bounds(node.location) on_args_forward end
def foo(…); end ^^^
Source
# File lib/prism/translation/ripper.rb, line 1792 def visit_forwarding_super_node(node) if node.block.nil? bounds(node.location) on_zsuper else block = visit(node.block) bounds(node.location) on_method_add_block(on_zsuper, block) end end
super ^^^^^
super {} ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1841 def visit_global_variable_and_write_node(node) bounds(node.name_loc) target = on_var_field(on_gvar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
$foo &&= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1827 def visit_global_variable_operator_write_node(node) bounds(node.name_loc) target = on_var_field(on_gvar(node.name.to_s)) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
$foo += bar ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1855 def visit_global_variable_or_write_node(node) bounds(node.name_loc) target = on_var_field(on_gvar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
$foo ||= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1806 def visit_global_variable_read_node(node) bounds(node.location) on_var_ref(on_gvar(node.name.to_s)) end
$foo ^^^^
Source
# File lib/prism/translation/ripper.rb, line 1869 def visit_global_variable_target_node(node) bounds(node.location) on_var_field(on_gvar(node.name.to_s)) end
$foo, = bar ^^^^
Source
# File lib/prism/translation/ripper.rb, line 1816 def visit_global_variable_write_node(node) bounds(node.name_loc) target = on_var_field(on_gvar(node.name.to_s)) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
$foo = 1 ^^^^^^^^
$foo, $bar = 1 ^^^^ ^^^^
Source
# File lib/prism/translation/ripper.rb, line 1876 def visit_hash_node(node) elements = if node.elements.any? args = visit_all(node.elements) bounds(node.elements.first.location) on_assoclist_from_args(args) end bounds(node.location) on_hash(elements) end
{} ^^
Source
# File lib/prism/translation/ripper.rb, line 1891 def visit_hash_pattern_node(node) constant = visit(node.constant) elements = if node.elements.any? || !node.rest.nil? node.elements.map do |element| [ if (key = element.key).opening_loc.nil? visit(key) else bounds(key.value_loc) if (value = key.value).empty? on_string_content else on_string_add(on_string_content, on_tstring_content(value)) end end, visit(element.value) ] end end rest = case node.rest when AssocSplatNode visit(node.rest.value) when NoKeywordsParameterNode bounds(node.rest.location) on_var_field(visit(node.rest)) end bounds(node.location) on_hshptn(constant, elements, rest) end
foo => {} ^^
Source
# File lib/prism/translation/ripper.rb, line 1933 def visit_if_node(node) if node.then_keyword == "?" predicate = visit(node.predicate) truthy = visit(node.statements.body.first) falsy = visit(node.subsequent.statements.body.first) bounds(node.location) on_ifop(predicate, truthy, falsy) elsif node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) predicate = visit(node.predicate) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end subsequent = visit(node.subsequent) bounds(node.location) if node.if_keyword == "if" on_if(predicate, statements, subsequent) else on_elsif(predicate, statements, subsequent) end else statements = visit(node.statements.body.first) predicate = visit(node.predicate) bounds(node.location) on_if_mod(predicate, statements) end end
if foo then bar end ^^^^^^^^^^^^^^^^^^^
bar if foo ^^^^^^^^^^
foo ? bar : baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 1969 def visit_imaginary_node(node) visit_number_node(node) { |text| on_imaginary(text) } end
1i ^^
Source
# File lib/prism/translation/ripper.rb, line 1975 def visit_implicit_node(node) end
{ foo: } ^^^^
Source
# File lib/prism/translation/ripper.rb, line 1980 def visit_implicit_rest_node(node) bounds(node.location) on_excessed_comma end
foo { |bar,| } ^
Source
# File lib/prism/translation/ripper.rb, line 1987 def visit_in_node(node) # This is a special case where we're not going to call on_in directly # because we don't have access to the subsequent. Instead, we'll return # the component parts and let the parent node handle it. pattern = visit_pattern_node(node.pattern) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end [pattern, statements] end
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2022 def visit_index_and_write_node(node) receiver = visit(node.receiver) arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) bounds(node.location) target = on_aref_field(receiver, arguments) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo &&= baz ^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2005 def visit_index_operator_write_node(node) receiver = visit(node.receiver) arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) bounds(node.location) target = on_aref_field(receiver, arguments) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo += baz ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2039 def visit_index_or_write_node(node) receiver = visit(node.receiver) arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) bounds(node.location) target = on_aref_field(receiver, arguments) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo ||= baz ^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2056 def visit_index_target_node(node) receiver = visit(node.receiver) arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc)) bounds(node.location) on_aref_field(receiver, arguments) end
foo, = 1 ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2098 def visit_instance_variable_and_write_node(node) bounds(node.name_loc) target = on_var_field(on_ivar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@foo &&= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2084 def visit_instance_variable_operator_write_node(node) bounds(node.name_loc) target = on_var_field(on_ivar(node.name.to_s)) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@foo += bar ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2112 def visit_instance_variable_or_write_node(node) bounds(node.name_loc) target = on_var_field(on_ivar(node.name.to_s)) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
@foo ||= bar ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2066 def visit_instance_variable_read_node(node) bounds(node.location) on_var_ref(on_ivar(node.name.to_s)) end
@foo ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2126 def visit_instance_variable_target_node(node) bounds(node.location) on_var_field(on_ivar(node.name.to_s)) end
@foo, = bar ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2073 def visit_instance_variable_write_node(node) bounds(node.name_loc) target = on_var_field(on_ivar(node.name.to_s)) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
@foo = 1 ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2133 def visit_integer_node(node) visit_number_node(node) { |text| on_int(text) } end
1 ^
Source
# File lib/prism/translation/ripper.rb, line 2139 def visit_interpolated_match_last_line_node(node) bounds(node.opening_loc) on_regexp_beg(node.opening) bounds(node.parts.first.location) parts = node.parts.inject(on_regexp_new) do |content, part| on_regexp_add(content, visit_string_content(part)) end bounds(node.closing_loc) closing = on_regexp_end(node.closing) bounds(node.location) on_regexp_literal(parts, closing) end
if /foo #{bar}/ then end ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2158 def visit_interpolated_regular_expression_node(node) bounds(node.opening_loc) on_regexp_beg(node.opening) bounds(node.parts.first.location) parts = node.parts.inject(on_regexp_new) do |content, part| on_regexp_add(content, visit_string_content(part)) end bounds(node.closing_loc) closing = on_regexp_end(node.closing) bounds(node.location) on_regexp_literal(parts, closing) end
/foo #{bar}/ ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2177 def visit_interpolated_string_node(node) if node.opening&.start_with?("<<~") heredoc = visit_heredoc_string_node(node) bounds(node.location) on_string_literal(heredoc) elsif !node.heredoc? && node.parts.length > 1 && node.parts.any? { |part| (part.is_a?(StringNode) || part.is_a?(InterpolatedStringNode)) && !part.opening_loc.nil? } first, *rest = node.parts rest.inject(visit(first)) do |content, part| concat = visit(part) bounds(part.location) on_string_concat(content, concat) end else bounds(node.parts.first.location) parts = node.parts.inject(on_string_content) do |content, part| on_string_add(content, visit_string_content(part)) end bounds(node.location) on_string_literal(parts) end end
“foo #{bar}” ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2205 def visit_interpolated_symbol_node(node) bounds(node.parts.first.location) parts = node.parts.inject(on_string_content) do |content, part| on_string_add(content, visit_string_content(part)) end bounds(node.location) on_dyna_symbol(parts) end
:“foo #{bar}” ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2218 def visit_interpolated_x_string_node(node) if node.opening.start_with?("<<~") heredoc = visit_heredoc_x_string_node(node) bounds(node.location) on_xstring_literal(heredoc) else bounds(node.parts.first.location) parts = node.parts.inject(on_xstring_new) do |content, part| on_xstring_add(content, visit_string_content(part)) end bounds(node.location) on_xstring_literal(parts) end end
foo #{bar}
^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2248 def visit_it_local_variable_read_node(node) bounds(node.location) on_vcall(on_ident(node.slice)) end
-> { it } ^^
Source
# File lib/prism/translation/ripper.rb, line 2255 def visit_it_parameters_node(node) end
-> { it } ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2260 def visit_keyword_hash_node(node) elements = visit_all(node.elements) bounds(node.location) on_bare_assoc_hash(elements) end
foo(bar: baz) ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2272 def visit_keyword_rest_parameter_node(node) if node.name_loc.nil? bounds(node.location) on_kwrest_param(nil) else bounds(node.name_loc) name = on_ident(node.name.to_s) bounds(node.location) on_kwrest_param(name) end end
def foo(**bar); end ^^^^^
def foo(**); end ^^
Source
# File lib/prism/translation/ripper.rb, line 2286 def visit_lambda_node(node) bounds(node.operator_loc) on_tlambda(node.operator) parameters = if node.parameters.is_a?(BlockParametersNode) # Ripper does not track block-locals within lambdas, so we skip # directly to the parameters here. params = if node.parameters.parameters.nil? bounds(node.location) on_params(nil, nil, nil, nil, nil, nil, nil) else visit(node.parameters.parameters) end if node.parameters.opening_loc.nil? params else bounds(node.parameters.opening_loc) on_paren(params) end else bounds(node.location) on_params(nil, nil, nil, nil, nil, nil, nil) end braces = node.opening == "{" if braces bounds(node.opening_loc) on_tlambeg(node.opening) end body = case node.body when nil bounds(node.location) stmts = on_stmts_add(on_stmts_new, on_void_stmt) bounds(node.location) braces ? stmts : on_bodystmt(stmts, nil, nil, nil) when StatementsNode stmts = node.body.body stmts.unshift(nil) if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false) stmts = visit_statements_node_body(stmts) bounds(node.body.location) braces ? stmts : on_bodystmt(stmts, nil, nil, nil) when BeginNode visit_body_node(node.opening_loc, node.body) else raise end bounds(node.location) on_lambda(parameters, body) end
-> {}
Source
# File lib/prism/translation/ripper.rb, line 2378 def visit_local_variable_and_write_node(node) bounds(node.name_loc) target = on_var_field(on_ident(node.name_loc.slice)) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo &&= bar ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2364 def visit_local_variable_operator_write_node(node) bounds(node.name_loc) target = on_var_field(on_ident(node.name_loc.slice)) bounds(node.binary_operator_loc) operator = on_op("#{node.binary_operator}=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo += bar ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2392 def visit_local_variable_or_write_node(node) bounds(node.name_loc) target = on_var_field(on_ident(node.name_loc.slice)) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
foo ||= bar ^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2346 def visit_local_variable_read_node(node) bounds(node.location) on_var_ref(on_ident(node.slice)) end
foo ^^^
Source
# File lib/prism/translation/ripper.rb, line 2406 def visit_local_variable_target_node(node) bounds(node.location) on_var_field(on_ident(node.name.to_s)) end
foo, = bar ^^^
Source
# File lib/prism/translation/ripper.rb, line 2353 def visit_local_variable_write_node(node) bounds(node.name_loc) target = on_var_field(on_ident(node.name_loc.slice)) value = visit_write_value(node.value) bounds(node.location) on_assign(target, value) end
foo = 1 ^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2413 def visit_match_last_line_node(node) bounds(node.opening_loc) on_regexp_beg(node.opening) bounds(node.content_loc) tstring_content = on_tstring_content(node.content) bounds(node.closing_loc) closing = on_regexp_end(node.closing) on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing) end
if /foo/ then end ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2428 def visit_match_predicate_node(node) value = visit(node.value) pattern = on_in(visit_pattern_node(node.pattern), nil, nil) on_case(value, pattern) end
foo in bar ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2437 def visit_match_required_node(node) value = visit(node.value) pattern = on_in(visit_pattern_node(node.pattern), nil, nil) on_case(value, pattern) end
foo => bar ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2446 def visit_match_write_node(node) visit(node.call) end
/(?<foo>foo)/ =~ bar ^^^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2452 def visit_missing_node(node) raise "Cannot visit missing nodes directly." end
A node that is missing from the syntax tree. This is only used in the case of a syntax error.
Source
# File lib/prism/translation/ripper.rb, line 2458 def visit_module_node(node) constant_path = if node.constant_path.is_a?(ConstantReadNode) bounds(node.constant_path.location) on_const_ref(on_const(node.constant_path.name.to_s)) else visit(node.constant_path) end bodystmt = visit_body_node(node.constant_path.location, node.body, true) bounds(node.location) on_module(constant_path, bodystmt) end
module Foo; end ^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2475 def visit_multi_target_node(node) bounds(node.location) targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true) if node.lparen_loc.nil? targets else bounds(node.lparen_loc) on_mlhs_paren(targets) end end
(foo, bar), bar = qux ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2529 def visit_multi_write_node(node) bounds(node.location) targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true) unless node.lparen_loc.nil? bounds(node.lparen_loc) targets = on_mlhs_paren(targets) end value = visit_write_value(node.value) bounds(node.location) on_massign(targets, value) end
foo, bar = baz ^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2549 def visit_next_node(node) if node.arguments.nil? bounds(node.location) on_next(on_args_new) else arguments = visit(node.arguments) bounds(node.location) on_next(arguments) end end
next ^^^^
next foo ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2563 def visit_nil_node(node) bounds(node.location) on_var_ref(on_kw("nil")) end
nil ^^^
Source
# File lib/prism/translation/ripper.rb, line 2570 def visit_no_keywords_parameter_node(node) bounds(node.location) on_nokw_param(nil) :nil end
def foo(**nil); end ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2579 def visit_numbered_parameters_node(node) end
-> { 1 + 2 } ^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2584 def visit_numbered_reference_read_node(node) bounds(node.location) on_backref(node.slice) end
$1 ^^
Source
# File lib/prism/translation/ripper.rb, line 2591 def visit_optional_keyword_parameter_node(node) bounds(node.name_loc) name = on_label("#{node.name}:") value = visit(node.value) [name, value] end
def foo(bar: baz); end ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2601 def visit_optional_parameter_node(node) bounds(node.name_loc) name = visit_token(node.name.to_s) value = visit(node.value) [name, value] end
def foo(bar = 1); end ^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2611 def visit_or_node(node) left = visit(node.left) right = visit(node.right) bounds(node.location) on_binary(left, node.operator.to_sym, right) end
a or b ^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2621 def visit_parameters_node(node) requireds = node.requireds.map { |required| required.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(required) : visit(required) } if node.requireds.any? optionals = visit_all(node.optionals) if node.optionals.any? rest = visit(node.rest) posts = node.posts.map { |post| post.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(post) : visit(post) } if node.posts.any? keywords = visit_all(node.keywords) if node.keywords.any? keyword_rest = visit(node.keyword_rest) block = visit(node.block) bounds(node.location) on_params(requireds, optionals, rest, posts, keywords, keyword_rest, block) end
def foo(bar, *baz); end ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2648 def visit_parentheses_node(node) body = if node.body.nil? on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.body) end bounds(node.location) on_paren(body) end
() ^^
(1) ^^^
Source
# File lib/prism/translation/ripper.rb, line 2662 def visit_pinned_expression_node(node) expression = visit(node.expression) bounds(node.location) on_begin(expression) end
foo => ^(bar) ^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2671 def visit_pinned_variable_node(node) visit(node.variable) end
foo = 1 and bar => ^foo ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2677 def visit_post_execution_node(node) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.location) on_END(statements) end
END {} ^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2692 def visit_pre_execution_node(node) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.location) on_BEGIN(statements) end
BEGIN {} ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2706 def visit_program_node(node) body = node.statements.body body << nil if body.empty? statements = visit_statements_node_body(body) bounds(node.location) on_program(statements) end
The top-level program node.
Source
# File lib/prism/translation/ripper.rb, line 2717 def visit_range_node(node) left = visit(node.left) right = visit(node.right) bounds(node.location) if node.exclude_end? on_dot3(left, right) else on_dot2(left, right) end end
0..5 ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2731 def visit_rational_node(node) visit_number_node(node) { |text| on_rational(text) } end
1r ^^
Source
# File lib/prism/translation/ripper.rb, line 2737 def visit_redo_node(node) bounds(node.location) on_redo end
redo ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2744 def visit_regular_expression_node(node) bounds(node.opening_loc) on_regexp_beg(node.opening) if node.content.empty? bounds(node.closing_loc) closing = on_regexp_end(node.closing) on_regexp_literal(on_regexp_new, closing) else bounds(node.content_loc) tstring_content = on_tstring_content(node.content) bounds(node.closing_loc) closing = on_regexp_end(node.closing) on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing) end end
/foo/ ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2766 def visit_required_keyword_parameter_node(node) bounds(node.name_loc) [on_label("#{node.name}:"), false] end
def foo(bar:); end ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2773 def visit_required_parameter_node(node) bounds(node.location) on_ident(node.name.to_s) end
def foo(bar); end ^^^
Source
# File lib/prism/translation/ripper.rb, line 2780 def visit_rescue_modifier_node(node) expression = visit_write_value(node.expression) rescue_expression = visit(node.rescue_expression) bounds(node.location) on_rescue_mod(expression, rescue_expression) end
foo rescue bar ^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2790 def visit_rescue_node(node) exceptions = case node.exceptions.length when 0 nil when 1 if (exception = node.exceptions.first).is_a?(SplatNode) bounds(exception.location) on_mrhs_add_star(on_mrhs_new, visit(exception)) else [visit(node.exceptions.first)] end else bounds(node.location) length = node.exceptions.length node.exceptions.each_with_index.inject(on_args_new) do |mrhs, (exception, index)| arg = visit(exception) bounds(exception.location) mrhs = on_mrhs_new_from_args(mrhs) if index == length - 1 if exception.is_a?(SplatNode) if index == length - 1 on_mrhs_add_star(mrhs, arg) else on_args_add_star(mrhs, arg) end else if index == length - 1 on_mrhs_add(mrhs, arg) else on_args_add(mrhs, arg) end end end end reference = visit(node.reference) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end subsequent = visit(node.subsequent) bounds(node.location) on_rescue(exceptions, reference, statements, subsequent) end
begin; rescue; end ^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2848 def visit_rest_parameter_node(node) if node.name_loc.nil? bounds(node.location) on_rest_param(nil) else bounds(node.name_loc) on_rest_param(visit_token(node.name.to_s)) end end
def foo(*bar); end ^^^^
def foo(*); end ^
Source
# File lib/prism/translation/ripper.rb, line 2860 def visit_retry_node(node) bounds(node.location) on_retry end
retry ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2870 def visit_return_node(node) if node.arguments.nil? bounds(node.location) on_return0 else arguments = visit(node.arguments) bounds(node.location) on_return(arguments) end end
return ^^^^^^
return 1 ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2884 def visit_self_node(node) bounds(node.location) on_var_ref(on_kw("self")) end
self ^^^^
Source
# File lib/prism/translation/ripper.rb, line 2896 def visit_singleton_class_node(node) expression = visit(node.expression) bodystmt = visit_body_node(node.body&.location || node.end_keyword_loc, node.body) bounds(node.location) on_sclass(expression, bodystmt) end
class << self; end ^^^^^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2906 def visit_source_encoding_node(node) bounds(node.location) on_var_ref(on_kw("__ENCODING__")) end
ENCODING ^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2913 def visit_source_file_node(node) bounds(node.location) on_var_ref(on_kw("__FILE__")) end
FILE ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2920 def visit_source_line_node(node) bounds(node.location) on_var_ref(on_kw("__LINE__")) end
LINE ^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 2933 def visit_splat_node(node) visit(node.expression) end
foo(*bar) ^^^^
def foo((bar, *baz)); end ^^^^
def foo(); bar(); end ^
Source
# File lib/prism/translation/ripper.rb, line 2938 def visit_statements_node(node) bounds(node.location) visit_statements_node_body(node.body) end
A list of statements.
Source
# File lib/prism/translation/ripper.rb, line 2955 def visit_string_node(node) if (content = node.content).empty? bounds(node.location) on_string_literal(on_string_content) elsif (opening = node.opening) == "?" bounds(node.location) on_CHAR("?#{node.content}") elsif opening.start_with?("<<~") heredoc = visit_heredoc_string_node(node.to_interpolated) bounds(node.location) on_string_literal(heredoc) else bounds(node.content_loc) tstring_content = on_tstring_content(content) bounds(node.location) on_string_literal(on_string_add(on_string_content, tstring_content)) end end
“foo” ^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3087 def visit_super_node(node) arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.rparen_loc || node.location)) if !node.lparen_loc.nil? bounds(node.lparen_loc) arguments = on_arg_paren(arguments) end bounds(node.location) call = on_super(arguments) if block.nil? call else bounds(node.block.location) on_method_add_block(call, block) end end
super(foo) ^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3108 def visit_symbol_node(node) if (opening = node.opening)&.match?(/^%s|['"]:?$/) bounds(node.value_loc) content = on_string_content if !(value = node.value).empty? content = on_string_add(content, on_tstring_content(value)) end on_dyna_symbol(content) elsif (closing = node.closing) == ":" bounds(node.location) on_label("#{node.value}:") elsif opening.nil? && node.closing_loc.nil? bounds(node.value_loc) on_symbol_literal(visit_token(node.value)) else bounds(node.value_loc) on_symbol_literal(on_symbol(visit_token(node.value))) end end
:foo ^^^^
Source
# File lib/prism/translation/ripper.rb, line 3132 def visit_true_node(node) bounds(node.location) on_var_ref(on_kw("true")) end
true ^^^^
Source
# File lib/prism/translation/ripper.rb, line 3139 def visit_undef_node(node) names = visit_all(node.names) bounds(node.location) on_undef(names) end
undef foo ^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3151 def visit_unless_node(node) if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) predicate = visit(node.predicate) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end else_clause = visit(node.else_clause) bounds(node.location) on_unless(predicate, statements, else_clause) else statements = visit(node.statements.body.first) predicate = visit(node.predicate) bounds(node.location) on_unless_mod(predicate, statements) end end
unless foo; bar end ^^^^^^^^^^^^^^^^^^^
bar unless foo ^^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3179 def visit_until_node(node) if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) predicate = visit(node.predicate) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.location) on_until(predicate, statements) else statements = visit(node.statements.body.first) predicate = visit(node.predicate) bounds(node.location) on_until_mod(predicate, statements) end end
until foo; bar end ^^^^^^^^^^^^^^^^^
bar until foo ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3203 def visit_when_node(node) # This is a special case where we're not going to call on_when directly # because we don't have access to the subsequent. Instead, we'll return # the component parts and let the parent node handle it. conditions = visit_arguments(node.conditions) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end [conditions, statements] end
case foo; when bar; end ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3224 def visit_while_node(node) if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset) predicate = visit(node.predicate) statements = if node.statements.nil? bounds(node.location) on_stmts_add(on_stmts_new, on_void_stmt) else visit(node.statements) end bounds(node.location) on_while(predicate, statements) else statements = visit(node.statements.body.first) predicate = visit(node.predicate) bounds(node.location) on_while_mod(predicate, statements) end end
while foo; bar end ^^^^^^^^^^^^^^^^^^
bar while foo ^^^^^^^^^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3248 def visit_x_string_node(node) if node.unescaped.empty? bounds(node.location) on_xstring_literal(on_xstring_new) elsif node.opening.start_with?("<<~") heredoc = visit_heredoc_x_string_node(node.to_interpolated) bounds(node.location) on_xstring_literal(heredoc) else bounds(node.content_loc) content = on_tstring_content(node.content) bounds(node.location) on_xstring_literal(on_xstring_add(on_xstring_new, content)) end end
foo
^^^^^
Source
# File lib/prism/translation/ripper.rb, line 3271 def visit_yield_node(node) if node.arguments.nil? && node.lparen_loc.nil? bounds(node.location) on_yield0 else arguments = if node.arguments.nil? bounds(node.location) on_args_new else visit(node.arguments) end unless node.lparen_loc.nil? bounds(node.lparen_loc) arguments = on_paren(arguments) end bounds(node.location) on_yield(arguments) end end
yield ^^^^^
yield 1 ^^^^^^^
Private Instance Methods
Source
# File lib/prism/translation/ripper.rb, line 3401 def bounds(location) @lineno = location.start_line @column = location.start_column 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.
Source
# File lib/prism/translation/ripper.rb, line 1174 def command?(node) node.is_a?(CallNode) && node.opening_loc.nil? && (!node.arguments.nil? || node.block.is_a?(BlockArgumentNode)) && !BINARY_OPERATORS.include?(node.name) end
Returns true if the given node is a command node.
Source
# File lib/prism/translation/ripper.rb, line 3439 def compile_error(msg) end
This method is called when the parser found syntax error.
Source
# File lib/prism/translation/ripper.rb, line 3454 def dedent_string(string, width) whitespace = 0 cursor = 0 while cursor < string.length && string[cursor].match?(/\s/) && whitespace < width if string[cursor] == "\t" whitespace = ((whitespace / 8 + 1) * 8) break if whitespace > width else whitespace += 1 end cursor += 1 end string.replace(string[cursor..]) cursor end
This method is provided by the Ripper
C extension. It is called when a string needs to be dedented because of a tilde heredoc. It is expected that it will modify the string in place and return the number of bytes that were removed.
Source
# File lib/prism/translation/ripper.rb, line 3297 def result @result ||= Prism.parse(source, partial_script: true) end
Lazily initialize the parse result.
Source
# File lib/prism/translation/ripper.rb, line 3306 def trailing_comma?(left, right) source.byteslice(left.end_offset...right.start_offset).include?(",") end
Returns true if there is a comma between the two locations.
Source
# File lib/prism/translation/ripper.rb, line 571 def visit_alias_global_variable_node_value(node) bounds(node.location) case node when BackReferenceReadNode on_backref(node.slice) when GlobalVariableReadNode on_gvar(node.name.to_s) else raise end end
Visit one side of an alias global variable node.
Source
# File lib/prism/translation/ripper.rb, line 757 def visit_arguments(elements) bounds(elements.first.location) elements.inject(on_args_new) do |args, element| arg = visit(element) bounds(element.location) case element when BlockArgumentNode on_args_add_block(args, arg) when SplatNode on_args_add_star(args, arg) else on_args_add(args, arg) end end end
Visit a list of elements, like the elements of an array or arguments.
Source
# File lib/prism/translation/ripper.rb, line 841 def visit_begin_node_clauses(location, node, allow_newline) statements = if node.statements.nil? on_stmts_add(on_stmts_new, on_void_stmt) else body = node.statements.body body.unshift(nil) if void_stmt?(location, node.statements.body[0].location, allow_newline) bounds(node.statements.location) visit_statements_node_body(body) end rescue_clause = visit(node.rescue_clause) else_clause = unless (else_clause_node = node.else_clause).nil? else_statements = if else_clause_node.statements.nil? [nil] else body = else_clause_node.statements.body body.unshift(nil) if void_stmt?(else_clause_node.else_keyword_loc, else_clause_node.statements.body[0].location, allow_newline) body end bounds(else_clause_node.location) visit_statements_node_body(else_statements) end ensure_clause = visit(node.ensure_clause) bounds(node.location) on_bodystmt(statements, rescue_clause, else_clause, ensure_clause) end
Visit the clauses of a begin node to form an on_bodystmt call.
Source
# File lib/prism/translation/ripper.rb, line 876 def visit_body_node(location, node, allow_newline = false) case node when nil bounds(location) on_bodystmt(visit_statements_node_body([nil]), nil, nil, nil) when StatementsNode body = [*node.body] body.unshift(nil) if void_stmt?(location, body[0].location, allow_newline) stmts = visit_statements_node_body(body) bounds(node.body.first.location) on_bodystmt(stmts, nil, nil, nil) when BeginNode visit_begin_node_clauses(location, node, allow_newline) else raise end end
Visit the body of a structure that can have either a set of statements or statements wrapped in rescue/else/ensure.
Source
# File lib/prism/translation/ripper.rb, line 1147 def visit_call_node_arguments(arguments_node, block_node, trailing_comma) arguments = arguments_node&.arguments || [] block = block_node if block.is_a?(BlockArgumentNode) arguments << block block = nil end [ if arguments.length == 1 && arguments.first.is_a?(ForwardingArgumentsNode) visit(arguments.first) elsif arguments.any? args = visit_arguments(arguments) if block_node.is_a?(BlockArgumentNode) || arguments.last.is_a?(ForwardingArgumentsNode) || command?(arguments.last) || trailing_comma args else bounds(arguments.first.location) on_args_add_block(args, false) end end, visit(block) ] end
Visit the arguments and block of a call node and return the arguments and block as they should be used.
Source
# File lib/prism/translation/ripper.rb, line 1500 def visit_constant_path_write_node_target(node) if node.parent.nil? bounds(node.name_loc) child = on_const(node.name.to_s) bounds(node.location) on_top_const_field(child) else parent = visit(node.parent) bounds(node.name_loc) child = on_const(node.name.to_s) bounds(node.location) on_const_path_field(parent, child) end end
Visit a constant path that is part of a write node.
Source
# File lib/prism/translation/ripper.rb, line 2635 def visit_destructured_parameter_node(node) bounds(node.location) targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, false) bounds(node.lparen_loc) on_mlhs_paren(targets) end
Visit a destructured positional parameter node.
Source
# File lib/prism/translation/ripper.rb, line 3006 def visit_heredoc_node(parts, base) common_whitespace = visit_heredoc_node_whitespace(parts) if common_whitespace == 0 bounds(parts.first.location) string = [] result = base parts.each do |part| if part.is_a?(StringNode) if string.empty? string = [part] else string << part end else unless string.empty? bounds(string[0].location) result = yield result, on_tstring_content(string.map(&:content).join) string = [] end result = yield result, visit(part) end end unless string.empty? bounds(string[0].location) result = yield result, on_tstring_content(string.map(&:content).join) end result else bounds(parts.first.location) result = parts.inject(base) do |string_content, part| yield string_content, visit_string_content(part) end bounds(parts.first.location) on_heredoc_dedent(result, common_whitespace) end end
Visit a string that is expressed using a <<~ heredoc.
Source
# File lib/prism/translation/ripper.rb, line 2981 def visit_heredoc_node_whitespace(parts) common_whitespace = nil dedent_next = true parts.each do |part| if part.is_a?(StringNode) if dedent_next && !(content = part.content).chomp.empty? common_whitespace = [ common_whitespace || Float::INFINITY, content[/\A\s*/].each_char.inject(0) do |part_whitespace, char| char == "\t" ? ((part_whitespace / 8 + 1) * 8) : (part_whitespace + 1) end ].min end dedent_next = true else dedent_next = false end end common_whitespace || 0 end
Ripper
gives back the escaped string content but strips out the common leading whitespace. Prism
gives back the unescaped string content and a location for the escaped string content. Unfortunately these don’t work well together, so here we need to re-derive the common leading whitespace.
Source
# File lib/prism/translation/ripper.rb, line 3052 def visit_heredoc_string_node(node) bounds(node.opening_loc) on_heredoc_beg(node.opening) bounds(node.location) result = visit_heredoc_node(node.parts, on_string_content) do |parts, part| on_string_add(parts, part) end bounds(node.closing_loc) on_heredoc_end(node.closing) result end
Visit a heredoc node that is representing a string.
Source
# File lib/prism/translation/ripper.rb, line 3069 def visit_heredoc_x_string_node(node) bounds(node.opening_loc) on_heredoc_beg(node.opening) bounds(node.location) result = visit_heredoc_node(node.parts, on_xstring_new) do |parts, part| on_xstring_add(parts, part) end bounds(node.closing_loc) on_heredoc_end(node.closing) result end
Visit a heredoc node that is representing an xstring.
Source
# File lib/prism/translation/ripper.rb, line 2488 def visit_multi_target_node_targets(lefts, rest, rights, skippable) if skippable && lefts.length == 1 && lefts.first.is_a?(MultiTargetNode) && rest.nil? && rights.empty? return visit(lefts.first) end mlhs = on_mlhs_new lefts.each do |left| bounds(left.location) mlhs = on_mlhs_add(mlhs, visit(left)) end case rest when nil # do nothing when ImplicitRestNode # these do not get put into the generated tree bounds(rest.location) on_excessed_comma else bounds(rest.location) mlhs = on_mlhs_add_star(mlhs, visit(rest)) end if rights.any? bounds(rights.first.location) post = on_mlhs_new rights.each do |right| bounds(right.location) post = on_mlhs_add(post, visit(right)) end mlhs = on_mlhs_add_post(mlhs, post) end mlhs end
Visit the targets of a multi-target node.
Source
# File lib/prism/translation/ripper.rb, line 3345 def visit_number_node(node) slice = node.slice location = node.location if slice[0] == "-" bounds(location.copy(start_offset: location.start_offset + 1)) value = yield slice[1..-1] bounds(node.location) on_unary(:-@, value) else bounds(location) yield slice end end
Visit a node that represents a number. We need to explicitly handle the unary - operator.
Source
# File lib/prism/translation/ripper.rb, line 596 def visit_pattern_node(node) if node.is_a?(ParenthesesNode) visit(node.body) else visit(node) end end
Visit a pattern within a pattern match. This is used to bypass the parenthesis node that can be used to wrap patterns.
Source
# File lib/prism/translation/ripper.rb, line 2947 def visit_statements_node_body(body) body.inject(on_stmts_new) do |stmts, stmt| on_stmts_add(stmts, stmt.nil? ? on_void_stmt : visit(stmt)) end end
Visit the list of statements of a statements node. We support nil statements in the list. This would normally not be allowed by the structure of the prism parse tree, but we manually add them here so that we can mirror Ripper’s void stmt.
Source
# File lib/prism/translation/ripper.rb, line 2237 def visit_string_content(part) if part.is_a?(StringNode) bounds(part.content_loc) on_tstring_content(part.content) else visit(part) end end
Visit an individual part of a string-like node.
Source
# File lib/prism/translation/ripper.rb, line 3318 def visit_token(token, allow_keywords = true) case token when "." on_period(token) when "`" on_backtick(token) when *(allow_keywords ? KEYWORDS : []) on_kw(token) when /^_/ on_ident(token) when /^[[:upper:]]\w*$/ on_const(token) when /^@@/ on_cvar(token) when /^@/ on_ivar(token) when /^\$/ on_gvar(token) when /^[[:punct:]]/ on_op(token) else on_ident(token) end end
Visit the string content of a particular node. This method is used to split into the various token types.
Source
# File lib/prism/translation/ripper.rb, line 746 def visit_words_sep(opening_loc, previous, current) end_offset = (previous.nil? ? opening_loc : previous.location).end_offset start_offset = current.location.start_offset if end_offset != start_offset bounds(current.location.copy(start_offset: end_offset)) on_words_sep(source.byteslice(end_offset...start_offset)) end end
Dispatch a words_sep event that contains the space between the elements of list literals.
Source
# File lib/prism/translation/ripper.rb, line 3363 def visit_write_value(node) if node.is_a?(ArrayNode) && node.opening_loc.nil? elements = node.elements length = elements.length bounds(elements.first.location) elements.each_with_index.inject((elements.first.is_a?(SplatNode) && length == 1) ? on_mrhs_new : on_args_new) do |args, (element, index)| arg = visit(element) bounds(element.location) if index == length - 1 if element.is_a?(SplatNode) mrhs = index == 0 ? args : on_mrhs_new_from_args(args) on_mrhs_add_star(mrhs, arg) else on_mrhs_add(on_mrhs_new_from_args(args), arg) end else case element when BlockArgumentNode on_args_add_block(args, arg) when SplatNode on_args_add_star(args, arg) else on_args_add(args, arg) end end end else visit(node) end end
Visit a node that represents a write value. This is used to handle the special case of an implicit array that is generated without brackets.
Source
# File lib/prism/translation/ripper.rb, line 3311 def void_stmt?(left, right, allow_newline) pattern = allow_newline ? /[;\n]/ : /;/ source.byteslice(left.end_offset...right.start_offset).match?(pattern) end
Returns true if there is a semicolon between the two locations.
Source
# File lib/prism/translation/ripper.rb, line 3430 def warn(fmt, *args) end
This method is called when weak warning is produced by the parser. fmt
and args
is printf style.
Source
# File lib/prism/translation/ripper.rb, line 3435 def warning(fmt, *args) end
This method is called when strong warning is produced by the parser. fmt
and args
is printf style.