class Prism::Translation::Ripper - Documentation for Ruby 4.0
Description: class Prism::Translation::Ripper: This class provides a compatibility layer between prism and Ripper. It functions by parsing the entire tree first and then walking it and executing ea
Keywords: ruby,class,Prism::Translation::Ripper

🔍

No recent searches

# class Prism::Translation::Ripper

This class provides a compatibility layer between prism and `Ripper`. It functions by parsing the entire tree first and then walking it and executing each of the `Ripper` callbacks as it goes. To use this class, you treat `Prism::Translation::Ripper` effectively as you would treat the `Ripper` class.

Note that this class will serve the most common use cases, but Ripper’s API is extensive and undocumented. It relies on reporting the state of the parser at any given time. We do our best to replicate that here, but because it is a different architecture it is not possible to perfectly replicate the behavior of `Ripper`.

The main known difference is that we may omit dispatching some events in some cases. This impacts the following events:

- on_assign_error

- on_comma

- on_ignored_nl

- on_ignored_sp

- on_kw

- on_label_end

- on_lbrace

- on_lbracket

- on_lparen

- on_nl

- on_op

- on_operator_ambiguous

- on_rbrace

- on_rbracket

- on_rparen

- on_semicolon

- on_sp

- on_symbeg

- on_tstring_beg

- on_tstring_end

### Constants

BINARY_OPERATORS

  A list of all of the Ruby binary operators.

EVENTS

  This array contains name of all ripper events.

KEYWORDS

  A list of all of the Ruby keywords.

PARSER_EVENTS

  This array contains name of parser events.

PARSER_EVENT_TABLE

  This contains a table of all of the parser events and their corresponding arity.

SCANNER_EVENTS

  This array contains name of scanner events.

SCANNER_EVENT_TABLE

  This contains a table of all of the scanner events and their corresponding arity.

### Attributes

column [R]

The current column number of the parser.

filename [R]

The filename of the source being parsed.

lineno [R]

The current line number of the parser.

source [R]

The source that is being parsed.

### Public Class Methods

lex (src, filename = "-", lineno = 1, raise_errors: false)
Source

    # File lib/prism/translation/ripper.rb, line 71
    def self.lex(src, filename = "-", lineno = 1, raise_errors: false)
      result = Prism.lex_compat(src, filepath: filename, line: lineno, version: "current")

      if result.failure? && raise_errors
        raise SyntaxError, result.errors.first.message
      else
        result.value
      end
    end

Tokenizes the Ruby program and returns an array of an array, which is formatted like `[[lineno, column], type, token, state]`. The `filename` argument is mostly ignored. By default, this method does not handle syntax errors in `src`, use the `raise_errors` keyword to raise a `SyntaxError` for an error in `src`.

    require "ripper"
    require "pp"

    pp Ripper.lex("def m(a) nil end")
    #=> [[[1,  0], :on_kw,     "def", FNAME    ],
         [[1,  3], :on_sp,     " ",   FNAME    ],
         [[1,  4], :on_ident,  "m",   ENDFN    ],
         [[1,  5], :on_lparen, "(",   BEG|LABEL],
         [[1,  6], :on_ident,  "a",   ARG      ],
         [[1,  7], :on_rparen, ")",   ENDFN    ],
         [[1,  8], :on_sp,     " ",   BEG      ],
         [[1,  9], :on_kw,     "nil", END      ],
         [[1, 12], :on_sp,     " ",   END      ],
         [[1, 13], :on_kw,     "end", END      ]]

new (source, filename = "(ripper)", lineno = 1)
Source

    # File lib/prism/translation/ripper.rb, line 468
    def initialize(source, filename = "(ripper)", lineno = 1)
      @source = source
      @filename = filename
      @lineno = lineno
      @column = 0
      @result = nil
    end

Create a new `Translation::Ripper` object with the given source.

parse (src, filename = "(ripper)", lineno = 1)
Source

    # File lib/prism/translation/ripper.rb, line 45
    def self.parse(src, filename = "(ripper)", lineno = 1)
      new(src, filename, lineno).parse
    end

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)
Source

    # File lib/prism/translation/ripper.rb, line 380
    def self.sexp(src, filename = "-", lineno = 1, raise_errors: false)
      builder = SexpBuilderPP.new(src, filename, lineno)
      sexp = builder.parse
      if builder.error?
        if raise_errors
          raise SyntaxError, builder.error
        end
      else
        sexp
      end
    end

Parses `src` and create S-exp tree. Returns more readable tree rather than `Ripper.sexp_raw`. This method is mainly for developer use. The `filename` argument is mostly ignored. By default, this method does not handle syntax errors in `src`, returning `nil` in such cases. Use the `raise_errors` keyword to raise a `SyntaxError` for an error in `src`.

    require "ripper"
    require "pp"

    pp Ripper.sexp("def m(a) nil end")
      #=> [:program,
           [[:def,
            [:@ident, "m", [1, 4]],
            [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil, nil, nil, nil]],
            [:bodystmt, [[:var_ref, [:@kw, "nil", [1, 9]]]], nil, nil, nil]]]]

sexp_raw (src, filename = "-", lineno = 1, raise_errors: false)
Source

    # File lib/prism/translation/ripper.rb, line 415
    def self.sexp_raw(src, filename = "-", lineno = 1, raise_errors: false)
      builder = SexpBuilder.new(src, filename, lineno)
      sexp = builder.parse
      if builder.error?
        if raise_errors
          raise SyntaxError, builder.error
        end
      else
        sexp
      end
    end

Parses `src` and create S-exp tree. This method is mainly for developer use. The `filename` argument is mostly ignored. By default, this method does not handle syntax errors in `src`, returning `nil` in such cases. Use the `raise_errors` keyword to raise a `SyntaxError` for an error in `src`.

    require "ripper"
    require "pp"

    pp Ripper.sexp_raw("def m(a) nil end")
      #=> [:program,
           [:stmts_add,
            [:stmts_new],
            [:def,
             [:@ident, "m", [1, 4]],
             [:paren, [:params, [[:@ident, "a", [1, 6]]], nil, nil, nil]],
             [:bodystmt,
              [:stmts_add, [:stmts_new], [:var_ref, [:@kw, "nil", [1, 9]]]],
              nil,
              nil,
              nil]]]]

### Public Instance Methods

error? ()
Source

    # File lib/prism/translation/ripper.rb, line 481
    def error?
      result.failure?
    end

True if the parser encountered an error during parsing.

parse ()
Source

    # File lib/prism/translation/ripper.rb, line 486
    def parse
      result.comments.each do |comment|
        location = comment.location
        bounds(location)

        if comment.is_a?(InlineComment)
          on_comment(comment.slice)
        else
          offset = location.start_offset
          lines = comment.slice.lines

          lines.each_with_index do |line, index|
            bounds(location.copy(start_offset: offset))

            if index == 0
              on_embdoc_beg(line)
            elsif index == lines.size - 1
              on_embdoc_end(line)
            else
              on_embdoc(line)
            end

            offset += line.bytesize
          end
        end
      end

      result.magic_comments.each do |magic_comment|
        on_magic_comment(magic_comment.key, magic_comment.value)
      end

      unless result.data_loc.nil?
        on___end__(result.data_loc.slice.each_line.first)
      end

      result.warnings.each do |warning|
        bounds(warning.location)

        if warning.level == :default
          warning(warning.message)
        else
          case warning.type
          when :ambiguous_first_argument_plus
            on_arg_ambiguous("+")
          when :ambiguous_first_argument_minus
            on_arg_ambiguous("-")
          when :ambiguous_slash
            on_arg_ambiguous("/")
          else
            warn(warning.message)
          end
        end
      end

      if error?
        result.errors.each do |error|
          location = error.location
          bounds(location)

          case error.type
          when :alias_argument
            on_alias_error("can't make alias for the number variables", location.slice)
          when :argument_formal_class
            on_param_error("formal argument cannot be a class variable", location.slice)
          when :argument_format_constant
            on_param_error("formal argument cannot be a constant", location.slice)
          when :argument_formal_global
            on_param_error("formal argument cannot be a global variable", location.slice)
          when :argument_formal_ivar
            on_param_error("formal argument cannot be an instance variable", location.slice)
          when :class_name, :module_name
            on_class_name_error("class/module name must be CONSTANT", location.slice)
          else
            on_parse_error(error.message)
          end
        end

        nil
      else
        result.value.accept(self)
      end
    end

Parse the source and return the result.

visit_alias_global_variable_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 585
    def visit_alias_global_variable_node(node)
      new_name = visit_alias_global_variable_node_value(node.new_name)
      old_name = visit_alias_global_variable_node_value(node.old_name)

      bounds(node.location)
      on_var_alias(new_name, old_name)
    end

alias $foo $bar ^^^^^^^^^^^^^^^

visit_alias_method_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 575
    def visit_alias_method_node(node)
      new_name = visit(node.new_name)
      old_name = visit(node.old_name)

      bounds(node.location)
      on_alias(new_name, old_name)
    end

alias foo bar ^^^^^^^^^^^^^

visit_alternation_pattern_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 609
    def visit_alternation_pattern_node(node)
      left = visit_pattern_node(node.left)
      right = visit_pattern_node(node.right)

      bounds(node.location)
      on_binary(left, :|, right)
    end

foo => bar | baz ^^^^^^^^^

visit_and_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 629
    def visit_and_node(node)
      left = visit(node.left)
      right = visit(node.right)

      bounds(node.location)
      on_binary(left, node.operator.to_sym, right)
    end

a and b ^^^^^^^

visit_arguments_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 820
    def visit_arguments_node(node)
      arguments, _ = visit_call_node_arguments(node, nil, false)
      arguments
    end

foo(bar) ^^^

visit_array_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 639
    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)
Source

    # File lib/prism/translation/ripper.rb, line 799
    def visit_array_pattern_node(node)
      constant = visit(node.constant)
      requireds = visit_all(node.requireds) if node.requireds.any?
      rest =
        if (rest_node = node.rest).is_a?(SplatNode)
          if rest_node.expression.nil?
            bounds(rest_node.location)
            on_var_field(nil)
          else
            visit(rest_node.expression)
          end
        end

      posts = visit_all(node.posts) if node.posts.any?

      bounds(node.location)
      on_aryptn(constant, requireds, rest, posts)
    end

foo => [bar] ^^^^^

visit_assoc_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 827
    def visit_assoc_node(node)
      key = visit(node.key)
      value = visit(node.value)

      bounds(node.location)
      on_assoc_new(key, value)
    end

{ a: 1 } ^^^^

visit_assoc_splat_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 840
    def visit_assoc_splat_node(node)
      value = visit(node.value)

      bounds(node.location)
      on_assoc_splat(value)
    end

def foo(); bar(); end ^^

{ **foo } ^^^^^

visit_back_reference_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 849
    def visit_back_reference_read_node(node)
      bounds(node.location)
      on_backref(node.slice)
    end

$+ ^^

visit_begin_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 856
    def visit_begin_node(node)
      clauses = visit_begin_node_clauses(node.begin_keyword_loc, node, false)

      bounds(node.location)
      on_begin(clauses)
    end

begin end ^^^^^^^^^

visit_block_argument_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 920
    def visit_block_argument_node(node)
      visit(node.expression)
    end

foo(&bar) ^^^^

visit_block_local_variable_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 926
    def visit_block_local_variable_node(node)
      bounds(node.location)
      on_ident(node.name.to_s)
    end

foo { |; bar| } ^^^

visit_block_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 932
    def visit_block_node(node)
      braces = node.opening == "{"
      parameters = visit(node.parameters)

      body =
        case node.body
        when nil
          bounds(node.location)
          stmts = on_stmts_add(on_stmts_new, on_void_stmt)

          bounds(node.location)
          braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
        when StatementsNode
          stmts = node.body.body
          stmts.unshift(nil) if void_stmt?(node.parameters&.location || node.opening_loc, node.body.location, false)
          stmts = visit_statements_node_body(stmts)

          bounds(node.body.location)
          braces ? stmts : on_bodystmt(stmts, nil, nil, nil)
        when BeginNode
          visit_body_node(node.parameters&.location || node.opening_loc, node.body)
        else
          raise
        end

      if braces
        bounds(node.location)
        on_brace_block(parameters, body)
      else
        bounds(node.location)
        on_do_block(parameters, body)
      end
    end

Visit a `BlockNode`.

visit_block_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 968
    def visit_block_parameter_node(node)
      if node.name_loc.nil?
        bounds(node.location)
        on_blockarg(nil)
      else
        bounds(node.name_loc)
        name = visit_token(node.name.to_s)

        bounds(node.location)
        on_blockarg(name)
      end
    end

def foo(&bar); end ^^^^

visit_block_parameters_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 982
    def visit_block_parameters_node(node)
      parameters =
        if node.parameters.nil?
          on_params(nil, nil, nil, nil, nil, nil, nil)
        else
          visit(node.parameters)
        end

      locals =
        if node.locals.any?
          visit_all(node.locals)
        else
          false
        end

      bounds(node.location)
      on_block_var(parameters, locals)
    end

A block’s parameters.

visit_break_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1006
    def visit_break_node(node)
      if node.arguments.nil?
        bounds(node.location)
        on_break(on_args_new)
      else
        arguments = visit(node.arguments)

        bounds(node.location)
        on_break(arguments)
      end
    end

break ^^^^^

break foo ^^^^^^^^^

visit_call_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1228
    def visit_call_and_write_node(node)
      receiver = visit(node.receiver)

      bounds(node.call_operator_loc)
      call_operator = visit_token(node.call_operator)

      bounds(node.message_loc)
      message = visit_token(node.message)

      bounds(node.location)
      target = on_field(receiver, call_operator, message)

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo.bar &&= baz ^^^^^^^^^^^^^^^

visit_call_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1026
    def visit_call_node(node)
      if node.call_operator_loc.nil?
        case node.name
        when :[]
          receiver = visit(node.receiver)
          arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))

          bounds(node.location)
          call = on_aref(receiver, arguments)

          if block.nil?
            call
          else
            bounds(node.location)
            on_method_add_block(call, block)
          end
        when :[]=
          receiver = visit(node.receiver)

          *arguments, last_argument = node.arguments.arguments
          arguments << node.block if !node.block.nil?

          arguments =
            if arguments.any?
              args = visit_arguments(arguments)

              if !node.block.nil?
                args
              else
                bounds(arguments.first.location)
                on_args_add_block(args, false)
              end
            end

          bounds(node.location)
          call = on_aref_field(receiver, arguments)
          value = visit_write_value(last_argument)

          bounds(last_argument.location)
          on_assign(call, value)
        when :-@, :+@, :~
          receiver = visit(node.receiver)

          bounds(node.location)
          on_unary(node.name, receiver)
        when :!
          if node.message == "not"
            receiver =
              if !node.receiver.is_a?(ParenthesesNode) || !node.receiver.body.nil?
                visit(node.receiver)
              end

            bounds(node.location)
            on_unary(:not, receiver)
          else
            receiver = visit(node.receiver)

            bounds(node.location)
            on_unary(:!, receiver)
          end
        when *BINARY_OPERATORS
          receiver = visit(node.receiver)
          value = visit(node.arguments.arguments.first)

          bounds(node.location)
          on_binary(receiver, node.name, value)
        else
          bounds(node.message_loc)
          message = visit_token(node.message, false)

          if node.variable_call?
            on_vcall(message)
          else
            arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location))
            call =
              if node.opening_loc.nil? && arguments&.any?
                bounds(node.location)
                on_command(message, arguments)
              elsif !node.opening_loc.nil?
                bounds(node.location)
                on_method_add_arg(on_fcall(message), on_arg_paren(arguments))
              else
                bounds(node.location)
                on_method_add_arg(on_fcall(message), on_args_new)
              end

            if block.nil?
              call
            else
              bounds(node.block.location)
              on_method_add_block(call, block)
            end
          end
        end
      else
        receiver = visit(node.receiver)

        bounds(node.call_operator_loc)
        call_operator = visit_token(node.call_operator)

        message =
          if node.message_loc.nil?
            :call
          else
            bounds(node.message_loc)
            visit_token(node.message, false)
          end

        if node.name.end_with?("=") && !node.message.end_with?("=") && !node.arguments.nil? && node.block.nil?
          value = visit_write_value(node.arguments.arguments.first)

          bounds(node.location)
          on_assign(on_field(receiver, call_operator, message), value)
        else
          arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc || node.location))
          call =
            if node.opening_loc.nil?
              bounds(node.location)

              if node.arguments.nil? && !node.block.is_a?(BlockArgumentNode)
                on_call(receiver, call_operator, message)
              else
                on_command_call(receiver, call_operator, message, arguments)
              end
            else
              bounds(node.opening_loc)
              arguments = on_arg_paren(arguments)

              bounds(node.location)
              on_method_add_arg(on_call(receiver, call_operator, message), arguments)
            end

          if block.nil?
            call
          else
            bounds(node.block.location)
            on_method_add_block(call, block)
          end
        end
      end
    end

foo ^^^

foo.bar ^^^^^^^

foo.bar() {} ^^^^^^^^^^^^

visit_call_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1206
    def visit_call_operator_write_node(node)
      receiver = visit(node.receiver)

      bounds(node.call_operator_loc)
      call_operator = visit_token(node.call_operator)

      bounds(node.message_loc)
      message = visit_token(node.message)

      bounds(node.location)
      target = on_field(receiver, call_operator, message)

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo.bar += baz ^^^^^^^^^^^^^^^

visit_call_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1250
    def visit_call_or_write_node(node)
      receiver = visit(node.receiver)

      bounds(node.call_operator_loc)
      call_operator = visit_token(node.call_operator)

      bounds(node.message_loc)
      message = visit_token(node.message)

      bounds(node.location)
      target = on_field(receiver, call_operator, message)

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo.bar ||= baz ^^^^^^^^^^^^^^^

visit_call_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1272
    def visit_call_target_node(node)
      if node.call_operator == "::"
        receiver = visit(node.receiver)

        bounds(node.message_loc)
        message = visit_token(node.message)

        bounds(node.location)
        on_const_path_field(receiver, message)
      else
        receiver = visit(node.receiver)

        bounds(node.call_operator_loc)
        call_operator = visit_token(node.call_operator)

        bounds(node.message_loc)
        message = visit_token(node.message)

        bounds(node.location)
        on_field(receiver, call_operator, message)
      end
    end

foo.bar, = 1 ^^^^^^^

visit_capture_pattern_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1297
    def visit_capture_pattern_node(node)
      value = visit(node.value)
      target = visit(node.target)

      bounds(node.location)
      on_binary(value, :"=>", target)
    end

foo => bar => baz ^^^^^^^^^^

visit_case_match_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1320
    def visit_case_match_node(node)
      predicate = visit(node.predicate)
      clauses =
        node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition|
          on_in(*visit(condition), current)
        end

      bounds(node.location)
      on_case(predicate, clauses)
    end

case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^

visit_case_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1307
    def visit_case_node(node)
      predicate = visit(node.predicate)
      clauses =
        node.conditions.reverse_each.inject(visit(node.else_clause)) do |current, condition|
          on_when(*visit(condition), current)
        end

      bounds(node.location)
      on_case(predicate, clauses)
    end

case foo; when bar; end ^^^^^^^^^^^^^^^^^^^^^^^

visit_class_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1333
    def visit_class_node(node)
      constant_path =
        if node.constant_path.is_a?(ConstantReadNode)
          bounds(node.constant_path.location)
          on_const_ref(on_const(node.constant_path.name.to_s))
        else
          visit(node.constant_path)
        end

      superclass = visit(node.superclass)
      bodystmt = visit_body_node(node.superclass&.location || node.constant_path.location, node.body, node.superclass.nil?)

      bounds(node.location)
      on_class(constant_path, superclass, bodystmt)
    end

class Foo; end ^^^^^^^^^^^^^^

visit_class_variable_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1386
    def visit_class_variable_and_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_cvar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@@foo &&= bar ^^^^^^^^^^^^^

visit_class_variable_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1372
    def visit_class_variable_operator_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_cvar(node.name.to_s))

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@@foo += bar ^^^^^^^^^^^^

visit_class_variable_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1400
    def visit_class_variable_or_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_cvar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@@foo ||= bar ^^^^^^^^^^^^^

visit_class_variable_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1351
    def visit_class_variable_read_node(node)
      bounds(node.location)
      on_var_ref(on_cvar(node.slice))
    end

@@foo ^^^^^

visit_class_variable_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1414
    def visit_class_variable_target_node(node)
      bounds(node.location)
      on_var_field(on_cvar(node.name.to_s))
    end

@@foo, = bar ^^^^^

visit_class_variable_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1361
    def visit_class_variable_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_cvar(node.name.to_s))
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

@@foo = 1 ^^^^^^^^^

@@foo, @@bar = 1 ^^^^^ ^^^^^

visit_constant_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1456
    def visit_constant_and_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_const(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo &&= bar ^^^^^^^^^^^^

visit_constant_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1442
    def visit_constant_operator_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_const(node.name.to_s))

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo += bar ^^^^^^^^^^^

visit_constant_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1470
    def visit_constant_or_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_const(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo ||= bar ^^^^^^^^^^^^

visit_constant_path_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1557
    def visit_constant_path_and_write_node(node)
      target = visit_constant_path_write_node_target(node.target)
      value = visit(node.value)

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo::Bar &&= baz ^^^^^^^^^^^^^^^^

visit_constant_path_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1491
    def visit_constant_path_node(node)
      if node.parent.nil?
        bounds(node.name_loc)
        child = on_const(node.name.to_s)

        bounds(node.location)
        on_top_const_ref(child)
      else
        parent = visit(node.parent)

        bounds(node.name_loc)
        child = on_const(node.name.to_s)

        bounds(node.location)
        on_const_path_ref(parent, child)
      end
    end

Foo::Bar ^^^^^^^^

visit_constant_path_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1543
    def visit_constant_path_operator_write_node(node)
      target = visit_constant_path_write_node_target(node.target)
      value = visit(node.value)

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo::Bar += baz ^^^^^^^^^^^^^^^

visit_constant_path_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1571
    def visit_constant_path_or_write_node(node)
      target = visit_constant_path_write_node_target(node.target)
      value = visit(node.value)

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

Foo::Bar ||= baz ^^^^^^^^^^^^^^^^

visit_constant_path_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1585
    def visit_constant_path_target_node(node)
      visit_constant_path_write_node_target(node)
    end

Foo::Bar, = baz ^^^^^^^^

visit_constant_path_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1514
    def visit_constant_path_write_node(node)
      target = visit_constant_path_write_node_target(node.target)
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

Foo::Bar = 1 ^^^^^^^^^^^^

Foo::Foo, Bar::Bar = 1 ^^^^^^^^ ^^^^^^^^

visit_constant_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1421
    def visit_constant_read_node(node)
      bounds(node.location)
      on_var_ref(on_const(node.name.to_s))
    end

Foo ^^^

visit_constant_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1484
    def visit_constant_target_node(node)
      bounds(node.location)
      on_var_field(on_const(node.name.to_s))
    end

Foo, = bar ^^^

visit_constant_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1431
    def visit_constant_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_const(node.name.to_s))
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

Foo = 1 ^^^^^^^

Foo, Bar = 1 ^^^ ^^^

visit_def_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1594
    def visit_def_node(node)
      receiver = visit(node.receiver)
      operator =
        if !node.operator_loc.nil?
          bounds(node.operator_loc)
          visit_token(node.operator)
        end

      bounds(node.name_loc)
      name = visit_token(node.name_loc.slice)

      parameters =
        if node.parameters.nil?
          bounds(node.location)
          on_params(nil, nil, nil, nil, nil, nil, nil)
        else
          visit(node.parameters)
        end

      if !node.lparen_loc.nil?
        bounds(node.lparen_loc)
        parameters = on_paren(parameters)
      end

      bodystmt =
        if node.equal_loc.nil?
          visit_body_node(node.rparen_loc || node.end_keyword_loc, node.body)
        else
          body = visit(node.body.body.first)

          bounds(node.body.location)
          on_bodystmt(body, nil, nil, nil)
        end

      bounds(node.location)
      if receiver.nil?
        on_def(name, parameters, bodystmt)
      else
        on_defs(receiver, operator, name, parameters, bodystmt)
      end
    end

def foo; end ^^^^^^^^^^^^

def self.foo; end ^^^^^^^^^^^^^^^^^

visit_defined_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1641
    def visit_defined_node(node)
      expression = visit(node.value)

      # Very weird circumstances here where something like:
      #
      #     defined?
      #     (1)
      #
      # gets parsed in Ruby as having only the `1` expression but in Ripper it
      # gets parsed as having a parentheses node. In this case we need to
      # synthesize that node to match Ripper's behavior.
      if node.lparen_loc && node.keyword_loc.join(node.lparen_loc).slice.include?("\n")
        bounds(node.lparen_loc.join(node.rparen_loc))
        expression = on_paren(on_stmts_add(on_stmts_new, expression))
      end

      bounds(node.location)
      on_defined(expression)
    end

defined? a ^^^^^^^^^^

defined?(a) ^^^^^^^^^^^

visit_else_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1663
    def visit_else_node(node)
      statements =
        if node.statements.nil?
          [nil]
        else
          body = node.statements.body
          body.unshift(nil) if void_stmt?(node.else_keyword_loc, node.statements.body[0].location, false)
          body
        end

      bounds(node.location)
      on_else(visit_statements_node_body(statements))
    end

if foo then bar else baz end ^^^^^^^^^^^^

visit_embedded_statements_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1679
    def visit_embedded_statements_node(node)
      bounds(node.opening_loc)
      on_embexpr_beg(node.opening)

      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      bounds(node.closing_loc)
      on_embexpr_end(node.closing)

      bounds(node.location)
      on_string_embexpr(statements)
    end

“foo #{bar}” ^^^^^^

visit_embedded_variable_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1700
    def visit_embedded_variable_node(node)
      bounds(node.operator_loc)
      on_embvar(node.operator)

      variable = visit(node.variable)

      bounds(node.location)
      on_string_dvar(variable)
    end

“foo #@bar” ^^^^^

visit_ensure_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1711
    def visit_ensure_node(node)
      statements =
        if node.statements.nil?
          [nil]
        else
          body = node.statements.body
          body.unshift(nil) if void_stmt?(node.ensure_keyword_loc, body[0].location, false)
          body
        end

      statements = visit_statements_node_body(statements)

      bounds(node.location)
      on_ensure(statements)
    end

Visit an `EnsureNode` node.

visit_false_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1729
    def visit_false_node(node)
      bounds(node.location)
      on_var_ref(on_kw("false"))
    end

false ^^^^^

visit_find_pattern_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1736
    def visit_find_pattern_node(node)
      constant = visit(node.constant)
      left =
        if node.left.expression.nil?
          bounds(node.left.location)
          on_var_field(nil)
        else
          visit(node.left.expression)
        end

      requireds = visit_all(node.requireds) if node.requireds.any?
      right =
        if node.right.expression.nil?
          bounds(node.right.location)
          on_var_field(nil)
        else
          visit(node.right.expression)
        end

      bounds(node.location)
      on_fndptn(constant, left, requireds, right)
    end

foo => [, bar, ] ^^^^^^^^^^^

visit_flip_flop_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1761
    def visit_flip_flop_node(node)
      left = visit(node.left)
      right = visit(node.right)

      bounds(node.location)
      if node.exclude_end?
        on_dot3(left, right)
      else
        on_dot2(left, right)
      end
    end

if foo .. bar; end ^^^^^^^^^^

visit_float_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1775
    def visit_float_node(node)
      visit_number_node(node) { |text| on_float(text) }
    end

1.0 ^^^

visit_for_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1781
    def visit_for_node(node)
      index = visit(node.index)
      collection = visit(node.collection)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      bounds(node.location)
      on_for(index, collection, statements)
    end

for foo in bar do end ^^^^^^^^^^^^^^^^^^^^^

visit_forwarding_arguments_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1798
    def visit_forwarding_arguments_node(node)
      bounds(node.location)
      on_args_forward
    end

def foo(…); bar(…); end ^^^

visit_forwarding_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1805
    def visit_forwarding_parameter_node(node)
      bounds(node.location)
      on_args_forward
    end

def foo(…); end ^^^

visit_forwarding_super_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1815
    def visit_forwarding_super_node(node)
      if node.block.nil?
        bounds(node.location)
        on_zsuper
      else
        block = visit(node.block)

        bounds(node.location)
        on_method_add_block(on_zsuper, block)
      end
    end

super ^^^^^

super {} ^^^^^^^^

visit_global_variable_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1864
    def visit_global_variable_and_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_gvar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

$foo &&= bar ^^^^^^^^^^^^

visit_global_variable_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1850
    def visit_global_variable_operator_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_gvar(node.name.to_s))

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

$foo += bar ^^^^^^^^^^^

visit_global_variable_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1878
    def visit_global_variable_or_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_gvar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

$foo ||= bar ^^^^^^^^^^^^

visit_global_variable_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1829
    def visit_global_variable_read_node(node)
      bounds(node.location)
      on_var_ref(on_gvar(node.name.to_s))
    end

$foo ^^^^

visit_global_variable_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1892
    def visit_global_variable_target_node(node)
      bounds(node.location)
      on_var_field(on_gvar(node.name.to_s))
    end

$foo, = bar ^^^^

visit_global_variable_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1839
    def visit_global_variable_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_gvar(node.name.to_s))
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

$foo = 1 ^^^^^^^^

$foo, $bar = 1 ^^^^ ^^^^

visit_hash_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1899
    def visit_hash_node(node)
      elements =
        if node.elements.any?
          args = visit_all(node.elements)

          bounds(node.elements.first.location)
          on_assoclist_from_args(args)
        end

      bounds(node.location)
      on_hash(elements)
    end

{} ^^

visit_hash_pattern_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1914
    def visit_hash_pattern_node(node)
      constant = visit(node.constant)
      elements =
        if node.elements.any? || !node.rest.nil?
          node.elements.map do |element|
            [
              if (key = element.key).opening_loc.nil?
                visit(key)
              else
                bounds(key.value_loc)
                if (value = key.value).empty?
                  on_string_content
                else
                  on_string_add(on_string_content, on_tstring_content(value))
                end
              end,
              visit(element.value)
            ]
          end
        end

      rest =
        case node.rest
        when AssocSplatNode
          visit(node.rest.value)
        when NoKeywordsParameterNode
          bounds(node.rest.location)
          on_var_field(visit(node.rest))
        end

      bounds(node.location)
      on_hshptn(constant, elements, rest)
    end

foo => {} ^^

visit_if_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1956
    def visit_if_node(node)
      if node.then_keyword == "?"
        predicate = visit(node.predicate)
        truthy = visit(node.statements.body.first)
        falsy = visit(node.subsequent.statements.body.first)

        bounds(node.location)
        on_ifop(predicate, truthy, falsy)
      elsif node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
        predicate = visit(node.predicate)
        statements =
          if node.statements.nil?
            bounds(node.location)
            on_stmts_add(on_stmts_new, on_void_stmt)
          else
            visit(node.statements)
          end
        subsequent = visit(node.subsequent)

        bounds(node.location)
        if node.if_keyword == "if"
          on_if(predicate, statements, subsequent)
        else
          on_elsif(predicate, statements, subsequent)
        end
      else
        statements = visit(node.statements.body.first)
        predicate = visit(node.predicate)

        bounds(node.location)
        on_if_mod(predicate, statements)
      end
    end

if foo then bar end ^^^^^^^^^^^^^^^^^^^

bar if foo ^^^^^^^^^^

foo ? bar : baz ^^^^^^^^^^^^^^^

visit_imaginary_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1992
    def visit_imaginary_node(node)
      visit_number_node(node) { |text| on_imaginary(text) }
    end

1i ^^

visit_implicit_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 1998
    def visit_implicit_node(node)
    end

{ foo: } ^^^^

visit_implicit_rest_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2003
    def visit_implicit_rest_node(node)
      bounds(node.location)
      on_excessed_comma
    end

foo { |bar,| } ^

visit_in_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2010
    def visit_in_node(node)
      # This is a special case where we're not going to call on_in directly
      # because we don't have access to the subsequent. Instead, we'll return
      # the component parts and let the parent node handle it.
      pattern = visit_pattern_node(node.pattern)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      [pattern, statements]
    end

case foo; in bar; end ^^^^^^^^^^^^^^^^^^^^^

visit_index_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2045
    def visit_index_and_write_node(node)
      receiver = visit(node.receiver)
      arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))

      bounds(node.location)
      target = on_aref_field(receiver, arguments)

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo &&= baz ^^^^^^^^^^^^^^^^

visit_index_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2028
    def visit_index_operator_write_node(node)
      receiver = visit(node.receiver)
      arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))

      bounds(node.location)
      target = on_aref_field(receiver, arguments)

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo += baz ^^^^^^^^^^^^^^^

visit_index_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2062
    def visit_index_or_write_node(node)
      receiver = visit(node.receiver)
      arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))

      bounds(node.location)
      target = on_aref_field(receiver, arguments)

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo ||= baz ^^^^^^^^^^^^^^^^

visit_index_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2079
    def visit_index_target_node(node)
      receiver = visit(node.receiver)
      arguments, _ = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.closing_loc))

      bounds(node.location)
      on_aref_field(receiver, arguments)
    end

foo, = 1 ^^^^^^^^

visit_instance_variable_and_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2121
    def visit_instance_variable_and_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ivar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@foo &&= bar ^^^^^^^^^^^^

visit_instance_variable_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2107
    def visit_instance_variable_operator_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ivar(node.name.to_s))

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@foo += bar ^^^^^^^^^^^

visit_instance_variable_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2135
    def visit_instance_variable_or_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ivar(node.name.to_s))

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

@foo ||= bar ^^^^^^^^^^^^

visit_instance_variable_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2089
    def visit_instance_variable_read_node(node)
      bounds(node.location)
      on_var_ref(on_ivar(node.name.to_s))
    end

@foo ^^^^

visit_instance_variable_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2149
    def visit_instance_variable_target_node(node)
      bounds(node.location)
      on_var_field(on_ivar(node.name.to_s))
    end

@foo, = bar ^^^^

visit_instance_variable_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2096
    def visit_instance_variable_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ivar(node.name.to_s))
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

@foo = 1 ^^^^^^^^

visit_integer_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2156
    def visit_integer_node(node)
      visit_number_node(node) { |text| on_int(text) }
    end

1 ^

visit_interpolated_match_last_line_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2162
    def visit_interpolated_match_last_line_node(node)
      bounds(node.opening_loc)
      on_regexp_beg(node.opening)

      bounds(node.parts.first.location)
      parts =
        node.parts.inject(on_regexp_new) do |content, part|
          on_regexp_add(content, visit_string_content(part))
        end

      bounds(node.closing_loc)
      closing = on_regexp_end(node.closing)

      bounds(node.location)
      on_regexp_literal(parts, closing)
    end

if /foo #{bar}/ then end ^^^^^^^^^^^^

visit_interpolated_regular_expression_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2181
    def visit_interpolated_regular_expression_node(node)
      bounds(node.opening_loc)
      on_regexp_beg(node.opening)

      bounds(node.parts.first.location)
      parts =
        node.parts.inject(on_regexp_new) do |content, part|
          on_regexp_add(content, visit_string_content(part))
        end

      bounds(node.closing_loc)
      closing = on_regexp_end(node.closing)

      bounds(node.location)
      on_regexp_literal(parts, closing)
    end

/foo #{bar}/ ^^^^^^^^^^^^

visit_interpolated_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2200
    def visit_interpolated_string_node(node)
      if node.opening&.start_with?("<<~")
        heredoc = visit_heredoc_string_node(node)

        bounds(node.location)
        on_string_literal(heredoc)
      elsif !node.heredoc? && node.parts.length > 1 && node.parts.any? { |part| (part.is_a?(StringNode) || part.is_a?(InterpolatedStringNode)) && !part.opening_loc.nil? }
        first, *rest = node.parts
        rest.inject(visit(first)) do |content, part|
          concat = visit(part)

          bounds(part.location)
          on_string_concat(content, concat)
        end
      else
        bounds(node.parts.first.location)
        parts =
          node.parts.inject(on_string_content) do |content, part|
            on_string_add(content, visit_string_content(part))
          end

        bounds(node.location)
        on_string_literal(parts)
      end
    end

“foo #{bar}” ^^^^^^^^^^^^

visit_interpolated_symbol_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2228
    def visit_interpolated_symbol_node(node)
      bounds(node.parts.first.location)
      parts =
        node.parts.inject(on_string_content) do |content, part|
          on_string_add(content, visit_string_content(part))
        end

      bounds(node.location)
      on_dyna_symbol(parts)
    end

:“foo #{bar}” ^^^^^^^^^^^^^

visit_interpolated_x_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2241
    def visit_interpolated_x_string_node(node)
      if node.opening.start_with?("<<~")
        heredoc = visit_heredoc_x_string_node(node)

        bounds(node.location)
        on_xstring_literal(heredoc)
      else
        bounds(node.parts.first.location)
        parts =
          node.parts.inject(on_xstring_new) do |content, part|
            on_xstring_add(content, visit_string_content(part))
          end

        bounds(node.location)
        on_xstring_literal(parts)
      end
    end

`foo #{bar}` ^^^^^^^^^^^^

visit_it_local_variable_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2271
    def visit_it_local_variable_read_node(node)
      bounds(node.location)
      on_vcall(on_ident(node.slice))
    end

-> { it } ^^

visit_it_parameters_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2278
    def visit_it_parameters_node(node)
    end

-> { it } ^^^^^^^^^

visit_keyword_hash_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2283
    def visit_keyword_hash_node(node)
      elements = visit_all(node.elements)

      bounds(node.location)
      on_bare_assoc_hash(elements)
    end

foo(bar: baz) ^^^^^^^^

visit_keyword_rest_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2295
    def visit_keyword_rest_parameter_node(node)
      if node.name_loc.nil?
        bounds(node.location)
        on_kwrest_param(nil)
      else
        bounds(node.name_loc)
        name = on_ident(node.name.to_s)

        bounds(node.location)
        on_kwrest_param(name)
      end
    end

def foo(**bar); end ^^^^^

def foo(**); end ^^

visit_lambda_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2309
    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)
Source

    # File lib/prism/translation/ripper.rb, line 2401
    def visit_local_variable_and_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ident(node.name_loc.slice))

      bounds(node.operator_loc)
      operator = on_op("&&=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo &&= bar ^^^^^^^^^^^

visit_local_variable_operator_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2387
    def visit_local_variable_operator_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ident(node.name_loc.slice))

      bounds(node.binary_operator_loc)
      operator = on_op("#{node.binary_operator}=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo += bar ^^^^^^^^^^

visit_local_variable_or_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2415
    def visit_local_variable_or_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ident(node.name_loc.slice))

      bounds(node.operator_loc)
      operator = on_op("||=")
      value = visit_write_value(node.value)

      bounds(node.location)
      on_opassign(target, operator, value)
    end

foo ||= bar ^^^^^^^^^^^

visit_local_variable_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2369
    def visit_local_variable_read_node(node)
      bounds(node.location)
      on_var_ref(on_ident(node.slice))
    end

foo ^^^

visit_local_variable_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2429
    def visit_local_variable_target_node(node)
      bounds(node.location)
      on_var_field(on_ident(node.name.to_s))
    end

foo, = bar ^^^

visit_local_variable_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2376
    def visit_local_variable_write_node(node)
      bounds(node.name_loc)
      target = on_var_field(on_ident(node.name_loc.slice))
      value = visit_write_value(node.value)

      bounds(node.location)
      on_assign(target, value)
    end

foo = 1 ^^^^^^^

visit_match_last_line_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2436
    def visit_match_last_line_node(node)
      bounds(node.opening_loc)
      on_regexp_beg(node.opening)

      bounds(node.content_loc)
      tstring_content = on_tstring_content(node.content)

      bounds(node.closing_loc)
      closing = on_regexp_end(node.closing)

      on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing)
    end

if /foo/ then end ^^^^^

visit_match_predicate_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2451
    def visit_match_predicate_node(node)
      value = visit(node.value)
      pattern = on_in(visit_pattern_node(node.pattern), nil, nil)

      on_case(value, pattern)
    end

foo in bar ^^^^^^^^^^

visit_match_required_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2460
    def visit_match_required_node(node)
      value = visit(node.value)
      pattern = on_in(visit_pattern_node(node.pattern), nil, nil)

      on_case(value, pattern)
    end

foo => bar ^^^^^^^^^^

visit_match_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2469
    def visit_match_write_node(node)
      visit(node.call)
    end

/(?<foo>foo)/ =~ bar ^^^^^^^^^^^^^^^^^^^^

visit_missing_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2475
    def visit_missing_node(node)
      raise "Cannot visit missing nodes directly."
    end

A node that is missing from the syntax tree. This is only used in the case of a syntax error.

visit_module_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2481
    def visit_module_node(node)
      constant_path =
        if node.constant_path.is_a?(ConstantReadNode)
          bounds(node.constant_path.location)
          on_const_ref(on_const(node.constant_path.name.to_s))
        else
          visit(node.constant_path)
        end

      bodystmt = visit_body_node(node.constant_path.location, node.body, true)

      bounds(node.location)
      on_module(constant_path, bodystmt)
    end

module Foo; end ^^^^^^^^^^^^^^^

visit_multi_target_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2498
    def visit_multi_target_node(node)
      bounds(node.location)
      targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)

      if node.lparen_loc.nil?
        targets
      else
        bounds(node.lparen_loc)
        on_mlhs_paren(targets)
      end
    end

(foo, bar), bar = qux ^^^^^^^^^^

visit_multi_write_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2552
    def visit_multi_write_node(node)
      bounds(node.location)
      targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, true)

      unless node.lparen_loc.nil?
        bounds(node.lparen_loc)
        targets = on_mlhs_paren(targets)
      end

      value = visit_write_value(node.value)

      bounds(node.location)
      on_massign(targets, value)
    end

foo, bar = baz ^^^^^^^^^^^^^^

visit_next_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2572
    def visit_next_node(node)
      if node.arguments.nil?
        bounds(node.location)
        on_next(on_args_new)
      else
        arguments = visit(node.arguments)

        bounds(node.location)
        on_next(arguments)
      end
    end

next ^^^^

next foo ^^^^^^^^

visit_nil_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2586
    def visit_nil_node(node)
      bounds(node.location)
      on_var_ref(on_kw("nil"))
    end

nil ^^^

visit_no_keywords_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2593
    def visit_no_keywords_parameter_node(node)
      bounds(node.location)
      on_nokw_param(nil)

      :nil
    end

def foo(**nil); end ^^^^^

visit_numbered_parameters_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2602
    def visit_numbered_parameters_node(node)
    end

-> { 1 + 2 } ^^^^^^^^^^^^^^

visit_numbered_reference_read_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2607
    def visit_numbered_reference_read_node(node)
      bounds(node.location)
      on_backref(node.slice)
    end

$1 ^^

visit_optional_keyword_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2614
    def visit_optional_keyword_parameter_node(node)
      bounds(node.name_loc)
      name = on_label("#{node.name}:")
      value = visit(node.value)

      [name, value]
    end

def foo(bar: baz); end ^^^^^^^^

visit_optional_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2624
    def visit_optional_parameter_node(node)
      bounds(node.name_loc)
      name = visit_token(node.name.to_s)
      value = visit(node.value)

      [name, value]
    end

def foo(bar = 1); end ^^^^^^^

visit_or_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2634
    def visit_or_node(node)
      left = visit(node.left)
      right = visit(node.right)

      bounds(node.location)
      on_binary(left, node.operator.to_sym, right)
    end

a or b ^^^^^^

visit_parameters_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2644
    def visit_parameters_node(node)
      requireds = node.requireds.map { |required| required.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(required) : visit(required) } if node.requireds.any?
      optionals = visit_all(node.optionals) if node.optionals.any?
      rest = visit(node.rest)
      posts = node.posts.map { |post| post.is_a?(MultiTargetNode) ? visit_destructured_parameter_node(post) : visit(post) } if node.posts.any?
      keywords = visit_all(node.keywords) if node.keywords.any?
      keyword_rest = visit(node.keyword_rest)
      block = visit(node.block)

      bounds(node.location)
      on_params(requireds, optionals, rest, posts, keywords, keyword_rest, block)
    end

def foo(bar, *baz); end ^^^^^^^^^

visit_parentheses_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2671
    def visit_parentheses_node(node)
      body =
        if node.body.nil?
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.body)
        end

      bounds(node.location)
      on_paren(body)
    end

() ^^

(1) ^^^

visit_pinned_expression_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2685
    def visit_pinned_expression_node(node)
      expression = visit(node.expression)

      bounds(node.location)
      on_begin(expression)
    end

foo => ^(bar) ^^^^^^

visit_pinned_variable_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2694
    def visit_pinned_variable_node(node)
      visit(node.variable)
    end

foo = 1 and bar => ^foo ^^^^

visit_post_execution_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2700
    def visit_post_execution_node(node)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      bounds(node.location)
      on_END(statements)
    end

END {} ^^^^^^

visit_pre_execution_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2715
    def visit_pre_execution_node(node)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      bounds(node.location)
      on_BEGIN(statements)
    end

BEGIN {} ^^^^^^^^

visit_program_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2729
    def visit_program_node(node)
      body = node.statements.body
      body << nil if body.empty?
      statements = visit_statements_node_body(body)

      bounds(node.location)
      on_program(statements)
    end

The top-level program node.

visit_range_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2740
    def visit_range_node(node)
      left = visit(node.left)
      right = visit(node.right)

      bounds(node.location)
      if node.exclude_end?
        on_dot3(left, right)
      else
        on_dot2(left, right)
      end
    end

0..5 ^^^^

visit_rational_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2754
    def visit_rational_node(node)
      visit_number_node(node) { |text| on_rational(text) }
    end

1r ^^

visit_redo_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2760
    def visit_redo_node(node)
      bounds(node.location)
      on_redo
    end

redo ^^^^

visit_regular_expression_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2767
    def visit_regular_expression_node(node)
      bounds(node.opening_loc)
      on_regexp_beg(node.opening)

      if node.content.empty?
        bounds(node.closing_loc)
        closing = on_regexp_end(node.closing)

        on_regexp_literal(on_regexp_new, closing)
      else
        bounds(node.content_loc)
        tstring_content = on_tstring_content(node.content)

        bounds(node.closing_loc)
        closing = on_regexp_end(node.closing)

        on_regexp_literal(on_regexp_add(on_regexp_new, tstring_content), closing)
      end
    end

/foo/ ^^^^^

visit_required_keyword_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2789
    def visit_required_keyword_parameter_node(node)
      bounds(node.name_loc)
      [on_label("#{node.name}:"), false]
    end

def foo(bar:); end ^^^^

visit_required_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2796
    def visit_required_parameter_node(node)
      bounds(node.location)
      on_ident(node.name.to_s)
    end

def foo(bar); end ^^^

visit_rescue_modifier_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2803
    def visit_rescue_modifier_node(node)
      expression = visit_write_value(node.expression)
      rescue_expression = visit(node.rescue_expression)

      bounds(node.location)
      on_rescue_mod(expression, rescue_expression)
    end

foo rescue bar ^^^^^^^^^^^^^^

visit_rescue_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2813
    def visit_rescue_node(node)
      exceptions =
        case node.exceptions.length
        when 0
          nil
        when 1
          if (exception = node.exceptions.first).is_a?(SplatNode)
            bounds(exception.location)
            on_mrhs_add_star(on_mrhs_new, visit(exception))
          else
            [visit(node.exceptions.first)]
          end
        else
          bounds(node.location)
          length = node.exceptions.length

          node.exceptions.each_with_index.inject(on_args_new) do |mrhs, (exception, index)|
            arg = visit(exception)

            bounds(exception.location)
            mrhs = on_mrhs_new_from_args(mrhs) if index == length - 1

            if exception.is_a?(SplatNode)
              if index == length - 1
                on_mrhs_add_star(mrhs, arg)
              else
                on_args_add_star(mrhs, arg)
              end
            else
              if index == length - 1
                on_mrhs_add(mrhs, arg)
              else
                on_args_add(mrhs, arg)
              end
            end
          end
        end

      reference = visit(node.reference)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      subsequent = visit(node.subsequent)

      bounds(node.location)
      on_rescue(exceptions, reference, statements, subsequent)
    end

begin; rescue; end ^^^^^^^

visit_rest_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2871
    def visit_rest_parameter_node(node)
      if node.name_loc.nil?
        bounds(node.location)
        on_rest_param(nil)
      else
        bounds(node.name_loc)
        on_rest_param(visit_token(node.name.to_s))
      end
    end

def foo(*bar); end ^^^^

def foo(*); end ^

visit_retry_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2883
    def visit_retry_node(node)
      bounds(node.location)
      on_retry
    end

retry ^^^^^

visit_return_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2893
    def visit_return_node(node)
      if node.arguments.nil?
        bounds(node.location)
        on_return0
      else
        arguments = visit(node.arguments)

        bounds(node.location)
        on_return(arguments)
      end
    end

return ^^^^^^

return 1 ^^^^^^^^

visit_self_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2907
    def visit_self_node(node)
      bounds(node.location)
      on_var_ref(on_kw("self"))
    end

self ^^^^

visit_shareable_constant_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2913
    def visit_shareable_constant_node(node)
      visit(node.write)
    end

A shareable constant.

visit_singleton_class_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2919
    def visit_singleton_class_node(node)
      expression = visit(node.expression)
      bodystmt = visit_body_node(node.body&.location || node.end_keyword_loc, node.body)

      bounds(node.location)
      on_sclass(expression, bodystmt)
    end

class << self; end ^^^^^^^^^^^^^^^^^^

visit_source_encoding_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2929
    def visit_source_encoding_node(node)
      bounds(node.location)
      on_var_ref(on_kw("__ENCODING__"))
    end

ENCODING ^^^^^^^^^^^^

visit_source_file_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2936
    def visit_source_file_node(node)
      bounds(node.location)
      on_var_ref(on_kw("__FILE__"))
    end

FILE ^^^^^^^^

visit_source_line_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2943
    def visit_source_line_node(node)
      bounds(node.location)
      on_var_ref(on_kw("__LINE__"))
    end

LINE ^^^^^^^^

visit_splat_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2956
    def visit_splat_node(node)
      visit(node.expression)
    end

foo(*bar) ^^^^

def foo((bar, *baz)); end ^^^^

def foo(); bar(); end ^

visit_statements_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2961
    def visit_statements_node(node)
      bounds(node.location)
      visit_statements_node_body(node.body)
    end

A list of statements.

visit_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2978
    def visit_string_node(node)
      if (content = node.content).empty?
        bounds(node.location)
        on_string_literal(on_string_content)
      elsif (opening = node.opening) == "?"
        bounds(node.location)
        on_CHAR("?#{node.content}")
      elsif opening.start_with?("<<~")
        heredoc = visit_heredoc_string_node(node.to_interpolated)

        bounds(node.location)
        on_string_literal(heredoc)
      else
        bounds(node.content_loc)
        tstring_content = on_tstring_content(content)

        bounds(node.location)
        on_string_literal(on_string_add(on_string_content, tstring_content))
      end
    end

“foo” ^^^^^

visit_super_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3110
    def visit_super_node(node)
      arguments, block = visit_call_node_arguments(node.arguments, node.block, trailing_comma?(node.arguments&.location || node.location, node.rparen_loc || node.location))

      if !node.lparen_loc.nil?
        bounds(node.lparen_loc)
        arguments = on_arg_paren(arguments)
      end

      bounds(node.location)
      call = on_super(arguments)

      if block.nil?
        call
      else
        bounds(node.block.location)
        on_method_add_block(call, block)
      end
    end

super(foo) ^^^^^^^^^^

visit_symbol_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3131
    def visit_symbol_node(node)
      if (opening = node.opening)&.match?(/^%s|['"]:?$/)
        bounds(node.value_loc)
        content = on_string_content

        if !(value = node.value).empty?
          content = on_string_add(content, on_tstring_content(value))
        end

        on_dyna_symbol(content)
      elsif (closing = node.closing) == ":"
        bounds(node.location)
        on_label("#{node.value}:")
      elsif opening.nil? && node.closing_loc.nil?
        bounds(node.value_loc)
        on_symbol_literal(visit_token(node.value))
      else
        bounds(node.value_loc)
        on_symbol_literal(on_symbol(visit_token(node.value)))
      end
    end

:foo ^^^^

visit_true_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3155
    def visit_true_node(node)
      bounds(node.location)
      on_var_ref(on_kw("true"))
    end

true ^^^^

visit_undef_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3162
    def visit_undef_node(node)
      names = visit_all(node.names)

      bounds(node.location)
      on_undef(names)
    end

undef foo ^^^^^^^^^

visit_unless_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3174
    def visit_unless_node(node)
      if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
        predicate = visit(node.predicate)
        statements =
          if node.statements.nil?
            bounds(node.location)
            on_stmts_add(on_stmts_new, on_void_stmt)
          else
            visit(node.statements)
          end
        else_clause = visit(node.else_clause)

        bounds(node.location)
        on_unless(predicate, statements, else_clause)
      else
        statements = visit(node.statements.body.first)
        predicate = visit(node.predicate)

        bounds(node.location)
        on_unless_mod(predicate, statements)
      end
    end

unless foo; bar end ^^^^^^^^^^^^^^^^^^^

bar unless foo ^^^^^^^^^^^^^^

visit_until_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3202
    def visit_until_node(node)
      if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
        predicate = visit(node.predicate)
        statements =
          if node.statements.nil?
            bounds(node.location)
            on_stmts_add(on_stmts_new, on_void_stmt)
          else
            visit(node.statements)
          end

        bounds(node.location)
        on_until(predicate, statements)
      else
        statements = visit(node.statements.body.first)
        predicate = visit(node.predicate)

        bounds(node.location)
        on_until_mod(predicate, statements)
      end
    end

until foo; bar end ^^^^^^^^^^^^^^^^^

bar until foo ^^^^^^^^^^^^^

visit_when_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3226
    def visit_when_node(node)
      # This is a special case where we're not going to call on_when directly
      # because we don't have access to the subsequent. Instead, we'll return
      # the component parts and let the parent node handle it.
      conditions = visit_arguments(node.conditions)
      statements =
        if node.statements.nil?
          bounds(node.location)
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          visit(node.statements)
        end

      [conditions, statements]
    end

case foo; when bar; end ^^^^^^^^^^^^^

visit_while_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3247
    def visit_while_node(node)
      if node.statements.nil? || (node.predicate.location.start_offset < node.statements.location.start_offset)
        predicate = visit(node.predicate)
        statements =
          if node.statements.nil?
            bounds(node.location)
            on_stmts_add(on_stmts_new, on_void_stmt)
          else
            visit(node.statements)
          end

        bounds(node.location)
        on_while(predicate, statements)
      else
        statements = visit(node.statements.body.first)
        predicate = visit(node.predicate)

        bounds(node.location)
        on_while_mod(predicate, statements)
      end
    end

while foo; bar end ^^^^^^^^^^^^^^^^^^

bar while foo ^^^^^^^^^^^^^

visit_x_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3271
    def visit_x_string_node(node)
      if node.unescaped.empty?
        bounds(node.location)
        on_xstring_literal(on_xstring_new)
      elsif node.opening.start_with?("<<~")
        heredoc = visit_heredoc_x_string_node(node.to_interpolated)

        bounds(node.location)
        on_xstring_literal(heredoc)
      else
        bounds(node.content_loc)
        content = on_tstring_content(node.content)

        bounds(node.location)
        on_xstring_literal(on_xstring_add(on_xstring_new, content))
      end
    end

`foo` ^^^^^

visit_yield_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3294
    def visit_yield_node(node)
      if node.arguments.nil? && node.lparen_loc.nil?
        bounds(node.location)
        on_yield0
      else
        arguments =
          if node.arguments.nil?
            bounds(node.location)
            on_args_new
          else
            visit(node.arguments)
          end

        unless node.lparen_loc.nil?
          bounds(node.lparen_loc)
          arguments = on_paren(arguments)
        end

        bounds(node.location)
        on_yield(arguments)
      end
    end

yield ^^^^^

yield 1 ^^^^^^^

### Private Instance Methods

bounds (location)
Source

    # File lib/prism/translation/ripper.rb, line 3424
    def bounds(location)
      @lineno = location.start_line
      @column = location.start_column
    end

This method is responsible for updating lineno and column information to reflect the current node.

This method could be drastically improved with some caching on the start of every line, but for now it’s good enough.

command? (node)
Source

    # File lib/prism/translation/ripper.rb, line 1197
            def command?(node)
      node.is_a?(CallNode) &&
        node.opening_loc.nil? &&
        (!node.arguments.nil? || node.block.is_a?(BlockArgumentNode)) &&
        !BINARY_OPERATORS.include?(node.name)
    end

Returns true if the given node is a command node.

compile_error (msg)
Source

    # File lib/prism/translation/ripper.rb, line 3462
    def compile_error(msg)
    end

This method is called when the parser found syntax error.

dedent_string (string, width)
Source

    # File lib/prism/translation/ripper.rb, line 3477
    def dedent_string(string, width)
      whitespace = 0
      cursor = 0

      while cursor < string.length && string[cursor].match?(/\s/) && whitespace < width
        if string[cursor] == "\t"
          whitespace = ((whitespace / 8 + 1) * 8)
          break if whitespace > width
        else
          whitespace += 1
        end

        cursor += 1
      end

      string.replace(string[cursor..])
      cursor
    end

This method is provided by the `Ripper` C extension. It is called when a string needs to be dedented because of a tilde heredoc. It is expected that it will modify the string in place and return the number of bytes that were removed.

result ()
Source

    # File lib/prism/translation/ripper.rb, line 3320
    def result
      @result ||= Prism.parse(source, partial_script: true, version: "current")
    end

Lazily initialize the parse result.

trailing_comma? (left, right)
Source

    # File lib/prism/translation/ripper.rb, line 3329
    def trailing_comma?(left, right)
      source.byteslice(left.end_offset...right.start_offset).include?(",")
    end

Returns true if there is a comma between the two locations.

visit_alias_global_variable_node_value (node)
Source

    # File lib/prism/translation/ripper.rb, line 594
            def visit_alias_global_variable_node_value(node)
      bounds(node.location)

      case node
      when BackReferenceReadNode
        on_backref(node.slice)
      when GlobalVariableReadNode
        on_gvar(node.name.to_s)
      else
        raise
      end
    end

Visit one side of an alias global variable node.

visit_arguments (elements)
Source

    # File lib/prism/translation/ripper.rb, line 780
            def visit_arguments(elements)
      bounds(elements.first.location)
      elements.inject(on_args_new) do |args, element|
        arg = visit(element)
        bounds(element.location)

        case element
        when BlockArgumentNode
          on_args_add_block(args, arg)
        when SplatNode
          on_args_add_star(args, arg)
        else
          on_args_add(args, arg)
        end
      end
    end

Visit a list of elements, like the elements of an array or arguments.

visit_begin_node_clauses (location, node, allow_newline)
Source

    # File lib/prism/translation/ripper.rb, line 864
            def visit_begin_node_clauses(location, node, allow_newline)
      statements =
        if node.statements.nil?
          on_stmts_add(on_stmts_new, on_void_stmt)
        else
          body = node.statements.body
          body.unshift(nil) if void_stmt?(location, node.statements.body[0].location, allow_newline)

          bounds(node.statements.location)
          visit_statements_node_body(body)
        end

      rescue_clause = visit(node.rescue_clause)
      else_clause =
        unless (else_clause_node = node.else_clause).nil?
          else_statements =
            if else_clause_node.statements.nil?
              [nil]
            else
              body = else_clause_node.statements.body
              body.unshift(nil) if void_stmt?(else_clause_node.else_keyword_loc, else_clause_node.statements.body[0].location, allow_newline)
              body
            end

          bounds(else_clause_node.location)
          visit_statements_node_body(else_statements)
        end
      ensure_clause = visit(node.ensure_clause)

      bounds(node.location)
      on_bodystmt(statements, rescue_clause, else_clause, ensure_clause)
    end

Visit the clauses of a begin node to form an on_bodystmt call.

visit_body_node (location, node, allow_newline = false)
Source

    # File lib/prism/translation/ripper.rb, line 899
            def visit_body_node(location, node, allow_newline = false)
      case node
      when nil
        bounds(location)
        on_bodystmt(visit_statements_node_body([nil]), nil, nil, nil)
      when StatementsNode
        body = [*node.body]
        body.unshift(nil) if void_stmt?(location, body[0].location, allow_newline)
        stmts = visit_statements_node_body(body)

        bounds(node.body.first.location)
        on_bodystmt(stmts, nil, nil, nil)
      when BeginNode
        visit_begin_node_clauses(location, node, allow_newline)
      else
        raise
      end
    end

Visit the body of a structure that can have either a set of statements or statements wrapped in rescue/else/ensure.

visit_call_node_arguments (arguments_node, block_node, trailing_comma)
Source

    # File lib/prism/translation/ripper.rb, line 1170
            def visit_call_node_arguments(arguments_node, block_node, trailing_comma)
      arguments = arguments_node&.arguments || []
      block = block_node

      if block.is_a?(BlockArgumentNode)
        arguments << block
        block = nil
      end

      [
        if arguments.length == 1 && arguments.first.is_a?(ForwardingArgumentsNode)
          visit(arguments.first)
        elsif arguments.any?
          args = visit_arguments(arguments)

          if block_node.is_a?(BlockArgumentNode) || arguments.last.is_a?(ForwardingArgumentsNode) || command?(arguments.last) || trailing_comma
            args
          else
            bounds(arguments.first.location)
            on_args_add_block(args, false)
          end
        end,
        visit(block)
      ]
    end

Visit the arguments and block of a call node and return the arguments and block as they should be used.

visit_constant_path_write_node_target (node)
Source

    # File lib/prism/translation/ripper.rb, line 1523
            def visit_constant_path_write_node_target(node)
      if node.parent.nil?
        bounds(node.name_loc)
        child = on_const(node.name.to_s)

        bounds(node.location)
        on_top_const_field(child)
      else
        parent = visit(node.parent)

        bounds(node.name_loc)
        child = on_const(node.name.to_s)

        bounds(node.location)
        on_const_path_field(parent, child)
      end
    end

Visit a constant path that is part of a write node.

visit_destructured_parameter_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 2658
            def visit_destructured_parameter_node(node)
      bounds(node.location)
      targets = visit_multi_target_node_targets(node.lefts, node.rest, node.rights, false)

      bounds(node.lparen_loc)
      on_mlhs_paren(targets)
    end

Visit a destructured positional parameter node.

visit_heredoc_node (parts, base) { |result, on_tstring_content(map(&:content).join)| ... }
Source

    # File lib/prism/translation/ripper.rb, line 3029
            def visit_heredoc_node(parts, base)
      common_whitespace = visit_heredoc_node_whitespace(parts)

      if common_whitespace == 0
        bounds(parts.first.location)

        string = []
        result = base

        parts.each do |part|
          if part.is_a?(StringNode)
            if string.empty?
              string = [part]
            else
              string << part
            end
          else
            unless string.empty?
              bounds(string[0].location)
              result = yield result, on_tstring_content(string.map(&:content).join)
              string = []
            end

            result = yield result, visit(part)
          end
        end

        unless string.empty?
          bounds(string[0].location)
          result = yield result, on_tstring_content(string.map(&:content).join)
        end

        result
      else
        bounds(parts.first.location)
        result =
          parts.inject(base) do |string_content, part|
            yield string_content, visit_string_content(part)
          end

        bounds(parts.first.location)
        on_heredoc_dedent(result, common_whitespace)
      end
    end

Visit a string that is expressed using a <<~ heredoc.

visit_heredoc_node_whitespace (parts)
Source

    # File lib/prism/translation/ripper.rb, line 3004
            def visit_heredoc_node_whitespace(parts)
      common_whitespace = nil
      dedent_next = true

      parts.each do |part|
        if part.is_a?(StringNode)
          if dedent_next && !(content = part.content).chomp.empty?
            common_whitespace = [
              common_whitespace || Float::INFINITY,
              content[/\A\s*/].each_char.inject(0) do |part_whitespace, char|
                char == "\t" ? ((part_whitespace / 8 + 1) * 8) : (part_whitespace + 1)
              end
            ].min
          end

          dedent_next = true
        else
          dedent_next = false
        end
      end

      common_whitespace || 0
    end

`Ripper` gives back the escaped string content but strips out the common leading whitespace. `Prism` gives back the unescaped string content and a location for the escaped string content. Unfortunately these don’t work well together, so here we need to re-derive the common leading whitespace.

visit_heredoc_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3075
            def visit_heredoc_string_node(node)
      bounds(node.opening_loc)
      on_heredoc_beg(node.opening)

      bounds(node.location)
      result =
        visit_heredoc_node(node.parts, on_string_content) do |parts, part|
          on_string_add(parts, part)
        end

      bounds(node.closing_loc)
      on_heredoc_end(node.closing)

      result
    end

Visit a heredoc node that is representing a string.

visit_heredoc_x_string_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 3092
            def visit_heredoc_x_string_node(node)
      bounds(node.opening_loc)
      on_heredoc_beg(node.opening)

      bounds(node.location)
      result =
        visit_heredoc_node(node.parts, on_xstring_new) do |parts, part|
          on_xstring_add(parts, part)
        end

      bounds(node.closing_loc)
      on_heredoc_end(node.closing)

      result
    end

Visit a heredoc node that is representing an xstring.

visit_multi_target_node_targets (lefts, rest, rights, skippable)
Source

    # File lib/prism/translation/ripper.rb, line 2511
            def visit_multi_target_node_targets(lefts, rest, rights, skippable)
      if skippable && lefts.length == 1 && lefts.first.is_a?(MultiTargetNode) && rest.nil? && rights.empty?
        return visit(lefts.first)
      end

      mlhs = on_mlhs_new

      lefts.each do |left|
        bounds(left.location)
        mlhs = on_mlhs_add(mlhs, visit(left))
      end

      case rest
      when nil
        # do nothing
      when ImplicitRestNode
        # these do not get put into the generated tree
        bounds(rest.location)
        on_excessed_comma
      else
        bounds(rest.location)
        mlhs = on_mlhs_add_star(mlhs, visit(rest))
      end

      if rights.any?
        bounds(rights.first.location)
        post = on_mlhs_new

        rights.each do |right|
          bounds(right.location)
          post = on_mlhs_add(post, visit(right))
        end

        mlhs = on_mlhs_add_post(mlhs, post)
      end

      mlhs
    end

Visit the targets of a multi-target node.

visit_number_node (node) { |slice| ... }
Source

    # File lib/prism/translation/ripper.rb, line 3368
    def visit_number_node(node)
      slice = node.slice
      location = node.location

      if slice[0] == "-"
        bounds(location.copy(start_offset: location.start_offset + 1))
        value = yield slice[1..-1]

        bounds(node.location)
        on_unary(:-@, value)
      else
        bounds(location)
        yield slice
      end
    end

Visit a node that represents a number. We need to explicitly handle the unary - operator.

visit_pattern_node (node)
Source

    # File lib/prism/translation/ripper.rb, line 619
            def visit_pattern_node(node)
      if node.is_a?(ParenthesesNode)
        visit(node.body)
      else
        visit(node)
      end
    end

Visit a pattern within a pattern match. This is used to bypass the parenthesis node that can be used to wrap patterns.

visit_statements_node_body (body)
Source

    # File lib/prism/translation/ripper.rb, line 2970
            def visit_statements_node_body(body)
      body.inject(on_stmts_new) do |stmts, stmt|
        on_stmts_add(stmts, stmt.nil? ? on_void_stmt : visit(stmt))
      end
    end

Visit the list of statements of a statements node. We support nil statements in the list. This would normally not be allowed by the structure of the prism parse tree, but we manually add them here so that we can mirror Ripper’s void stmt.

visit_string_content (part)
Source

    # File lib/prism/translation/ripper.rb, line 2260
            def visit_string_content(part)
      if part.is_a?(StringNode)
        bounds(part.content_loc)
        on_tstring_content(part.content)
      else
        visit(part)
      end
    end

Visit an individual part of a string-like node.

visit_token (token, allow_keywords = true)
Source

    # File lib/prism/translation/ripper.rb, line 3341
    def visit_token(token, allow_keywords = true)
      case token
      when "."
        on_period(token)
      when "`"
        on_backtick(token)
      when *(allow_keywords ? KEYWORDS : [])
        on_kw(token)
      when /^_/
        on_ident(token)
      when /^[[:upper:]]\w*$/
        on_const(token)
      when /^@@/
        on_cvar(token)
      when /^@/
        on_ivar(token)
      when /^\$/
        on_gvar(token)
      when /^[[:punct:]]/
        on_op(token)
      else
        on_ident(token)
      end
    end

Visit the string content of a particular node. This method is used to split into the various token types.

visit_words_sep (opening_loc, previous, current)
Source

    # File lib/prism/translation/ripper.rb, line 769
            def visit_words_sep(opening_loc, previous, current)
      end_offset = (previous.nil? ? opening_loc : previous.location).end_offset
      start_offset = current.location.start_offset

      if end_offset != start_offset
        bounds(current.location.copy(start_offset: end_offset))
        on_words_sep(source.byteslice(end_offset...start_offset))
      end
    end

Dispatch a words_sep event that contains the space between the elements of list literals.

visit_write_value (node)
Source

    # File lib/prism/translation/ripper.rb, line 3386
    def visit_write_value(node)
      if node.is_a?(ArrayNode) && node.opening_loc.nil?
        elements = node.elements
        length = elements.length

        bounds(elements.first.location)
        elements.each_with_index.inject((elements.first.is_a?(SplatNode) && length == 1) ? on_mrhs_new : on_args_new) do |args, (element, index)|
          arg = visit(element)
          bounds(element.location)

          if index == length - 1
            if element.is_a?(SplatNode)
              mrhs = index == 0 ? args : on_mrhs_new_from_args(args)
              on_mrhs_add_star(mrhs, arg)
            else
              on_mrhs_add(on_mrhs_new_from_args(args), arg)
            end
          else
            case element
            when BlockArgumentNode
              on_args_add_block(args, arg)
            when SplatNode
              on_args_add_star(args, arg)
            else
              on_args_add(args, arg)
            end
          end
        end
      else
        visit(node)
      end
    end

Visit a node that represents a write value. This is used to handle the special case of an implicit array that is generated without brackets.

void_stmt? (left, right, allow_newline)
Source

    # File lib/prism/translation/ripper.rb, line 3334
    def void_stmt?(left, right, allow_newline)
      pattern = allow_newline ? /[;\n]/ : /;/
      source.byteslice(left.end_offset...right.start_offset).match?(pattern)
    end

Returns true if there is a semicolon between the two locations.

warn (fmt, *args)
Source

    # File lib/prism/translation/ripper.rb, line 3453
    def warn(fmt, *args)
    end

This method is called when weak warning is produced by the parser. `fmt` and `args` is printf style.

warning (fmt, *args)
Source

    # File lib/prism/translation/ripper.rb, line 3458
    def warning(fmt, *args)
    end

This method is called when strong warning is produced by the parser. `fmt` and `args` is printf style.