Class: Prism::Translation::Ripper
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Subclasses:
|
|
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Compiler
|
|
Instance Chain:
self,
Compiler
|
|
Inherits: |
Compiler
|
Defined in: | lib/prism/translation/ripper.rb, lib/prism/translation/ripper/sexp.rb |
Overview
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 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
Constant Summary
-
BINARY_OPERATORS =
private
A list of all of the Ruby binary operators.
[ :!=, :!~, :=~, :==, :===, :<=>, :>, :>=, :<, :<=, :&, :|, :^, :>>, :<<, :-, :+, :%, :/, :*, :** ]
-
EVENTS =
This array contains name of all ripper events.
PARSER_EVENTS + SCANNER_EVENTS
-
KEYWORDS =
private
A list of all of the Ruby keywords.
[ "alias", "and", "begin", "BEGIN", "break", "case", "class", "def", "defined?", "do", "else", "elsif", "end", "END", "ensure", "false", "for", "if", "in", "module", "next", "nil", "not", "or", "redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef", "unless", "until", "when", "while", "yield", "__ENCODING__", "__FILE__", "__LINE__" ]
-
PARSER_EVENTS =
This array contains name of parser events.
PARSER_EVENT_TABLE.keys
-
PARSER_EVENT_TABLE =
This contains a table of all of the parser events and their corresponding arity.
{ BEGIN: 1, END: 1, alias: 2, alias_error: 2, aref: 2, aref_field: 2, arg_ambiguous: 1, arg_paren: 1, args_add: 2, args_add_block: 2, args_add_star: 2, args_forward: 0, args_new: 0, array: 1, aryptn: 4, assign: 2, assign_error: 2, assoc_new: 2, assoc_splat: 1, assoclist_from_args: 1, bare_assoc_hash: 1, begin: 1, binary: 3, block_var: 2, blockarg: 1, bodystmt: 4, brace_block: 2, break: 1, call: 3, case: 2, class: 3, class_name_error: 2, command: 2, command_call: 4, const_path_field: 2, const_path_ref: 2, const_ref: 1, def: 3, defined: 1, defs: 5, do_block: 2, dot2: 2, dot3: 2, dyna_symbol: 1, else: 1, elsif: 3, ensure: 1, excessed_comma: 0, fcall: 1, field: 3, fndptn: 4, for: 3, hash: 1, heredoc_dedent: 2, hshptn: 3, if: 3, if_mod: 2, ifop: 3, in: 3, kwrest_param: 1, lambda: 2, magic_comment: 2, massign: 2, method_add_arg: 2, method_add_block: 2, mlhs_add: 2, mlhs_add_post: 2, mlhs_add_star: 2, mlhs_new: 0, mlhs_paren: 1, module: 2, mrhs_add: 2, mrhs_add_star: 2, mrhs_new: 0, mrhs_new_from_args: 1, next: 1, nokw_param: 1, opassign: 3, operator_ambiguous: 2, param_error: 2, params: 7, paren: 1, parse_error: 1, program: 1, qsymbols_add: 2, qsymbols_new: 0, qwords_add: 2, qwords_new: 0, redo: 0, regexp_add: 2, regexp_literal: 2, regexp_new: 0, rescue: 4, rescue_mod: 2, rest_param: 1, retry: 0, return: 1, return0: 0, sclass: 2, stmts_add: 2, stmts_new: 0, string_add: 2, string_concat: 2, string_content: 0, string_dvar: 1, string_embexpr: 1, string_literal: 1, super: 1, symbol: 1, symbol_literal: 1, symbols_add: 2, symbols_new: 0, top_const_field: 1, top_const_ref: 1, unary: 2, undef: 1, unless: 3, unless_mod: 2, until: 2, until_mod: 2, var_alias: 2, var_field: 1, var_ref: 1, vcall: 1, void_stmt: 0, when: 3, while: 2, while_mod: 2, word_add: 2, word_new: 0, words_add: 2, words_new: 0, xstring_add: 2, xstring_literal: 1, xstring_new: 0, yield: 1, yield0: 0, zsuper: 0 }
-
SCANNER_EVENTS =
This array contains name of scanner events.
SCANNER_EVENT_TABLE.keys
-
SCANNER_EVENT_TABLE =
This contains a table of all of the scanner events and their corresponding arity.
{ CHAR: 1, __end__: 1, backref: 1, backtick: 1, comma: 1, comment: 1, const: 1, cvar: 1, embdoc: 1, embdoc_beg: 1, embdoc_end: 1, embexpr_beg: 1, embexpr_end: 1, embvar: 1, float: 1, gvar: 1, heredoc_beg: 1, heredoc_end: 1, ident: 1, ignored_nl: 1, imaginary: 1, int: 1, ivar: 1, kw: 1, label: 1, label_end: 1, lbrace: 1, lbracket: 1, lparen: 1, nl: 1, op: 1, period: 1, qsymbols_beg: 1, qwords_beg: 1, rational: 1, rbrace: 1, rbracket: 1, regexp_beg: 1, regexp_end: 1, rparen: 1, semicolon: 1, sp: 1, symbeg: 1, symbols_beg: 1, tlambda: 1, tlambeg: 1, tstring_beg: 1, tstring_content: 1, tstring_end: 1, words_beg: 1, words_sep: 1, ignored_sp: 1 }
Class Method Summary
-
.lex(src, filename = "-", lineno = 1, raise_errors: false)
Tokenizes the Ruby program and returns an array of an array, which is formatted like
[[lineno, column], type, token, state]
. -
.new(source, filename = "(ripper)", lineno = 1) ⇒ Ripper
constructor
Create a new
Ripper
object with the given source. -
.parse(src, filename = "(ripper)", lineno = 1)
Parses the given Ruby program read from
src
. -
.sexp(src, filename = "-", lineno = 1, raise_errors: false)
Parses
src
and create S-exp tree. -
.sexp_raw(src, filename = "-", lineno = 1, raise_errors: false)
Parses
src
and create S-exp tree.
Instance Attribute Summary
-
#column
readonly
The current column number of the parser.
-
#error? ⇒ Boolean
readonly
True if the parser encountered an error during parsing.
-
#filename
readonly
The filename of the source being parsed.
-
#lineno
readonly
The current line number of the parser.
-
#source
readonly
The source that is being parsed.
Instance Method Summary
-
#parse
Parse the source and return the result.
-
#visit_alias_global_variable_node(node)
alias $foo $bar ^^^^^^^^^^^^^^^.
-
#visit_alias_method_node(node)
alias foo bar ^^^^^^^^^^^^^.
-
#visit_alternation_pattern_node(node)
foo => bar | baz.
-
#visit_and_node(node)
a and b ^^^^^^^.
-
#visit_arguments_node(node)
foo(bar).
-
#visit_array_node(node)
^^.
-
#visit_array_pattern_node(node)
foo => [bar].
-
#visit_assoc_node(node)
{ a: 1 }
-
#visit_assoc_splat_node(node)
def foo(**); bar(**); end.
-
#visit_back_reference_read_node(node)
$+ ^^.
-
#visit_begin_node(node)
begin end ^^^^^^^^^.
-
#visit_block_argument_node(node)
foo(&bar).
-
#visit_block_local_variable_node(node)
foo { |; bar| }
-
#visit_block_node(node)
Visit a BlockNode.
-
#visit_block_parameter_node(node)
def foo(&bar); end.
-
#visit_block_parameters_node(node)
A block’s parameters.
-
#visit_break_node(node)
break ^^^^^.
-
#visit_call_and_write_node(node)
foo.bar &&= baz ^^^^^^^^^^^^^^^.
-
#visit_call_node(node)
foo ^^^.
-
#visit_call_operator_write_node(node)
foo.bar += baz ^^^^^^^^^^^^^^^.
-
#visit_call_or_write_node(node)
foo.bar ||= baz ^^^^^^^^^^^^^^^.
-
#visit_call_target_node(node)
foo.bar, = 1 ^^^^^^^.
-
#visit_capture_pattern_node(node)
foo => bar => baz.
-
#visit_case_match_node(node)
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^.
-
#visit_case_node(node)
case foo; when bar; end ^^^^^^^^^^^^^^^^^^^^^^^.
-
#visit_class_node(node)
class Foo; end ^^^^^^^^^^^^^^.
-
#visit_class_variable_and_write_node(node)
@@foo &&= bar ^^^^^^^^^^^^^.
-
#visit_class_variable_operator_write_node(node)
@@foo += bar ^^^^^^^^^^^^.
-
#visit_class_variable_or_write_node(node)
@@foo ||= bar ^^^^^^^^^^^^^.
-
#visit_class_variable_read_node(node)
@@foo ^^^^^.
-
#visit_class_variable_target_node(node)
@@foo, = bar ^^^^^.
-
#visit_class_variable_write_node(node)
@@foo = 1 ^^^^^^^^^.
-
#visit_constant_and_write_node(node)
Foo &&= bar ^^^^^^^^^^^^.
-
#visit_constant_operator_write_node(node)
Foo += bar ^^^^^^^^^^^.
-
#visit_constant_or_write_node(node)
Foo ||= bar ^^^^^^^^^^^^.
-
#visit_constant_path_and_write_node(node)
Foo::Bar
&&= baz ^^^^^^^^^^^^^^^^. -
#visit_constant_path_node(node)
Foo::Bar
^^^^^^^^. -
#visit_constant_path_operator_write_node(node)
Foo::Bar
+= baz ^^^^^^^^^^^^^^^. -
#visit_constant_path_or_write_node(node)
Foo::Bar
||= baz ^^^^^^^^^^^^^^^^. -
#visit_constant_path_target_node(node)
Foo::Bar
, = baz ^^^^^^^^. -
#visit_constant_path_write_node(node)
Foo::Bar
= 1 ^^^^^^^^^^^^. -
#visit_constant_read_node(node)
Foo ^^^.
-
#visit_constant_target_node(node)
Foo, = bar ^^^.
-
#visit_constant_write_node(node)
Foo = 1 ^^^^^^^.
-
#visit_def_node(node)
def foo; end ^^^^^^^^^^^^.
-
#visit_defined_node(node)
defined? a ^^^^^^^^^^.
-
#visit_else_node(node)
if foo then bar else baz end.
-
#visit_embedded_statements_node(node)
“foo #
bar
”. -
#visit_embedded_variable_node(node)
“foo #@bar”.
-
#visit_ensure_node(node)
Visit an EnsureNode node.
-
#visit_false_node(node)
false ^^^^^.
-
#visit_find_pattern_node(node)
foo => [*, bar, *].
-
#visit_flip_flop_node(node)
if foo ..
-
#visit_float_node(node)
1.0 ^^^.
-
#visit_for_node(node)
for foo in bar do end ^^^^^^^^^^^^^^^^^^^^^.
-
#visit_forwarding_arguments_node(node)
def foo(…); bar(…); end.
-
#visit_forwarding_parameter_node(node)
def foo(…); end.
-
#visit_forwarding_super_node(node)
super ^^^^^.
-
#visit_global_variable_and_write_node(node)
$foo &&= bar ^^^^^^^^^^^^.
-
#visit_global_variable_operator_write_node(node)
$foo += bar ^^^^^^^^^^^.
-
#visit_global_variable_or_write_node(node)
$foo ||= bar ^^^^^^^^^^^^.
-
#visit_global_variable_read_node(node)
$foo ^^^^.
-
#visit_global_variable_target_node(node)
$foo, = bar ^^^^.
-
#visit_global_variable_write_node(node)
$foo = 1 ^^^^^^^^.
-
#visit_hash_node(node)
{} ^^.
-
#visit_hash_pattern_node(node)
foo => {}
-
#visit_if_node(node)
if foo then bar end ^^^^^^^^^^^^^^^^^^^.
-
#visit_imaginary_node(node)
1i ^^.
-
#visit_implicit_node(node)
{ foo: }
-
#visit_implicit_rest_node(node)
foo { |bar,| }
-
#visit_in_node(node)
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^.
-
#visit_index_and_write_node(node)
foo &&= baz ^^^^^^^^^^^^^^^^.
-
#visit_index_operator_write_node(node)
foo += baz ^^^^^^^^^^^^^^^.
-
#visit_index_or_write_node(node)
foo ||= baz ^^^^^^^^^^^^^^^^.
-
#visit_index_target_node(node)
foo, = 1 ^^^^^^^^.
-
#visit_instance_variable_and_write_node(node)
^^^^^^^^^^^^.
-
#visit_instance_variable_operator_write_node(node)
^^^^^^^^^^^.
-
#visit_instance_variable_or_write_node(node)
^^^^^^^^^^^^.
-
#visit_instance_variable_read_node(node)
^^^^.
-
#visit_instance_variable_target_node(node)
@foo, = bar ^^^^.
-
#visit_instance_variable_write_node(node)
^^^^^^^^.
-
#visit_integer_node(node)
1 ^.
-
#visit_interpolated_match_last_line_node(node)
if /foo #
bar
/ then end. -
#visit_interpolated_regular_expression_node(node)
/foo #
bar
/ ^^^^^^^^^^^^. -
#visit_interpolated_string_node(node)
“foo #
bar
” ^^^^^^^^^^^^. -
#visit_interpolated_symbol_node(node)
:“foo #
bar
” ^^^^^^^^^^^^^. -
#visit_interpolated_x_string_node(node)
foo #{bar}
^^^^^^^^^^^^. -
#visit_it_local_variable_read_node(node)
-> { it }
-
#visit_it_parameters_node(node)
-> { it } ^^^^^^^^^.
-
#visit_keyword_hash_node(node)
foo(bar: baz).
-
#visit_keyword_rest_parameter_node(node)
def foo(**bar); end.
-
#visit_lambda_node(node)
-> {}
-
#visit_local_variable_and_write_node(node)
foo &&= bar ^^^^^^^^^^^.
-
#visit_local_variable_operator_write_node(node)
foo += bar ^^^^^^^^^^.
-
#visit_local_variable_or_write_node(node)
foo ||= bar ^^^^^^^^^^^.
-
#visit_local_variable_read_node(node)
foo ^^^.
-
#visit_local_variable_target_node(node)
foo, = bar ^^^.
-
#visit_local_variable_write_node(node)
foo = 1 ^^^^^^^.
-
#visit_match_last_line_node(node)
if /foo/ then end.
-
#visit_match_predicate_node(node)
foo in bar ^^^^^^^^^^.
-
#visit_match_required_node(node)
foo => bar ^^^^^^^^^^.
-
#visit_match_write_node(node)
/(?<foo>foo)/ =~ bar ^^^^^^^^^^^^^^^^^^^^.
-
#visit_missing_node(node)
A node that is missing from the syntax tree.
-
#visit_module_node(node)
module Foo; end ^^^^^^^^^^^^^^^.
-
#visit_multi_target_node(node)
(foo, bar), bar = qux ^^^^^^^^^^.
-
#visit_multi_write_node(node)
foo, bar = baz ^^^^^^^^^^^^^^.
-
#visit_next_node(node)
next ^^^^.
-
#visit_nil_node(node)
nil ^^^.
-
#visit_no_keywords_parameter_node(node)
def foo(**nil); end.
-
#visit_numbered_parameters_node(node)
-> { _1 + _2 } ^^^^^^^^^^^^^^.
-
#visit_numbered_reference_read_node(node)
$1 ^^.
-
#visit_optional_keyword_parameter_node(node)
def foo(bar: baz); end.
-
#visit_optional_parameter_node(node)
def foo(bar = 1); end.
-
#visit_or_node(node)
a or b ^^^^^^.
-
#visit_parameters_node(node)
def foo(bar, *baz); end.
-
#visit_parentheses_node(node)
() ^^.
-
#visit_pinned_expression_node(node)
foo => ^(bar).
-
#visit_pinned_variable_node(node)
foo = 1 and bar => ^foo.
-
#visit_post_execution_node(node)
END {} ^^^^^^.
-
#visit_pre_execution_node(node)
BEGIN {} ^^^^^^^^.
-
#visit_program_node(node)
The top-level program node.
-
#visit_range_node(node)
0..5 ^^^^.
-
#visit_rational_node(node)
1r ^^.
-
#visit_redo_node(node)
redo ^^^^.
-
#visit_regular_expression_node(node)
/foo/ ^^^^^.
-
#visit_required_keyword_parameter_node(node)
def foo(bar:); end.
-
#visit_required_parameter_node(node)
def foo(bar); end.
-
#visit_rescue_modifier_node(node)
foo rescue bar ^^^^^^^^^^^^^^.
-
#visit_rescue_node(node)
begin; rescue; end.
-
#visit_rest_parameter_node(node)
def foo(*bar); end.
-
#visit_retry_node(node)
retry ^^^^^.
-
#visit_return_node(node)
return ^^^^^^.
-
#visit_self_node(node)
self ^^^^.
-
#visit_shareable_constant_node(node)
A shareable constant.
-
#visit_singleton_class_node(node)
class << self; end ^^^^^^^^^^^^^^^^^^.
-
#visit_source_encoding_node(node)
__ENCODING__ ^^^^^^^^^^^^.
-
#visit_source_file_node(node)
__FILE__ ^^^^^^^^.
-
#visit_source_line_node(node)
__LINE__ ^^^^^^^^.
-
#visit_splat_node(node)
foo(*bar).
-
#visit_statements_node(node)
A list of statements.
-
#visit_string_node(node)
“foo” ^^^^^.
-
#visit_super_node(node)
super(foo) ^^^^^^^^^^.
-
#visit_symbol_node(node)
:foo
^^^^. -
#visit_true_node(node)
true ^^^^.
-
#visit_undef_node(node)
undef foo ^^^^^^^^^.
-
#visit_unless_node(node)
unless foo; bar end ^^^^^^^^^^^^^^^^^^^.
-
#visit_until_node(node)
until foo; bar end ^^^^^^^^^^^^^^^^^.
-
#visit_when_node(node)
case foo; when bar; end.
-
#visit_while_node(node)
while foo; bar end ^^^^^^^^^^^^^^^^^^.
-
#visit_x_string_node(node)
foo
^^^^^. -
#visit_yield_node(node)
yield ^^^^^.
-
#bounds(location)
private
This method is responsible for updating lineno and column information to reflect the current node.
-
#command?(node) ⇒ Boolean
private
Returns true if the given node is a command node.
-
#compile_error(msg)
private
This method is called when the parser found syntax error.
-
#dedent_string(string, width)
private
This method is provided by the
Ripper
C extension. -
#result
private
Lazily initialize the parse result.
-
#trailing_comma?(left, right) ⇒ Boolean
private
Returns true if there is a comma between the two locations.
-
#visit_alias_global_variable_node_value(node)
private
Visit one side of an alias global variable node.
-
#visit_arguments(elements)
private
Visit a list of elements, like the elements of an array or arguments.
-
#visit_begin_node_clauses(location, node, allow_newline)
private
Visit the clauses of a begin node to form an on_bodystmt call.
-
#visit_body_node(location, node, allow_newline = false)
private
Visit the body of a structure that can have either a set of statements or statements wrapped in rescue/else/ensure.
-
#visit_call_node_arguments(arguments_node, block_node, trailing_comma)
private
Visit the arguments and block of a call node and return the arguments and block as they should be used.
-
#visit_constant_path_write_node_target(node)
private
Visit a constant path that is part of a write node.
-
#visit_destructured_parameter_node(node)
private
Visit a destructured positional parameter node.
-
#visit_heredoc_node(parts, base)
private
Visit a string that is expressed using a <<~ heredoc.
-
#visit_heredoc_node_whitespace(parts)
private
Ripper
gives back the escaped string content but strips out the common leading whitespace. -
#visit_heredoc_string_node(node)
private
Visit a heredoc node that is representing a string.
-
#visit_heredoc_x_string_node(node)
private
Visit a heredoc node that is representing an xstring.
-
#visit_multi_target_node_targets(lefts, rest, rights, skippable)
private
Visit the targets of a multi-target node.
-
#visit_number_node(node)
private
Visit a node that represents a number.
-
#visit_pattern_node(node)
private
Visit a pattern within a pattern match.
-
#visit_statements_node_body(body)
private
Visit the list of statements of a statements node.
-
#visit_string_content(part)
private
Visit an individual part of a string-like node.
-
#visit_token(token, allow_keywords = true)
private
Visit the string content of a particular node.
-
#visit_words_sep(opening_loc, previous, current)
private
Dispatch a words_sep event that contains the space between the elements of list literals.
-
#visit_write_value(node)
private
Visit a node that represents a write value.
-
#void_stmt?(left, right, allow_newline) ⇒ Boolean
private
Returns true if there is a semicolon between the two locations.
-
#warn(fmt, *args)
private
This method is called when weak warning is produced by the parser.
-
#warning(fmt, *args)
private
This method is called when strong warning is produced by the parser.
- #_dispatch_0 private Internal use only
- #_dispatch_1(_) private Internal use only
- #_dispatch_2(_, _) private Internal use only
- #_dispatch_3(_, _, _) private Internal use only
- #_dispatch_4(_, _, _, _) private Internal use only
- #_dispatch_5(_, _, _, _, _) private Internal use only
- #_dispatch_7(_, _, _, _, _, _, _) private Internal use only
Constructor Details
.new(source, filename = "(ripper)", lineno = 1) ⇒ Ripper
Create a new Ripper
object with the given source.
Class Method Details
.lex(src, filename = "-", lineno = 1, raise_errors: false)
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 ]]
.parse(src, filename = "(ripper)", lineno = 1)
Parses the given Ruby program read from src
. src
must be a String or an IO or a object with a #gets
method.
.sexp(src, filename = "-", lineno = 1, raise_errors: false)
Parses src
and create S-exp tree. Returns more readable tree rather than .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]]]]
.sexp_raw(src, filename = "-", lineno = 1, raise_errors: false)
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]]]]
Instance Attribute Details
#column (readonly)
The current column number of the parser.
# File 'lib/prism/translation/ripper.rb', line 442
attr_reader :column
#error? ⇒ Boolean
(readonly)
True if the parser encountered an error during parsing.
# File 'lib/prism/translation/ripper.rb', line 458
def error? result.failure? end
#filename (readonly)
The filename of the source being parsed.
# File 'lib/prism/translation/ripper.rb', line 436
attr_reader :filename
#lineno (readonly)
The current line number of the parser.
# File 'lib/prism/translation/ripper.rb', line 439
attr_reader :lineno
#source (readonly)
The source that is being parsed.
# File 'lib/prism/translation/ripper.rb', line 433
attr_reader :source
Instance Method Details
#_dispatch_0 (private)
# File 'lib/prism/translation/ripper.rb', line 3411
def _dispatch_0; end
#_dispatch_1(_) (private)
# File 'lib/prism/translation/ripper.rb', line 3412
def _dispatch_1(_); end
#_dispatch_2(_, _) (private)
# File 'lib/prism/translation/ripper.rb', line 3413
def _dispatch_2(_, _); end
#_dispatch_3(_, _, _) (private)
# File 'lib/prism/translation/ripper.rb', line 3414
def _dispatch_3(_, _, _); end
#_dispatch_4(_, _, _, _) (private)
# File 'lib/prism/translation/ripper.rb', line 3415
def _dispatch_4(_, _, _, _); end
#_dispatch_5(_, _, _, _, _) (private)
# File 'lib/prism/translation/ripper.rb', line 3416
def _dispatch_5(_, _, _, _, _); end
#_dispatch_7(_, _, _, _, _, _, _) (private)
# File 'lib/prism/translation/ripper.rb', line 3417
def _dispatch_7(_, _, _, _, _, _, _); end
#bounds(location) (private)
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/translation/ripper.rb', line 3401
def bounds(location) @lineno = location.start_line @column = location.start_column end
#command?(node) ⇒ Boolean
(private)
Returns true if the given node is a command node.
# File 'lib/prism/translation/ripper.rb', line 1174
private 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
#compile_error(msg) (private)
This method is called when the parser found syntax error.
# File 'lib/prism/translation/ripper.rb', line 3439
def compile_error(msg) end
#dedent_string(string, width) (private)
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.
# 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
#parse
Parse the source and return the result.
# 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. ) 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. ) 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. ) end end nil else result.value.accept(self) end end
#result (private)
Lazily initialize the parse result.
#trailing_comma?(left, right) ⇒ Boolean
(private)
Returns true if there is a comma between the two locations.
# File 'lib/prism/translation/ripper.rb', line 3306
def trailing_comma?(left, right) source.byteslice(left.end_offset...right.start_offset).include?(",") end
#visit_alias_global_variable_node(node)
alias $foo $bar ^^^^^^^^^^^^^^^
# 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
#visit_alias_global_variable_node_value(node) (private)
Visit one side of an alias global variable node.
# File 'lib/prism/translation/ripper.rb', line 571
private 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_alias_method_node(node)
alias foo bar ^^^^^^^^^^^^^
# 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
#visit_alternation_pattern_node(node)
foo => bar | baz
^^^^^^^^^
# 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
#visit_and_node(node)
a and b ^^^^^^^
# 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
#visit_arguments(elements) (private)
Visit a list of elements, like the elements of an array or arguments.
# File 'lib/prism/translation/ripper.rb', line 757
private 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_arguments_node(node)
foo(bar)
^^^
# File 'lib/prism/translation/ripper.rb', line 797
def visit_arguments_node(node) arguments, _ = visit_call_node_arguments(node, nil, false) arguments end
#visit_array_node(node)
-
^^
# 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
#visit_array_pattern_node(node)
foo => [bar]
^^^^^
# 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
#visit_assoc_node(node)
{ a: 1 }
^^^^
# 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
#visit_assoc_splat_node(node)
def foo(**); bar(**); end
^^
{ **foo }
^^^^^
# 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
#visit_back_reference_read_node(node)
$+ ^^
# File 'lib/prism/translation/ripper.rb', line 826
def visit_back_reference_read_node(node) bounds(node.location) on_backref(node.slice) end
#visit_begin_node(node)
begin end ^^^^^^^^^
# 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
#visit_begin_node_clauses(location, node, allow_newline) (private)
Visit the clauses of a begin node to form an on_bodystmt call.
# File 'lib/prism/translation/ripper.rb', line 841
private 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_block_argument_node(node)
foo(&bar)
^^^^
# File 'lib/prism/translation/ripper.rb', line 897
def visit_block_argument_node(node) visit(node.expression) end
#visit_block_local_variable_node(node)
foo { |; bar| }
^^^
# 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
#visit_block_node(node)
Visit a BlockNode.
# 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_block_parameter_node(node)
def foo(&bar); end
^^^^
# 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
#visit_block_parameters_node(node)
A block’s parameters.
# 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
#visit_body_node(location, node, allow_newline = false) (private)
Visit the body of a structure that can have either a set of statements or statements wrapped in rescue/else/ensure.
# File 'lib/prism/translation/ripper.rb', line 876
private 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_break_node(node)
break ^^^^^
break foo ^^^^^^^^^
#visit_call_and_write_node(node)
foo.bar &&= baz ^^^^^^^^^^^^^^^
# 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. ) = visit_token(node. ) bounds(node.location) target = on_field(receiver, call_operator, ) bounds(node.operator_loc) operator = on_op("&&=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
#visit_call_node(node)
foo ^^^
foo.bar ^^^^^^^
foo.bar() {} ^^^^^^^^^^^^
# 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. == "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. ) = visit_token(node., false) if node.variable_call? on_vcall( ) 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(, arguments) elsif !node.opening_loc.nil? bounds(node.location) on_method_add_arg(on_fcall( ), on_arg_paren(arguments)) else bounds(node.location) on_method_add_arg(on_fcall( ), 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) = if node. .nil? :call else bounds(node. ) visit_token(node., false) end if node.name.end_with?("=") && !node. .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, ), 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, ) else on_command_call(receiver, call_operator, , arguments) end else bounds(node.opening_loc) arguments = on_arg_paren(arguments) bounds(node.location) on_method_add_arg(on_call(receiver, call_operator, ), arguments) end if block.nil? call else bounds(node.block.location) on_method_add_block(call, block) end end end end
#visit_call_node_arguments(arguments_node, block_node, trailing_comma) (private)
Visit the arguments and block of a call node and return the arguments and block as they should be used.
# File 'lib/prism/translation/ripper.rb', line 1147
private 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_call_operator_write_node(node)
foo.bar += baz ^^^^^^^^^^^^^^^
# 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. ) = visit_token(node. ) bounds(node.location) target = on_field(receiver, call_operator, ) 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
#visit_call_or_write_node(node)
foo.bar ||= baz ^^^^^^^^^^^^^^^
# 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. ) = visit_token(node. ) bounds(node.location) target = on_field(receiver, call_operator, ) bounds(node.operator_loc) operator = on_op("||=") value = visit_write_value(node.value) bounds(node.location) on_opassign(target, operator, value) end
#visit_call_target_node(node)
foo.bar, = 1 ^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 1249
def visit_call_target_node(node) if node.call_operator == "::" receiver = visit(node.receiver) bounds(node. ) = visit_token(node. ) bounds(node.location) on_const_path_field(receiver, ) else receiver = visit(node.receiver) bounds(node.call_operator_loc) call_operator = visit_token(node.call_operator) bounds(node. ) = visit_token(node. ) bounds(node.location) on_field(receiver, call_operator, ) end end
#visit_capture_pattern_node(node)
foo => bar => baz
^^^^^^^^^^
# 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
#visit_case_match_node(node)
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^
# 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
#visit_case_node(node)
case foo; when bar; end ^^^^^^^^^^^^^^^^^^^^^^^
# 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
#visit_class_node(node)
class Foo; end ^^^^^^^^^^^^^^
# 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
#visit_class_variable_and_write_node(node)
@@foo &&= bar ^^^^^^^^^^^^^
# 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
#visit_class_variable_operator_write_node(node)
@@foo += bar ^^^^^^^^^^^^
# 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
#visit_class_variable_or_write_node(node)
@@foo ||= bar ^^^^^^^^^^^^^
# 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
#visit_class_variable_read_node(node)
@@foo ^^^^^
# 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
#visit_class_variable_target_node(node)
@@foo, = bar ^^^^^
# 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
#visit_class_variable_write_node(node)
@@foo = 1 ^^^^^^^^^
@@foo, @@bar = 1 ^^^^^ ^^^^^
# 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
#visit_constant_and_write_node(node)
Foo &&= bar ^^^^^^^^^^^^
# 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
#visit_constant_operator_write_node(node)
Foo += bar ^^^^^^^^^^^
# 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
#visit_constant_or_write_node(node)
Foo ||= bar ^^^^^^^^^^^^
# 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
#visit_constant_path_and_write_node(node)
Foo::Bar
&&= baz ^^^^^^^^^^^^^^^^
# 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
#visit_constant_path_node(node)
Foo::Bar
^^^^^^^^
# 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
#visit_constant_path_operator_write_node(node)
Foo::Bar
+= baz ^^^^^^^^^^^^^^^
# 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
#visit_constant_path_or_write_node(node)
Foo::Bar
||= baz ^^^^^^^^^^^^^^^^
# 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
#visit_constant_path_target_node(node)
Foo::Bar
, = baz ^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 1562
def visit_constant_path_target_node(node) visit_constant_path_write_node_target(node) end
#visit_constant_path_write_node(node)
Foo::Bar
= 1 ^^^^^^^^^^^^
Foo::Foo
, Bar::Bar
= 1 ^^^^^^^^ ^^^^^^^^
# 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
#visit_constant_path_write_node_target(node) (private)
Visit a constant path that is part of a write node.
# File 'lib/prism/translation/ripper.rb', line 1500
private 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_constant_read_node(node)
Foo ^^^
# 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
#visit_constant_target_node(node)
Foo, = bar ^^^
# 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
#visit_constant_write_node(node)
Foo = 1 ^^^^^^^
Foo, Bar = 1 ^^^ ^^^
# 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
#visit_def_node(node)
def foo; end ^^^^^^^^^^^^
def self.foo; end ^^^^^^^^^^^^^^^^^
# 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
#visit_defined_node(node)
defined? a ^^^^^^^^^^
defined?(a) ^^^^^^^^^^^
# 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
#visit_destructured_parameter_node(node) (private)
Visit a destructured positional parameter node.
# File 'lib/prism/translation/ripper.rb', line 2635
private 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_else_node(node)
if foo then bar else baz end
^^^^^^^^^^^^
# 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
#visit_embedded_statements_node(node)
“foo #bar
”
^^^^^^
# File 'lib/prism/translation/ripper.rb', line 1656
def (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
#visit_embedded_variable_node(node)
“foo #@bar”
^^^^^
#visit_ensure_node(node)
Visit an EnsureNode node.
# 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_false_node(node)
false ^^^^^
# File 'lib/prism/translation/ripper.rb', line 1706
def visit_false_node(node) bounds(node.location) on_var_ref(on_kw("false")) end
#visit_find_pattern_node(node)
foo => [*, bar, *]
^^^^^^^^^^^
# 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
#visit_flip_flop_node(node)
if foo .. bar; end
^^^^^^^^^^
# 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
#visit_float_node(node)
1.0 ^^^
# File 'lib/prism/translation/ripper.rb', line 1752
def visit_float_node(node) visit_number_node(node) { |text| on_float(text) } end
#visit_for_node(node)
for foo in bar do end ^^^^^^^^^^^^^^^^^^^^^
# 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
#visit_forwarding_arguments_node(node)
def foo(…); bar(…); end
^^^
# File 'lib/prism/translation/ripper.rb', line 1775
def visit_forwarding_arguments_node(node) bounds(node.location) on_args_forward end
#visit_forwarding_parameter_node(node)
def foo(…); end
^^^
# File 'lib/prism/translation/ripper.rb', line 1782
def visit_forwarding_parameter_node(node) bounds(node.location) on_args_forward end
#visit_forwarding_super_node(node)
super ^^^^^
super {} ^^^^^^^^
#visit_global_variable_and_write_node(node)
$foo &&= bar ^^^^^^^^^^^^
# 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
#visit_global_variable_operator_write_node(node)
$foo += bar ^^^^^^^^^^^
# 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
#visit_global_variable_or_write_node(node)
$foo ||= bar ^^^^^^^^^^^^
# 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
#visit_global_variable_read_node(node)
$foo ^^^^
# 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
#visit_global_variable_target_node(node)
$foo, = bar ^^^^
# 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
#visit_global_variable_write_node(node)
$foo = 1 ^^^^^^^^
$foo, $bar = 1 ^^^^ ^^^^
# 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
#visit_hash_node(node)
{} ^^
#visit_hash_pattern_node(node)
foo => {}
^^
# 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
#visit_heredoc_node(parts, base) (private)
Visit a string that is expressed using a <<~ heredoc.
# File 'lib/prism/translation/ripper.rb', line 3006
private 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_heredoc_node_whitespace(parts) (private)
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.
# File 'lib/prism/translation/ripper.rb', line 2981
private 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
#visit_heredoc_string_node(node) (private)
Visit a heredoc node that is representing a string.
# File 'lib/prism/translation/ripper.rb', line 3052
private 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_heredoc_x_string_node(node) (private)
Visit a heredoc node that is representing an xstring.
# File 'lib/prism/translation/ripper.rb', line 3069
private 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_if_node(node)
if foo then bar end ^^^^^^^^^^^^^^^^^^^
bar if foo ^^^^^^^^^^
foo ? bar : baz ^^^^^^^^^^^^^^^
# 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
#visit_imaginary_node(node)
1i ^^
# File 'lib/prism/translation/ripper.rb', line 1969
def visit_imaginary_node(node) visit_number_node(node) { |text| on_imaginary(text) } end
#visit_implicit_node(node)
{ foo: }
^^^^
# File 'lib/prism/translation/ripper.rb', line 1975
def visit_implicit_node(node) end
#visit_implicit_rest_node(node)
foo { |bar,| }
^
# File 'lib/prism/translation/ripper.rb', line 1980
def visit_implicit_rest_node(node) bounds(node.location) on_excessed_comma end
#visit_in_node(node)
case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^
# 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
#visit_index_and_write_node(node)
foo &&= baz ^^^^^^^^^^^^^^^^
# 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
#visit_index_operator_write_node(node)
foo += baz ^^^^^^^^^^^^^^^
# 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
#visit_index_or_write_node(node)
foo ||= baz ^^^^^^^^^^^^^^^^
# 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
#visit_index_target_node(node)
foo, = 1 ^^^^^^^^
# 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
#visit_instance_variable_and_write_node(node)
^^^^^^^^^^^^
# 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
#visit_instance_variable_operator_write_node(node)
^^^^^^^^^^^
# 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
#visit_instance_variable_or_write_node(node)
^^^^^^^^^^^^
# 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
#visit_instance_variable_read_node(node)
^^^^
# 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
#visit_instance_variable_target_node(node)
@foo, = bar ^^^^
# 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
#visit_instance_variable_write_node(node)
^^^^^^^^
# 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
#visit_integer_node(node)
1 ^
# File 'lib/prism/translation/ripper.rb', line 2133
def visit_integer_node(node) visit_number_node(node) { |text| on_int(text) } end
#visit_interpolated_match_last_line_node(node)
if /foo #bar
/ then end
^^^^^^^^^^^^
# 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
#visit_interpolated_regular_expression_node(node)
/foo #bar
/ ^^^^^^^^^^^^
# 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
#visit_interpolated_string_node(node)
“foo #bar
” ^^^^^^^^^^^^
# 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
#visit_interpolated_symbol_node(node)
:“foo #bar
” ^^^^^^^^^^^^^
# 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
#visit_interpolated_x_string_node(node)
foo #{bar}
^^^^^^^^^^^^
# 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
#visit_it_local_variable_read_node(node)
-> { it }
^^
# 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
#visit_it_parameters_node(node)
-> { it } ^^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2255
def visit_it_parameters_node(node) end
#visit_keyword_hash_node(node)
foo(bar: baz)
^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2260
def visit_keyword_hash_node(node) elements = visit_all(node.elements) bounds(node.location) (elements) end
#visit_keyword_rest_parameter_node(node)
def foo(**bar); end
^^^^^
def foo(**); end
^^
#visit_lambda_node(node)
-> {}
# 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
#visit_local_variable_and_write_node(node)
foo &&= bar ^^^^^^^^^^^
# 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
#visit_local_variable_operator_write_node(node)
foo += bar ^^^^^^^^^^
# 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
#visit_local_variable_or_write_node(node)
foo ||= bar ^^^^^^^^^^^
# 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
#visit_local_variable_read_node(node)
foo ^^^
# 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
#visit_local_variable_target_node(node)
foo, = bar ^^^
# 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
#visit_local_variable_write_node(node)
foo = 1 ^^^^^^^
# 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
#visit_match_last_line_node(node)
if /foo/ then end
^^^^^
# 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
#visit_match_predicate_node(node)
foo in bar ^^^^^^^^^^
# 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
#visit_match_required_node(node)
foo => bar ^^^^^^^^^^
# 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
#visit_match_write_node(node)
/(?<foo>foo)/ =~ bar ^^^^^^^^^^^^^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2446
def visit_match_write_node(node) visit(node.call) end
#visit_missing_node(node)
A node that is missing from the syntax tree. This is only used in the case of a syntax error.
# File 'lib/prism/translation/ripper.rb', line 2452
def visit_missing_node(node) raise "Cannot visit missing nodes directly." end
#visit_module_node(node)
module Foo; end ^^^^^^^^^^^^^^^
# 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
#visit_multi_target_node(node)
(foo, bar), bar = qux ^^^^^^^^^^
# 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
#visit_multi_target_node_targets(lefts, rest, rights, skippable) (private)
Visit the targets of a multi-target node.
# File 'lib/prism/translation/ripper.rb', line 2488
private 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_multi_write_node(node)
foo, bar = baz ^^^^^^^^^^^^^^
# 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
#visit_next_node(node)
next ^^^^
next foo ^^^^^^^^
#visit_nil_node(node)
nil ^^^
# File 'lib/prism/translation/ripper.rb', line 2563
def visit_nil_node(node) bounds(node.location) on_var_ref(on_kw("nil")) end
#visit_no_keywords_parameter_node(node)
def foo(**nil); end
^^^^^
# File 'lib/prism/translation/ripper.rb', line 2570
def visit_no_keywords_parameter_node(node) bounds(node.location) on_nokw_param(nil) :nil end
#visit_number_node(node) (private)
Visit a node that represents a number. We need to explicitly handle the unary - operator.
# 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_numbered_parameters_node(node)
-> { _1 + _2 } ^^^^^^^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2579
def visit_numbered_parameters_node(node) end
#visit_numbered_reference_read_node(node)
$1 ^^
# File 'lib/prism/translation/ripper.rb', line 2584
def visit_numbered_reference_read_node(node) bounds(node.location) on_backref(node.slice) end
#visit_optional_keyword_parameter_node(node)
def foo(bar: baz); end
^^^^^^^^
# 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
#visit_optional_parameter_node(node)
def foo(bar = 1); end
^^^^^^^
# 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
#visit_or_node(node)
a or b ^^^^^^
# 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
#visit_parameters_node(node)
def foo(bar, *baz); end
^^^^^^^^^
# 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
#visit_parentheses_node(node)
() ^^
(1) ^^^
# 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
#visit_pattern_node(node) (private)
Visit a pattern within a pattern match. This is used to bypass the parenthesis node that can be used to wrap patterns.
# File 'lib/prism/translation/ripper.rb', line 596
private def visit_pattern_node(node) if node.is_a?(ParenthesesNode) visit(node.body) else visit(node) end end
#visit_pinned_expression_node(node)
foo => ^(bar)
^^^^^^
# 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
#visit_pinned_variable_node(node)
foo = 1 and bar => ^foo
^^^^
# File 'lib/prism/translation/ripper.rb', line 2671
def visit_pinned_variable_node(node) visit(node.variable) end
#visit_post_execution_node(node)
END {} ^^^^^^
#visit_pre_execution_node(node)
BEGIN {} ^^^^^^^^
#visit_program_node(node)
The top-level program node.
# 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
#visit_range_node(node)
0..5 ^^^^
# 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
#visit_rational_node(node)
1r ^^
# File 'lib/prism/translation/ripper.rb', line 2731
def visit_rational_node(node) visit_number_node(node) { |text| on_rational(text) } end
#visit_redo_node(node)
redo ^^^^
# File 'lib/prism/translation/ripper.rb', line 2737
def visit_redo_node(node) bounds(node.location) on_redo end
#visit_regular_expression_node(node)
/foo/ ^^^^^
# 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
#visit_required_keyword_parameter_node(node)
def foo(bar:); end
^^^^
# 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
#visit_required_parameter_node(node)
def foo(bar); end
^^^
# File 'lib/prism/translation/ripper.rb', line 2773
def visit_required_parameter_node(node) bounds(node.location) on_ident(node.name.to_s) end
#visit_rescue_modifier_node(node)
foo rescue bar ^^^^^^^^^^^^^^
# 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
#visit_rescue_node(node)
begin; rescue; end
^^^^^^^
# 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
#visit_rest_parameter_node(node)
def foo(*bar); end
^^^^
def foo(*); end
^
# 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
#visit_retry_node(node)
retry ^^^^^
# File 'lib/prism/translation/ripper.rb', line 2860
def visit_retry_node(node) bounds(node.location) on_retry end
#visit_return_node(node)
return ^^^^^^
return 1 ^^^^^^^^
#visit_self_node(node)
self ^^^^
# File 'lib/prism/translation/ripper.rb', line 2884
def visit_self_node(node) bounds(node.location) on_var_ref(on_kw("self")) end
#visit_singleton_class_node(node)
class << self; end ^^^^^^^^^^^^^^^^^^
# 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
#visit_source_encoding_node(node)
__ENCODING__ ^^^^^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2906
def visit_source_encoding_node(node) bounds(node.location) on_var_ref(on_kw("__ENCODING__")) end
#visit_source_file_node(node)
__FILE__ ^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2913
def visit_source_file_node(node) bounds(node.location) on_var_ref(on_kw("__FILE__")) end
#visit_source_line_node(node)
__LINE__ ^^^^^^^^
# File 'lib/prism/translation/ripper.rb', line 2920
def visit_source_line_node(node) bounds(node.location) on_var_ref(on_kw("__LINE__")) end
#visit_splat_node(node)
foo(*bar)
^^^^
def foo((bar, *baz)); end
^^^^
def foo(*); bar(*); end
^
# File 'lib/prism/translation/ripper.rb', line 2933
def visit_splat_node(node) visit(node.expression) end
#visit_statements_node(node)
A list of statements.
# File 'lib/prism/translation/ripper.rb', line 2938
def visit_statements_node(node) bounds(node.location) visit_statements_node_body(node.body) end
#visit_statements_node_body(body) (private)
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.
# File 'lib/prism/translation/ripper.rb', line 2947
private 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_string_content(part) (private)
Visit an individual part of a string-like node.
# File 'lib/prism/translation/ripper.rb', line 2237
private 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_string_node(node)
“foo” ^^^^^
# 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
#visit_super_node(node)
super(foo) ^^^^^^^^^^
# 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
#visit_symbol_node(node)
:foo
^^^^
# 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
#visit_token(token, allow_keywords = true) (private)
Visit the string content of a particular node. This method is used to split into the various token types.
# 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_true_node(node)
true ^^^^
# File 'lib/prism/translation/ripper.rb', line 3132
def visit_true_node(node) bounds(node.location) on_var_ref(on_kw("true")) end
#visit_undef_node(node)
undef foo ^^^^^^^^^
# 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
#visit_unless_node(node)
unless foo; bar end ^^^^^^^^^^^^^^^^^^^
bar unless foo ^^^^^^^^^^^^^^
# 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
#visit_until_node(node)
until foo; bar end ^^^^^^^^^^^^^^^^^
bar until foo ^^^^^^^^^^^^^
# 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
#visit_when_node(node)
case foo; when bar; end
^^^^^^^^^^^^^
# 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
#visit_while_node(node)
while foo; bar end ^^^^^^^^^^^^^^^^^^
bar while foo ^^^^^^^^^^^^^
# 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
#visit_words_sep(opening_loc, previous, current) (private)
Dispatch a words_sep event that contains the space between the elements of list literals.
# File 'lib/prism/translation/ripper.rb', line 746
private 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
#visit_write_value(node) (private)
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.
# 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_x_string_node(node)
foo
^^^^^
# 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
#visit_yield_node(node)
yield ^^^^^
yield 1 ^^^^^^^
# 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
#void_stmt?(left, right, allow_newline) ⇒ Boolean
(private)
Returns true if there is a semicolon between the two locations.
# 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
#warn(fmt, *args) (private)
This method is called when weak warning is produced by the parser. fmt
and args
is printf style.
# File 'lib/prism/translation/ripper.rb', line 3430
def warn(fmt, *args) end
#warning(fmt, *args) (private)
This method is called when strong warning is produced by the parser. fmt
and args
is printf style.
# File 'lib/prism/translation/ripper.rb', line 3435
def warning(fmt, *args) end