summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJemma Issroff <jemmaissroff@gmail.com>2023-06-20 11:53:02 -0400
committerTakashi Kokubun <takashikkbn@gmail.com>2023-06-21 11:25:39 -0700
commitcc7f765f2c12a9ba050b0d95f9d85f3923c8d944 (patch)
tree5b5c60c1950240900dc749773083324a0e39748a /lib
parent08478fefca827276d68e33f2e6a5940c85957a51 (diff)
[Feature #19741] Sync all files in yarp
This commit is the initial sync of all files from ruby/yarp into ruby/ruby. Notably, it does the following: * Sync all ruby/yarp/lib/ files to ruby/ruby/lib/yarp * Sync all ruby/yarp/src/ files to ruby/ruby/yarp/ * Sync all ruby/yarp/test/ files to ruby/ruby/test/yarp
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/7964
Diffstat (limited to 'lib')
-rw-r--r--lib/yarp.rb248
-rw-r--r--lib/yarp/language_server.rb166
-rw-r--r--lib/yarp/lex_compat.rb749
-rw-r--r--lib/yarp/node.rb6434
-rw-r--r--lib/yarp/pack.rb185
-rw-r--r--lib/yarp/ripper_compat.rb174
-rw-r--r--lib/yarp/serialize.rb367
7 files changed, 8323 insertions, 0 deletions
diff --git a/lib/yarp.rb b/lib/yarp.rb
new file mode 100644
index 0000000000..dd790434cc
--- /dev/null
+++ b/lib/yarp.rb
@@ -0,0 +1,248 @@
+# frozen_string_literal: true
+
+module YARP
+ # This represents a location in the source corresponding to a node or token.
+ class Location
+ attr_reader :start_offset, :length
+
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ def end_offset
+ @start_offset + @length
+ end
+
+ def deconstruct_keys(keys)
+ { start_offset: start_offset, end_offset: end_offset }
+ end
+
+ def pretty_print(q)
+ q.text("(#{start_offset}...#{end_offset})")
+ end
+
+ def ==(other)
+ other in Location[start_offset: ^(start_offset), end_offset: ^(end_offset)]
+ end
+
+ def self.null
+ new(0, 0)
+ end
+ end
+
+ # This represents a comment that was encountered during parsing.
+ class Comment
+ attr_reader :type, :location
+
+ def initialize(type, location)
+ @type = type
+ @location = location
+ end
+
+ def deconstruct_keys(keys)
+ { type: type, location: location }
+ end
+ end
+
+ # This represents an error that was encountered during parsing.
+ class ParseError
+ attr_reader :message, :location
+
+ def initialize(message, location)
+ @message = message
+ @location = location
+ end
+
+ def deconstruct_keys(keys)
+ { message: message, location: location }
+ end
+ end
+
+ # This represents a warning that was encountered during parsing.
+ class ParseWarning
+ attr_reader :message, :location
+
+ def initialize(message, location)
+ @message = message
+ @location = location
+ end
+
+ def deconstruct_keys(keys)
+ { message: message, location: location }
+ end
+ end
+
+ # This represents the result of a call to ::parse or ::parse_file. It contains
+ # the AST, any comments that were encounters, and any errors that were
+ # encountered.
+ class ParseResult
+ attr_reader :value, :comments, :errors, :warnings
+
+ def initialize(value, comments, errors, warnings)
+ @value = value
+ @comments = comments
+ @errors = errors
+ @warnings = warnings
+ end
+
+ def deconstruct_keys(keys)
+ { value: value, comments: comments, errors: errors, warnings: warnings }
+ end
+
+ def success?
+ errors.empty?
+ end
+
+ def failure?
+ !success?
+ end
+ end
+
+ # This represents a token from the Ruby source.
+ class Token
+ attr_reader :type, :value, :start_offset, :length
+
+ def initialize(type, value, start_offset, length)
+ @type = type
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ def end_offset
+ @start_offset + @length
+ end
+
+ def location
+ Location.new(@start_offset, @length)
+ end
+
+ def deconstruct_keys(keys)
+ { type: type, value: value, location: location }
+ end
+
+ def pretty_print(q)
+ q.group do
+ q.text(type.to_s)
+ self.location.pretty_print(q)
+ q.text("(")
+ q.nest(2) do
+ q.breakable("")
+ q.pp(value)
+ end
+ q.breakable("")
+ q.text(")")
+ end
+ end
+
+ def ==(other)
+ other in Token[type: ^(type), value: ^(value)]
+ end
+ end
+
+ # This represents a node in the tree.
+ class Node
+ attr_reader :start_offset, :length
+
+ def end_offset
+ @start_offset + @length
+ end
+
+ def location
+ Location.new(@start_offset, @length)
+ end
+
+ def pretty_print(q)
+ q.group do
+ q.text(self.class.name.split("::").last)
+ self.location.pretty_print(q)
+ q.text("(")
+ q.nest(2) do
+ deconstructed = deconstruct_keys([])
+ deconstructed.delete(:location)
+
+ q.breakable("")
+ q.seplist(deconstructed, lambda { q.comma_breakable }, :each_value) { |value| q.pp(value) }
+ end
+ q.breakable("")
+ q.text(")")
+ end
+ end
+ end
+
+ # A class that knows how to walk down the tree. None of the individual visit
+ # methods are implemented on this visitor, so it forces the consumer to
+ # implement each one that they need. For a default implementation that
+ # continues walking the tree, see the Visitor class.
+ class BasicVisitor
+ def visit(node)
+ node&.accept(self)
+ end
+
+ def visit_all(nodes)
+ nodes.map { |node| visit(node) }
+ end
+
+ def visit_child_nodes(node)
+ visit_all(node.child_nodes)
+ end
+ end
+
+ # This lexes with the Ripper lex. It drops any space events but otherwise
+ # returns the same tokens.
+ # [raises SyntaxError] if the syntax in source is invalid
+ def self.lex_ripper(source)
+ previous = []
+ results = []
+
+ Ripper.lex(source, raise_errors: true).each do |token|
+ case token[1]
+ when :on_sp
+ # skip
+ when :on_tstring_content
+ if previous[1] == :on_tstring_content &&
+ (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
+ previous[2] << token[2]
+ else
+ results << token
+ previous = token
+ end
+ when :on_words_sep
+ if previous[1] == :on_words_sep
+ previous[2] << token[2]
+ else
+ results << token
+ previous = token
+ end
+ else
+ results << token
+ previous = token
+ end
+ end
+
+ results
+ end
+
+ # Load the serialized AST using the source as a reference into a tree.
+ def self.load(source, serialized)
+ Serialize.load(source, serialized)
+ end
+
+ def self.parse(source, filepath=nil)
+ _parse(source, filepath)
+ end
+end
+
+require_relative "yarp/lex_compat"
+require_relative "yarp/node"
+require_relative "yarp/ripper_compat"
+require_relative "yarp/serialize"
+require_relative "yarp/pack"
+require "yarp.so"
+
+module YARP
+ class << self
+ private :_parse
+ end
+end
diff --git a/lib/yarp/language_server.rb b/lib/yarp/language_server.rb
new file mode 100644
index 0000000000..5a10d484a1
--- /dev/null
+++ b/lib/yarp/language_server.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require "cgi"
+require "json"
+require "uri"
+
+module YARP
+ # YARP additionally ships with a language server conforming to the
+ # language server protocol. It can be invoked by running the yarp-lsp
+ # bin script (bin/yarp-lsp)
+ class LanguageServer
+ GITHUB_TEMPLATE = <<~TEMPLATE
+ Reporting issue with error `%{error}`.
+
+ ## Expected behavior
+ <!-- TODO: Briefly explain what the expected behavior should be on this example. -->
+
+ ## Actual behavior
+ <!-- TODO: Describe here what actually happened. -->
+
+ ## Steps to reproduce the problem
+ <!-- TODO: Describe how we can reproduce the problem. -->
+
+ ## Additional information
+ <!-- TODO: Include any additional information, such as screenshots. -->
+
+ TEMPLATE
+
+ attr_reader :input, :output
+
+ def initialize(
+ input: $stdin,
+ output: $stdout
+ )
+ @input = input.binmode
+ @output = output.binmode
+ end
+
+ # rubocop:disable Layout/LineLength
+ def run
+ store =
+ Hash.new do |hash, uri|
+ filepath = CGI.unescape(URI.parse(uri).path)
+ File.exist?(filepath) ? (hash[uri] = File.read(filepath)) : nil
+ end
+
+ while (headers = input.gets("\r\n\r\n"))
+ source = input.read(headers[/Content-Length: (\d+)/i, 1].to_i)
+ request = JSON.parse(source, symbolize_names: true)
+
+ # stree-ignore
+ case request
+ in { method: "initialize", id: }
+ store.clear
+ write(id: id, result: { capabilities: capabilities })
+ in { method: "initialized" }
+ # ignored
+ in { method: "shutdown" } # tolerate missing ID to be a good citizen
+ store.clear
+ write(id: request[:id], result: {})
+ in { method: "exit"}
+ return
+ in { method: "textDocument/didChange", params: { textDocument: { uri: }, contentChanges: [{ text: }, *] } }
+ store[uri] = text
+ in { method: "textDocument/didOpen", params: { textDocument: { uri:, text: } } }
+ store[uri] = text
+ in { method: "textDocument/didClose", params: { textDocument: { uri: } } }
+ store.delete(uri)
+ in { method: "textDocument/diagnostic", id:, params: { textDocument: { uri: } } }
+ contents = store[uri]
+ write(id: id, result: contents ? diagnostics(contents) : nil)
+ in { method: "textDocument/codeAction", id:, params: { textDocument: { uri: }, context: { diagnostics: }}}
+ contents = store[uri]
+ write(id: id, result: contents ? code_actions(contents, diagnostics) : nil)
+ in { method: %r{\$/.+} }
+ # ignored
+ end
+ end
+ end
+ # rubocop:enable Layout/LineLength
+
+ private
+
+ def capabilities
+ {
+ codeActionProvider: {
+ codeActionKinds: [
+ 'quickfix',
+ ],
+ },
+ diagnosticProvider: {
+ interFileDependencies: false,
+ workspaceDiagnostics: false,
+ },
+ textDocumentSync: {
+ change: 1,
+ openClose: true
+ },
+ }
+ end
+
+ def code_actions(source, diagnostics)
+ diagnostics.map do |diagnostic|
+ message = diagnostic[:message]
+ issue_content = URI.encode_www_form_component(GITHUB_TEMPLATE % {error: message})
+ issue_link = "https://github.com/ruby/yarp/issues/new?&labels=Bug&body=#{issue_content}"
+
+ {
+ title: "Report incorrect error: `#{diagnostic[:message]}`",
+ kind: "quickfix",
+ diagnostics: [diagnostic],
+ command: {
+ title: "Report incorrect error",
+ command: "vscode.open",
+ arguments: [issue_link]
+ }
+ }
+ end
+ end
+
+ def diagnostics(source)
+ offsets = Hash.new do |hash, key|
+ slice = source.byteslice(...key)
+ lineno = slice.count("\n")
+
+ char = slice.length
+ newline = source.rindex("\n", [char - 1, 0].max) || -1
+ hash[key] = { line: lineno, character: char - newline - 1 }
+ end
+
+ parse_output = YARP.parse(source)
+
+ {
+ kind: "full",
+ items: [
+ *parse_output.errors.map do |error|
+ {
+ range: {
+ start: offsets[error.location.start_offset],
+ end: offsets[error.location.end_offset],
+ },
+ message: error.message,
+ severity: 1,
+ }
+ end,
+ *parse_output.warnings.map do |warning|
+ {
+ range: {
+ start: offsets[warning.location.start_offset],
+ end: offsets[warning.location.end_offset],
+ },
+ message: warning.message,
+ severity: 2,
+ }
+ end,
+ ]
+ }
+ end
+
+ def write(value)
+ response = value.merge(jsonrpc: "2.0").to_json
+ output.print("Content-Length: #{response.bytesize}\r\n\r\n#{response}")
+ output.flush
+ end
+ end
+end
diff --git a/lib/yarp/lex_compat.rb b/lib/yarp/lex_compat.rb
new file mode 100644
index 0000000000..a72f8c0aeb
--- /dev/null
+++ b/lib/yarp/lex_compat.rb
@@ -0,0 +1,749 @@
+# frozen_string_literal: true
+
+require "delegate"
+
+module YARP
+ # This class is responsible for lexing the source using YARP and then
+ # converting those tokens to be compatible with Ripper. In the vast majority
+ # of cases, this is a one-to-one mapping of the token type. Everything else
+ # generally lines up. However, there are a few cases that require special
+ # handling.
+ class LexCompat
+ # This is a mapping of YARP token types to Ripper token types. This is a
+ # many-to-one mapping because we split up our token types, whereas Ripper
+ # tends to group them.
+ RIPPER = {
+ AMPERSAND: :on_op,
+ AMPERSAND_AMPERSAND: :on_op,
+ AMPERSAND_AMPERSAND_EQUAL: :on_op,
+ AMPERSAND_DOT: :on_op,
+ AMPERSAND_EQUAL: :on_op,
+ BACK_REFERENCE: :on_backref,
+ BACKTICK: :on_backtick,
+ BANG: :on_op,
+ BANG_EQUAL: :on_op,
+ BANG_TILDE: :on_op,
+ BRACE_LEFT: :on_lbrace,
+ BRACE_RIGHT: :on_rbrace,
+ BRACKET_LEFT: :on_lbracket,
+ BRACKET_LEFT_ARRAY: :on_lbracket,
+ BRACKET_LEFT_RIGHT: :on_op,
+ BRACKET_LEFT_RIGHT_EQUAL: :on_op,
+ BRACKET_RIGHT: :on_rbracket,
+ CARET: :on_op,
+ CARET_EQUAL: :on_op,
+ CHARACTER_LITERAL: :on_CHAR,
+ CLASS_VARIABLE: :on_cvar,
+ COLON: :on_op,
+ COLON_COLON: :on_op,
+ COMMA: :on_comma,
+ COMMENT: :on_comment,
+ CONSTANT: :on_const,
+ DOT: :on_period,
+ DOT_DOT: :on_op,
+ DOT_DOT_DOT: :on_op,
+ EMBDOC_BEGIN: :on_embdoc_beg,
+ EMBDOC_END: :on_embdoc_end,
+ EMBDOC_LINE: :on_embdoc,
+ EMBEXPR_BEGIN: :on_embexpr_beg,
+ EMBEXPR_END: :on_embexpr_end,
+ EMBVAR: :on_embvar,
+ EOF: :on_eof,
+ EQUAL: :on_op,
+ EQUAL_EQUAL: :on_op,
+ EQUAL_EQUAL_EQUAL: :on_op,
+ EQUAL_GREATER: :on_op,
+ EQUAL_TILDE: :on_op,
+ FLOAT: :on_float,
+ GREATER: :on_op,
+ GREATER_EQUAL: :on_op,
+ GREATER_GREATER: :on_op,
+ GREATER_GREATER_EQUAL: :on_op,
+ GLOBAL_VARIABLE: :on_gvar,
+ HEREDOC_END: :on_heredoc_end,
+ HEREDOC_START: :on_heredoc_beg,
+ IDENTIFIER: :on_ident,
+ IGNORED_NEWLINE: :on_ignored_nl,
+ IMAGINARY_NUMBER: :on_imaginary,
+ INTEGER: :on_int,
+ INSTANCE_VARIABLE: :on_ivar,
+ INVALID: :INVALID,
+ KEYWORD___ENCODING__: :on_kw,
+ KEYWORD___LINE__: :on_kw,
+ KEYWORD___FILE__: :on_kw,
+ KEYWORD_ALIAS: :on_kw,
+ KEYWORD_AND: :on_kw,
+ KEYWORD_BEGIN: :on_kw,
+ KEYWORD_BEGIN_UPCASE: :on_kw,
+ KEYWORD_BREAK: :on_kw,
+ KEYWORD_CASE: :on_kw,
+ KEYWORD_CLASS: :on_kw,
+ KEYWORD_DEF: :on_kw,
+ KEYWORD_DEFINED: :on_kw,
+ KEYWORD_DO: :on_kw,
+ KEYWORD_DO_LOOP: :on_kw,
+ KEYWORD_ELSE: :on_kw,
+ KEYWORD_ELSIF: :on_kw,
+ KEYWORD_END: :on_kw,
+ KEYWORD_END_UPCASE: :on_kw,
+ KEYWORD_ENSURE: :on_kw,
+ KEYWORD_FALSE: :on_kw,
+ KEYWORD_FOR: :on_kw,
+ KEYWORD_IF: :on_kw,
+ KEYWORD_IF_MODIFIER: :on_kw,
+ KEYWORD_IN: :on_kw,
+ KEYWORD_MODULE: :on_kw,
+ KEYWORD_NEXT: :on_kw,
+ KEYWORD_NIL: :on_kw,
+ KEYWORD_NOT: :on_kw,
+ KEYWORD_OR: :on_kw,
+ KEYWORD_REDO: :on_kw,
+ KEYWORD_RESCUE: :on_kw,
+ KEYWORD_RESCUE_MODIFIER: :on_kw,
+ KEYWORD_RETRY: :on_kw,
+ KEYWORD_RETURN: :on_kw,
+ KEYWORD_SELF: :on_kw,
+ KEYWORD_SUPER: :on_kw,
+ KEYWORD_THEN: :on_kw,
+ KEYWORD_TRUE: :on_kw,
+ KEYWORD_UNDEF: :on_kw,
+ KEYWORD_UNLESS: :on_kw,
+ KEYWORD_UNLESS_MODIFIER: :on_kw,
+ KEYWORD_UNTIL: :on_kw,
+ KEYWORD_UNTIL_MODIFIER: :on_kw,
+ KEYWORD_WHEN: :on_kw,
+ KEYWORD_WHILE: :on_kw,
+ KEYWORD_WHILE_MODIFIER: :on_kw,
+ KEYWORD_YIELD: :on_kw,
+ LABEL: :on_label,
+ LABEL_END: :on_label_end,
+ LAMBDA_BEGIN: :on_tlambeg,
+ LESS: :on_op,
+ LESS_EQUAL: :on_op,
+ LESS_EQUAL_GREATER: :on_op,
+ LESS_LESS: :on_op,
+ LESS_LESS_EQUAL: :on_op,
+ MINUS: :on_op,
+ MINUS_EQUAL: :on_op,
+ MINUS_GREATER: :on_tlambda,
+ NEWLINE: :on_nl,
+ NUMBERED_REFERENCE: :on_backref,
+ PARENTHESIS_LEFT: :on_lparen,
+ PARENTHESIS_LEFT_PARENTHESES: :on_lparen,
+ PARENTHESIS_RIGHT: :on_rparen,
+ PERCENT: :on_op,
+ PERCENT_EQUAL: :on_op,
+ PERCENT_LOWER_I: :on_qsymbols_beg,
+ PERCENT_LOWER_W: :on_qwords_beg,
+ PERCENT_LOWER_X: :on_backtick,
+ PERCENT_UPPER_I: :on_symbols_beg,
+ PERCENT_UPPER_W: :on_words_beg,
+ PIPE: :on_op,
+ PIPE_EQUAL: :on_op,
+ PIPE_PIPE: :on_op,
+ PIPE_PIPE_EQUAL: :on_op,
+ PLUS: :on_op,
+ PLUS_EQUAL: :on_op,
+ QUESTION_MARK: :on_op,
+ RATIONAL_NUMBER: :on_rational,
+ REGEXP_BEGIN: :on_regexp_beg,
+ REGEXP_END: :on_regexp_end,
+ SEMICOLON: :on_semicolon,
+ SLASH: :on_op,
+ SLASH_EQUAL: :on_op,
+ STAR: :on_op,
+ STAR_EQUAL: :on_op,
+ STAR_STAR: :on_op,
+ STAR_STAR_EQUAL: :on_op,
+ STRING_BEGIN: :on_tstring_beg,
+ STRING_CONTENT: :on_tstring_content,
+ STRING_END: :on_tstring_end,
+ SYMBOL_BEGIN: :on_symbeg,
+ TILDE: :on_op,
+ UCOLON_COLON: :on_op,
+ UDOT_DOT: :on_op,
+ UDOT_DOT_DOT: :on_op,
+ UMINUS: :on_op,
+ UMINUS_NUM: :on_op,
+ UPLUS: :on_op,
+ USTAR: :on_op,
+ USTAR_STAR: :on_op,
+ WORDS_SEP: :on_words_sep,
+ __END__: :on___end__
+ }.freeze
+
+ # When we produce tokens, we produce the same arrays that Ripper does.
+ # However, we add a couple of convenience methods onto them to make them a
+ # little easier to work with. We delegate all other methods to the array.
+ class Token < SimpleDelegator
+ def location
+ self[0]
+ end
+
+ def event
+ self[1]
+ end
+
+ def value
+ self[2]
+ end
+
+ def state
+ self[3]
+ end
+ end
+
+ # Ripper doesn't include the rest of the token in the event, so we need to
+ # trim it down to just the content on the first line when comparing.
+ class EndContentToken < Token
+ def ==(other)
+ [self[0], self[1], self[2][0..self[2].index("\n")], self[3]] == other
+ end
+ end
+
+ # It is extremely non obvious which state the parser is in when comments get
+ # dispatched. Because of this we don't both comparing state when comparing
+ # against other comment tokens.
+ class CommentToken < Token
+ def ==(other)
+ self[0...-1] == other[0...-1]
+ end
+ end
+
+ # Heredoc end tokens are emitted in an odd order, so we don't compare the
+ # state on them.
+ class HeredocEndToken < Token
+ def ==(other)
+ self[0...-1] == other[0...-1]
+ end
+ end
+
+ # Ident tokens for the most part are exactly the same, except sometimes we
+ # know an ident is a local when ripper doesn't (when they are introduced
+ # through named captures in regular expressions). In that case we don't
+ # compare the state.
+ class IdentToken < Token
+ def ==(other)
+ (self[0...-1] == other[0...-1]) && (
+ (other[3] == Ripper::EXPR_LABEL | Ripper::EXPR_END) ||
+ (other[3] & Ripper::EXPR_ARG_ANY != 0)
+ )
+ end
+ end
+
+ # Ignored newlines can occasionally have a LABEL state attached to them, so
+ # we compare the state differently here.
+ class IgnoredNewlineToken < Token
+ def ==(other)
+ return false unless self[0...-1] == other[0...-1]
+
+ if self[4] == Ripper::EXPR_ARG | Ripper::EXPR_LABELED
+ other[4] & Ripper::EXPR_ARG | Ripper::EXPR_LABELED > 0
+ else
+ self[4] == other[4]
+ end
+ end
+ end
+
+ # A heredoc in this case is a list of tokens that belong to the body of the
+ # heredoc that should be appended onto the list of tokens when the heredoc
+ # closes.
+ module Heredoc
+ # Heredocs that are no dash or tilde heredocs are just a list of tokens.
+ # We need to keep them around so that we can insert them in the correct
+ # order back into the token stream and set the state of the last token to
+ # the state that the heredoc was opened in.
+ class PlainHeredoc
+ attr_reader :tokens
+
+ def initialize
+ @tokens = []
+ end
+
+ def <<(token)
+ tokens << token
+ end
+
+ def to_a
+ tokens
+ end
+ end
+
+ # Dash heredocs are a little more complicated. They are a list of tokens
+ # that need to be split on "\\\n" to mimic Ripper's behavior. We also need
+ # to keep track of the state that the heredoc was opened in.
+ class DashHeredoc
+ attr_reader :split, :tokens
+
+ def initialize(split)
+ @split = split
+ @tokens = []
+ end
+
+ def <<(token)
+ tokens << token
+ end
+
+ def to_a
+ embexpr_balance = 0
+
+ tokens.each_with_object([]) do |token, results|
+ case token.event
+ when :on_embexpr_beg
+ embexpr_balance += 1
+ results << token
+ when :on_embexpr_end
+ embexpr_balance -= 1
+ results << token
+ when :on_tstring_content
+ if embexpr_balance == 0
+ lineno = token[0][0]
+ column = token[0][1]
+
+ if split
+ # Split on "\\\n" to mimic Ripper's behavior. Use a lookbehind
+ # to keep the delimiter in the result.
+ token.value.split(/(?<=[^\\]\\\n)|(?<=[^\\]\\\r\n)/).each_with_index do |value, index|
+ column = 0 if index > 0
+ results << Token.new([[lineno, column], :on_tstring_content, value, token.state])
+ lineno += value.count("\n")
+ end
+ else
+ results << token
+ end
+ else
+ results << token
+ end
+ else
+ results << token
+ end
+ end
+ end
+ end
+
+ # Heredocs that are dedenting heredocs are a little more complicated.
+ # Ripper outputs on_ignored_sp tokens for the whitespace that is being
+ # removed from the output. YARP only modifies the node itself and keeps
+ # the token the same. This simplifies YARP, but makes comparing against
+ # Ripper much harder because there is a length mismatch.
+ #
+ # Fortunately, we already have to pull out the heredoc tokens in order to
+ # insert them into the stream in the correct order. As such, we can do
+ # some extra manipulation on the tokens to make them match Ripper's
+ # output by mirroring the dedent logic that Ripper uses.
+ class DedentingHeredoc
+ TAB_WIDTH = 8
+
+ attr_reader :tokens, :dedent_next, :dedent, :embexpr_balance
+
+ def initialize
+ @tokens = []
+ @dedent_next = true
+ @dedent = nil
+ @embexpr_balance = 0
+ end
+
+ # As tokens are coming in, we track the minimum amount of common leading
+ # whitespace on plain string content tokens. This allows us to later
+ # remove that amount of whitespace from the beginning of each line.
+ def <<(token)
+ case token.event
+ when :on_embexpr_beg, :on_heredoc_beg
+ @embexpr_balance += 1
+ when :on_embexpr_end, :on_heredoc_end
+ @embexpr_balance -= 1
+ when :on_tstring_content
+ if embexpr_balance == 0
+ token.value.split(/(?<=\n)/).each_with_index do |line, index|
+ next if line.strip.empty? && line.end_with?("\n")
+ next if !(dedent_next || index > 0)
+
+ leading = line[/\A(\s*)\n?/, 1]
+ next_dedent = 0
+
+ leading.each_char do |char|
+ if char == "\t"
+ next_dedent = next_dedent - (next_dedent % TAB_WIDTH) + TAB_WIDTH
+ else
+ next_dedent += 1
+ end
+ end
+
+ @dedent = [dedent, next_dedent].compact.min
+ end
+ end
+ end
+
+ @dedent_next = token.event == :on_tstring_content && embexpr_balance == 0
+ tokens << token
+ end
+
+ def to_a
+ # If every line in the heredoc is blank, we still need to split up the
+ # string content token into multiple tokens.
+ if dedent.nil?
+ results = []
+ embexpr_balance = 0
+
+ tokens.each do |token|
+ case token.event
+ when :on_embexpr_beg, :on_heredoc_beg
+ embexpr_balance += 1
+ results << token
+ when :on_embexpr_end, :on_heredoc_end
+ embexpr_balance -= 1
+ results << token
+ when :on_tstring_content
+ if embexpr_balance == 0
+ lineno = token[0][0]
+ column = token[0][1]
+
+ token.value.split(/(?<=\n)/).each_with_index do |value, index|
+ column = 0 if index > 0
+ results << Token.new([[lineno, column], :on_tstring_content, value, token.state])
+ lineno += 1
+ end
+ else
+ results << token
+ end
+ else
+ results << token
+ end
+ end
+
+ return results
+ end
+
+ # Otherwise, we're going to run through each token in the list and
+ # insert on_ignored_sp tokens for the amount of dedent that we need to
+ # perform. We also need to remove the dedent from the beginning of
+ # each line of plain string content tokens.
+ results = []
+ dedent_next = true
+ embexpr_balance = 0
+
+ tokens.each do |token|
+ # Notice that the structure of this conditional largely matches the
+ # whitespace calculation we performed above. This is because
+ # checking if the subsequent token needs to be dedented is common to
+ # both the dedent calculation and the ignored_sp insertion.
+ case token.event
+ when :on_embexpr_beg
+ embexpr_balance += 1
+ results << token
+ when :on_embexpr_end
+ embexpr_balance -= 1
+ results << token
+ when :on_tstring_content
+ if embexpr_balance == 0
+ # Here we're going to split the string on newlines, but maintain
+ # the newlines in the resulting array. We'll do that with a look
+ # behind assertion.
+ splits = token.value.split(/(?<=\n)/)
+ index = 0
+
+ while index < splits.length
+ line = splits[index]
+ lineno = token[0][0] + index
+ column = token[0][1]
+
+ # Blank lines do not count toward common leading whitespace
+ # calculation and do not need to be dedented.
+ if dedent_next || index > 0
+ column = 0
+ end
+
+ # If the dedent is 0 and we're not supposed to dedent the next
+ # line or this line doesn't start with whitespace, then we
+ # should concatenate the rest of the string to match ripper.
+ if dedent == 0 && (!dedent_next || !line.start_with?(/\s/))
+ line = splits[index..].join
+ index = splits.length
+ end
+
+ # If we are supposed to dedent this line or if this is not the
+ # first line of the string and this line isn't entirely blank,
+ # then we need to insert an on_ignored_sp token and remove the
+ # dedent from the beginning of the line.
+ if (dedent > 0) && (dedent_next || index > 0)
+ deleting = 0
+ deleted_chars = []
+
+ # Gather up all of the characters that we're going to
+ # delete, stopping when you hit a character that would put
+ # you over the dedent amount.
+ line.each_char.with_index do |char, i|
+ case char
+ when "\r"
+ if line.chars[i + 1] == "\n"
+ break
+ end
+ when "\n"
+ break
+ when "\t"
+ deleting = deleting - (deleting % TAB_WIDTH) + TAB_WIDTH
+ else
+ deleting += 1
+ end
+
+ break if deleting > dedent
+ deleted_chars << char
+ end
+
+ # If we have something to delete, then delete it from the
+ # string and insert an on_ignored_sp token.
+ if deleted_chars.any?
+ ignored = deleted_chars.join
+ line.delete_prefix!(ignored)
+
+ results << Token.new([[lineno, 0], :on_ignored_sp, ignored, token[3]])
+ column = ignored.length
+ end
+ end
+
+ results << Token.new([[lineno, column], token[1], line, token[3]]) unless line.empty?
+ index += 1
+ end
+ else
+ results << token
+ end
+ else
+ results << token
+ end
+
+ dedent_next =
+ ((token.event == :on_tstring_content) || (token.event == :on_heredoc_end)) &&
+ embexpr_balance == 0
+ end
+
+ results
+ end
+ end
+
+ # Here we will split between the two types of heredocs and return the
+ # object that will store their tokens.
+ def self.build(opening)
+ case opening.value[2]
+ when "~"
+ DedentingHeredoc.new
+ when "-"
+ DashHeredoc.new(opening.value[3] != "'")
+ else
+ PlainHeredoc.new
+ end
+ end
+ end
+
+ attr_reader :source, :offsets, :filepath
+
+ def initialize(source, filepath = "")
+ @source = source
+ @filepath = filepath || ""
+ @offsets = find_offsets(source)
+ end
+
+ def result
+ tokens = []
+
+ state = :default
+ heredoc_stack = [[]]
+
+ result = YARP.lex(source, @filepath)
+ result_value = result.value
+ previous_state = nil
+
+ # If there's a UTF-8 byte-order mark as the start of the file, then ripper
+ # sets every token's on the first line back by 6 bytes. It also keeps the
+ # byte order mark in the first token's value. This is weird, and I don't
+ # want to mirror that in our parser. So instead, we'll match up the values
+ # here, and then match up the locations as we process the tokens.
+ bom = source.bytes[0..2] == [0xEF, 0xBB, 0xBF]
+ result_value[0][0].value.prepend("\xEF\xBB\xBF") if bom
+
+ result_value.each_with_index do |(token, lex_state), index|
+ (lineno, column) = find_location(token.location.start_offset)
+ column -= index == 0 ? 6 : 3 if bom && lineno == 1
+
+ event = RIPPER.fetch(token.type)
+ value = token.value
+ lex_state = Ripper::Lexer::State.new(lex_state)
+
+ token =
+ case event
+ when :on___end__
+ EndContentToken.new([[lineno, column], event, value, lex_state])
+ when :on_comment
+ CommentToken.new([[lineno, column], event, value, lex_state])
+ when :on_heredoc_end
+ # Heredoc end tokens can be emitted in an odd order, so we don't
+ # want to bother comparing the state on them.
+ HeredocEndToken.new([[lineno, column], event, value, lex_state])
+ when :on_embexpr_end, :on_ident
+ if lex_state == Ripper::EXPR_END | Ripper::EXPR_LABEL
+ # In the event that we're comparing identifiers, we're going to
+ # allow a little divergence. Ripper doesn't account for local
+ # variables introduced through named captures in regexes, and we
+ # do, which accounts for this difference.
+ IdentToken.new([[lineno, column], event, value, lex_state])
+ else
+ Token.new([[lineno, column], event, value, lex_state])
+ end
+ when :on_ignored_nl
+ # Ignored newlines can occasionally have a LABEL state attached to
+ # them which doesn't actually impact anything. We don't mirror that
+ # state so we ignored it.
+ IgnoredNewlineToken.new([[lineno, column], event, value, lex_state])
+ when :on_regexp_end
+ # On regex end, Ripper scans and then sets end state, so the ripper
+ # lexed output is begin, when it should be end. YARP sets lex state
+ # correctly to end state, but we want to be able to compare against
+ # Ripper's lexed state. So here, if it's a regexp end token, we
+ # output the state as the previous state, solely for the sake of
+ # comparison.
+ previous_token = result_value[index - 1][0]
+ lex_state =
+ if RIPPER.fetch(previous_token.type) == :on_embexpr_end
+ # If the previous token is embexpr_end, then we have to do even
+ # more processing. The end of an embedded expression sets the
+ # state to the state that it had at the beginning of the
+ # embedded expression. So we have to go and find that state and
+ # set it here.
+ counter = 1
+ current_index = index - 1
+
+ until counter == 0
+ current_index -= 1
+ current_event = RIPPER.fetch(result_value[current_index][0].type)
+ counter += { on_embexpr_beg: -1, on_embexpr_end: 1 }[current_event] || 0
+ end
+
+ Ripper::Lexer::State.new(result_value[current_index][1])
+ else
+ previous_state
+ end
+
+ Token.new([[lineno, column], event, value, lex_state])
+ else
+ Token.new([[lineno, column], event, value, lex_state])
+ end
+
+ previous_state = lex_state
+
+ # The order in which tokens appear in our lexer is different from the
+ # order that they appear in Ripper. When we hit the declaration of a
+ # heredoc in YARP, we skip forward and lex the rest of the content of
+ # the heredoc before going back and lexing at the end of the heredoc
+ # identifier.
+ #
+ # To match up to ripper, we keep a small state variable around here to
+ # track whether we're in the middle of a heredoc or not. In this way we
+ # can shuffle around the token to match Ripper's output.
+ case state
+ when :default
+ tokens << token
+
+ if event == :on_heredoc_beg
+ state = :heredoc_opened
+ heredoc_stack.last << Heredoc.build(token)
+ end
+ when :heredoc_opened
+ heredoc_stack.last.last << token
+
+ case event
+ when :on_heredoc_beg
+ heredoc_stack << [Heredoc.build(token)]
+ when :on_heredoc_end
+ state = :heredoc_closed
+ end
+ when :heredoc_closed
+ if %i[on_nl on_ignored_nl on_comment].include?(event) || (event == :on_tstring_content && value.end_with?("\n"))
+ if heredoc_stack.size > 1
+ flushing = heredoc_stack.pop
+ heredoc_stack.last.last << token
+
+ flushing.each do |heredoc|
+ heredoc.to_a.each do |flushed_token|
+ heredoc_stack.last.last << flushed_token
+ end
+ end
+
+ state = :heredoc_opened
+ next
+ end
+ elsif event == :on_heredoc_beg
+ tokens << token
+ state = :heredoc_opened
+ heredoc_stack.last << Heredoc.build(token)
+ next
+ elsif heredoc_stack.size > 1
+ heredoc_stack[-2].last << token
+ next
+ end
+
+ heredoc_stack.last.each do |heredoc|
+ tokens.concat(heredoc.to_a)
+ end
+
+ heredoc_stack.last.clear
+ state = :default
+
+ tokens << token
+ end
+ end
+
+ tokens.reject! { |t| t.event == :on_eof }
+
+ # We sort by location to compare against Ripper's output
+ tokens.sort_by!(&:location)
+
+ if result_value.size - 1 > tokens.size
+ raise StandardError, "Lost tokens when performing lex_compat"
+ end
+
+ ParseResult.new(tokens, result.comments, result.errors, result.warnings)
+ end
+
+ private
+
+ # YARP keeps locations around in the form of ranges of byte offsets from the
+ # start of the file. Ripper keeps locations around in the form of line and
+ # column numbers. To match the output, we keep a cache of the offsets at the
+ # beginning of each line.
+ def find_offsets(source)
+ last_offset = 0
+ offsets = [0]
+
+ source.each_line do |line|
+ last_offset += line.bytesize
+ offsets << last_offset
+ end
+
+ offsets
+ end
+
+ # Given a byte offset, find the line number and column number that it maps
+ # to. We use a binary search over the cached offsets to find the line number
+ # that the offset is on, and then subtract the offset of the previous line
+ # to find the column number.
+ def find_location(value)
+ line_number = offsets.bsearch_index { |offset| offset > value }
+ line_offset = offsets[line_number - 1] if line_number
+
+ [
+ line_number || offsets.length - 1,
+ value - (line_offset || offsets.last)
+ ]
+ end
+ end
+
+ # The constant that wraps the behavior of the lexer to match Ripper's output
+ # is an implementation detail, so we don't want it to be public.
+ private_constant :LexCompat
+
+ # Returns an array of tokens that closely resembles that of the Ripper lexer.
+ # The only difference is that since we don't keep track of lexer state in the
+ # same way, it's going to always return the NONE state.
+ def self.lex_compat(source, filepath = "")
+ LexCompat.new(source, filepath).result
+ end
+end
diff --git a/lib/yarp/node.rb b/lib/yarp/node.rb
new file mode 100644
index 0000000000..f6f9136cd1
--- /dev/null
+++ b/lib/yarp/node.rb
@@ -0,0 +1,6434 @@
+# frozen_string_literal: true
+=begin
+This file is generated by the bin/template script and should not be
+modified manually. See templates/lib/yarp/node.rb.erb
+if you are looking to modify the template
+=end
+
+module YARP
+ # Represents the use of the `alias` keyword.
+ #
+ # alias foo bar
+ # ^^^^^^^^^^^^^
+ class AliasNode < Node
+ # attr_reader new_name: Node
+ attr_reader :new_name
+
+ # attr_reader old_name: Node
+ attr_reader :old_name
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (new_name: Node, old_name: Node, keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(new_name, old_name, keyword_loc, start_offset, length)
+ @new_name = new_name
+ @old_name = old_name
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_alias_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [new_name, old_name]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { new_name: new_name, old_name: old_name, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents an alternation pattern in pattern matching.
+ #
+ # foo => bar | baz
+ # ^^^^^^^^^
+ class AlternationPatternNode < Node
+ # attr_reader left: Node
+ attr_reader :left
+
+ # attr_reader right: Node
+ attr_reader :right
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(left, right, operator_loc, start_offset, length)
+ @left = left
+ @right = right
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_alternation_pattern_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [left, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { left: left, right: right, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `&&` operator or the `and` keyword.
+ #
+ # left and right
+ # ^^^^^^^^^^^^^^
+ class AndNode < Node
+ # attr_reader left: Node
+ attr_reader :left
+
+ # attr_reader right: Node
+ attr_reader :right
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(left, right, operator_loc, start_offset, length)
+ @left = left
+ @right = right
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_and_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [left, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { left: left, right: right, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents a set of arguments to a method or a keyword.
+ #
+ # return foo, bar, baz
+ # ^^^^^^^^^^^^^
+ class ArgumentsNode < Node
+ # attr_reader arguments: Array[Node]
+ attr_reader :arguments
+
+ # def initialize: (arguments: Array[Node], start_offset: Integer, length: Integer) -> void
+ def initialize(arguments, start_offset, length)
+ @arguments = arguments
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_arguments_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*arguments]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { arguments: arguments, location: location }
+ end
+ end
+
+ # Represents an array literal. This can be a regular array using brackets or
+ # a special array using % like %w or %i.
+ #
+ # [1, 2, 3]
+ # ^^^^^^^^^
+ class ArrayNode < Node
+ # attr_reader elements: Array[Node]
+ attr_reader :elements
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (elements: Array[Node], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(elements, opening_loc, closing_loc, start_offset, length)
+ @elements = elements
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_array_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*elements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { elements: elements, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents an array pattern in pattern matching.
+ #
+ # foo in 1, 2
+ # ^^^^^^^^^^^
+ #
+ # foo in [1, 2]
+ # ^^^^^^^^^^^^^
+ #
+ # foo in *1
+ # ^^^^^^^^^
+ #
+ # foo in Bar[]
+ # ^^^^^^^^^^^^
+ #
+ # foo in Bar[1, 2, 3]
+ # ^^^^^^^^^^^^^^^^^^^
+ class ArrayPatternNode < Node
+ # attr_reader constant: Node?
+ attr_reader :constant
+
+ # attr_reader requireds: Array[Node]
+ attr_reader :requireds
+
+ # attr_reader rest: Node?
+ attr_reader :rest
+
+ # attr_reader posts: Array[Node]
+ attr_reader :posts
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (constant: Node?, requireds: Array[Node], rest: Node?, posts: Array[Node], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(constant, requireds, rest, posts, opening_loc, closing_loc, start_offset, length)
+ @constant = constant
+ @requireds = requireds
+ @rest = rest
+ @posts = posts
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_array_pattern_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [constant, *requireds, rest, *posts]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant: constant, requireds: requireds, rest: rest, posts: posts, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a hash key/value pair.
+ #
+ # { a => b }
+ # ^^^^^^
+ class AssocNode < Node
+ # attr_reader key: Node
+ attr_reader :key
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # def initialize: (key: Node, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(key, value, operator_loc, start_offset, length)
+ @key = key
+ @value = value
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_assoc_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [key, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { key: key, value: value, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents a splat in a hash literal.
+ #
+ # { **foo }
+ # ^^^^^
+ class AssocSplatNode < Node
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (value: Node?, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(value, operator_loc, start_offset, length)
+ @value = value
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_assoc_splat_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { value: value, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents reading a reference to a field in the previous match.
+ #
+ # $'
+ # ^^
+ class BackReferenceReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_back_reference_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a begin statement.
+ #
+ # begin
+ # foo
+ # end
+ # ^^^^^
+ class BeginNode < Node
+ # attr_reader begin_keyword_loc: Location?
+ attr_reader :begin_keyword_loc
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader rescue_clause: Node?
+ attr_reader :rescue_clause
+
+ # attr_reader else_clause: Node?
+ attr_reader :else_clause
+
+ # attr_reader ensure_clause: Node?
+ attr_reader :ensure_clause
+
+ # attr_reader end_keyword_loc: Location?
+ attr_reader :end_keyword_loc
+
+ # def initialize: (begin_keyword_loc: Location?, statements: Node?, rescue_clause: Node?, else_clause: Node?, ensure_clause: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, start_offset, length)
+ @begin_keyword_loc = begin_keyword_loc
+ @statements = statements
+ @rescue_clause = rescue_clause
+ @else_clause = else_clause
+ @ensure_clause = ensure_clause
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_begin_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements, rescue_clause, else_clause, ensure_clause]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { begin_keyword_loc: begin_keyword_loc, statements: statements, rescue_clause: rescue_clause, else_clause: else_clause, ensure_clause: ensure_clause, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents block method arguments.
+ #
+ # bar(&args)
+ # ^^^^^^^^^^
+ class BlockArgumentNode < Node
+ # attr_reader expression: Node?
+ attr_reader :expression
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (expression: Node?, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(expression, operator_loc, start_offset, length)
+ @expression = expression
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_block_argument_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [expression]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { expression: expression, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents a block of ruby code.
+ #
+ # [1, 2, 3].each { |i| puts x }
+ # ^^^^^^^^^^^^^^
+ class BlockNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader parameters: Node?
+ attr_reader :parameters
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (locals: Array[Symbol], parameters: Node?, statements: Node?, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, parameters, statements, opening_loc, closing_loc, start_offset, length)
+ @locals = locals
+ @parameters = parameters
+ @statements = statements
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_block_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [parameters, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, parameters: parameters, statements: statements, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a block parameter to a method, block, or lambda definition.
+ #
+ # def a(&b)
+ # ^^
+ # end
+ class BlockParameterNode < Node
+ # attr_reader name_loc: Location?
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (name_loc: Location?, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_block_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents a block's parameters declaration.
+ #
+ # -> (a, b = 1; local) { }
+ # ^^^^^^^^^^^^^^^^^
+ #
+ # foo do |a, b = 1; local|
+ # ^^^^^^^^^^^^^^^^^
+ # end
+ class BlockParametersNode < Node
+ # attr_reader parameters: Node?
+ attr_reader :parameters
+
+ # attr_reader locals: Array[Location]
+ attr_reader :locals
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (parameters: Node?, locals: Array[Location], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(parameters, locals, opening_loc, closing_loc, start_offset, length)
+ @parameters = parameters
+ @locals = locals
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_block_parameters_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [parameters]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { parameters: parameters, locals: locals, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `break` keyword.
+ #
+ # break foo
+ # ^^^^^^^^^
+ class BreakNode < Node
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (arguments: Node?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(arguments, keyword_loc, start_offset, length)
+ @arguments = arguments
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_break_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [arguments]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { arguments: arguments, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents a method call, in all of the various forms that can take.
+ #
+ # foo
+ # ^^^
+ #
+ # foo()
+ # ^^^^^
+ #
+ # +foo
+ # ^^^^
+ #
+ # foo + bar
+ # ^^^^^^^^^
+ #
+ # foo.bar
+ # ^^^^^^^
+ #
+ # foo&.bar
+ # ^^^^^^^^
+ class CallNode < Node
+ # attr_reader receiver: Node?
+ attr_reader :receiver
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader message_loc: Location?
+ attr_reader :message_loc
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # attr_reader block: Node?
+ attr_reader :block
+
+ # attr_reader flags: Integer
+ attr_reader :flags
+
+ # attr_reader name: String
+ attr_reader :name
+
+ # def initialize: (receiver: Node?, operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: Node?, closing_loc: Location?, block: Node?, flags: Integer, name: String, start_offset: Integer, length: Integer) -> void
+ def initialize(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, start_offset, length)
+ @receiver = receiver
+ @operator_loc = operator_loc
+ @message_loc = message_loc
+ @opening_loc = opening_loc
+ @arguments = arguments
+ @closing_loc = closing_loc
+ @block = block
+ @flags = flags
+ @name = name
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_call_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [receiver, arguments, block]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { receiver: receiver, operator_loc: operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, name: name, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator on a call.
+ #
+ # foo.bar &&= value
+ # ^^^^^^^^^^^^^^^^^
+ class CallOperatorAndWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_call_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator on a call.
+ #
+ # foo.bar ||= value
+ # ^^^^^^^^^^^^^^^^^
+ class CallOperatorOrWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (target: Node, value: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(target, value, operator_loc, start_offset, length)
+ @target = target
+ @value = value
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_call_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, value: value, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of an assignment operator on a call.
+ #
+ # foo.bar += baz
+ # ^^^^^^^^^^^^^^
+ class CallOperatorWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator_id: Symbol
+ attr_reader :operator_id
+
+ # def initialize: (target: Node, operator_loc: Location, value: Node, operator_id: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, operator_id, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @operator_id = operator_id
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_call_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, operator_id: operator_id, location: location }
+ end
+ end
+
+ # Represents assigning to a local variable in pattern matching.
+ #
+ # foo => [bar => baz]
+ # ^^^^^^^^^^^^
+ class CapturePatternNode < Node
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (value: Node, target: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(value, target, operator_loc, start_offset, length)
+ @value = value
+ @target = target
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_capture_pattern_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value, target]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { value: value, target: target, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of a case statement.
+ #
+ # case true
+ # ^^^^^^^^^
+ # when false
+ # end
+ class CaseNode < Node
+ # attr_reader predicate: Node?
+ attr_reader :predicate
+
+ # attr_reader conditions: Array[Node]
+ attr_reader :conditions
+
+ # attr_reader consequent: Node?
+ attr_reader :consequent
+
+ # attr_reader case_keyword_loc: Location
+ attr_reader :case_keyword_loc
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (predicate: Node?, conditions: Array[Node], consequent: Node?, case_keyword_loc: Location, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, start_offset, length)
+ @predicate = predicate
+ @conditions = conditions
+ @consequent = consequent
+ @case_keyword_loc = case_keyword_loc
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_case_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [predicate, *conditions, consequent]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { predicate: predicate, conditions: conditions, consequent: consequent, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents a class declaration involving the `class` keyword.
+ #
+ # class Foo end
+ # ^^^^^^^^^^^^^
+ class ClassNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader class_keyword_loc: Location
+ attr_reader :class_keyword_loc
+
+ # attr_reader constant_path: Node
+ attr_reader :constant_path
+
+ # attr_reader inheritance_operator_loc: Location?
+ attr_reader :inheritance_operator_loc
+
+ # attr_reader superclass: Node?
+ attr_reader :superclass
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, constant_path: Node, inheritance_operator_loc: Location?, superclass: Node?, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, start_offset, length)
+ @locals = locals
+ @class_keyword_loc = class_keyword_loc
+ @constant_path = constant_path
+ @inheritance_operator_loc = inheritance_operator_loc
+ @superclass = superclass
+ @statements = statements
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [constant_path, superclass, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, class_keyword_loc: class_keyword_loc, constant_path: constant_path, inheritance_operator_loc: inheritance_operator_loc, superclass: superclass, statements: statements, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to a class variable.
+ #
+ # @@target &&= value
+ # ^^^^^^^^^^^^^^^^
+ class ClassVariableOperatorAndWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_variable_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to a class variable.
+ #
+ # @@target ||= value
+ # ^^^^^^^^^^^^^^^^^^
+ class ClassVariableOperatorOrWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_variable_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents assigning to a class variable using an operator that isn't `=`.
+ #
+ # @@target += value
+ # ^^^^^^^^^^^^^^^^^
+ class ClassVariableOperatorWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator: Symbol
+ attr_reader :operator
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, operator, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @operator = operator
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_variable_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location }
+ end
+ end
+
+ # Represents referencing a class variable.
+ #
+ # @@foo
+ # ^^^^^
+ class ClassVariableReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_variable_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents writing to a class variable.
+ #
+ # @@foo = 1
+ # ^^^^^^^^^
+ class ClassVariableWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # def initialize: (name_loc: Location, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, value, operator_loc, start_offset, length)
+ @name_loc = name_loc
+ @value = value
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_class_variable_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, value: value, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to a constant.
+ #
+ # Target &&= value
+ # ^^^^^^^^^^^^^^^^
+ class ConstantOperatorAndWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to a constant.
+ #
+ # Target ||= value
+ # ^^^^^^^^^^^^^^^^
+ class ConstantOperatorOrWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents assigning to a constant using an operator that isn't `=`.
+ #
+ # Target += value
+ # ^^^^^^^^^^^^^^^
+ class ConstantOperatorWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator: Symbol
+ attr_reader :operator
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, operator, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @operator = operator
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location }
+ end
+ end
+
+ # Represents accessing a constant through a path of `::` operators.
+ #
+ # Foo::Bar
+ # ^^^^^^^^
+ class ConstantPathNode < Node
+ # attr_reader parent: Node?
+ attr_reader :parent
+
+ # attr_reader child: Node
+ attr_reader :child
+
+ # attr_reader delimiter_loc: Location
+ attr_reader :delimiter_loc
+
+ # def initialize: (parent: Node?, child: Node, delimiter_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(parent, child, delimiter_loc, start_offset, length)
+ @parent = parent
+ @child = child
+ @delimiter_loc = delimiter_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_path_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [parent, child]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { parent: parent, child: child, delimiter_loc: delimiter_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to a constant path.
+ #
+ # Parent::Child &&= value
+ # ^^^^^^^^^^^^^^^^^^^^^^^
+ class ConstantPathOperatorAndWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_path_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to a constant path.
+ #
+ # Parent::Child ||= value
+ # ^^^^^^^^^^^^^^^^^^^^^^^
+ class ConstantPathOperatorOrWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_path_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents assigning to a constant path using an operator that isn't `=`.
+ #
+ # Parent::Child += value
+ # ^^^^^^^^^^^^^^^^^^^^^^
+ class ConstantPathOperatorWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator: Symbol
+ attr_reader :operator
+
+ # def initialize: (target: Node, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, operator, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @operator = operator
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_path_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, operator: operator, location: location }
+ end
+ end
+
+ # Represents writing to a constant.
+ #
+ # Foo = 1
+ # ^^^^^^^
+ #
+ # Foo::Bar = 1
+ # ^^^^^^^^^^^^
+ class ConstantPathWriteNode < Node
+ # attr_reader target: Node
+ attr_reader :target
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # def initialize: (target: Node, operator_loc: Location?, value: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(target, operator_loc, value, start_offset, length)
+ @target = target
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_path_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [target, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { target: target, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents referencing a constant.
+ #
+ # Foo
+ # ^^^
+ class ConstantReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_constant_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a method definition.
+ #
+ # def method
+ # end
+ # ^^^^^^^^^^
+ class DefNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader receiver: Node?
+ attr_reader :receiver
+
+ # attr_reader parameters: Node?
+ attr_reader :parameters
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader def_keyword_loc: Location
+ attr_reader :def_keyword_loc
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader lparen_loc: Location?
+ attr_reader :lparen_loc
+
+ # attr_reader rparen_loc: Location?
+ attr_reader :rparen_loc
+
+ # attr_reader equal_loc: Location?
+ attr_reader :equal_loc
+
+ # attr_reader end_keyword_loc: Location?
+ attr_reader :end_keyword_loc
+
+ # def initialize: (name_loc: Location, receiver: Node?, parameters: Node?, statements: Node?, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, start_offset, length)
+ @name_loc = name_loc
+ @receiver = receiver
+ @parameters = parameters
+ @statements = statements
+ @locals = locals
+ @def_keyword_loc = def_keyword_loc
+ @operator_loc = operator_loc
+ @lparen_loc = lparen_loc
+ @rparen_loc = rparen_loc
+ @equal_loc = equal_loc
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_def_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [receiver, parameters, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, receiver: receiver, parameters: parameters, statements: statements, locals: locals, def_keyword_loc: def_keyword_loc, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, equal_loc: equal_loc, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `defined?` keyword.
+ #
+ # defined?(a)
+ # ^^^^^^^^^^^
+ class DefinedNode < Node
+ # attr_reader lparen_loc: Location?
+ attr_reader :lparen_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader rparen_loc: Location?
+ attr_reader :rparen_loc
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (lparen_loc: Location?, value: Node, rparen_loc: Location?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(lparen_loc, value, rparen_loc, keyword_loc, start_offset, length)
+ @lparen_loc = lparen_loc
+ @value = value
+ @rparen_loc = rparen_loc
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_defined_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { lparen_loc: lparen_loc, value: value, rparen_loc: rparen_loc, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents an `else` clause in a `case`, `if`, or `unless` statement.
+ #
+ # if a then b else c end
+ # ^^^^^^^^^^
+ class ElseNode < Node
+ # attr_reader else_keyword_loc: Location
+ attr_reader :else_keyword_loc
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader end_keyword_loc: Location?
+ attr_reader :end_keyword_loc
+
+ # def initialize: (else_keyword_loc: Location, statements: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(else_keyword_loc, statements, end_keyword_loc, start_offset, length)
+ @else_keyword_loc = else_keyword_loc
+ @statements = statements
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_else_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { else_keyword_loc: else_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents an interpolated set of statements.
+ #
+ # "foo #{bar}"
+ # ^^^^^^
+ class EmbeddedStatementsNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (opening_loc: Location, statements: Node?, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, statements, closing_loc, start_offset, length)
+ @opening_loc = opening_loc
+ @statements = statements
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_embedded_statements_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, statements: statements, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents an interpolated variable.
+ #
+ # "foo #@bar"
+ # ^^^^^
+ class EmbeddedVariableNode < Node
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader variable: Node
+ attr_reader :variable
+
+ # def initialize: (operator_loc: Location, variable: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(operator_loc, variable, start_offset, length)
+ @operator_loc = operator_loc
+ @variable = variable
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_embedded_variable_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [variable]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { operator_loc: operator_loc, variable: variable, location: location }
+ end
+ end
+
+ # Represents an `ensure` clause in a `begin` statement.
+ #
+ # begin
+ # foo
+ # ensure
+ # ^^^^^^
+ # bar
+ # end
+ class EnsureNode < Node
+ # attr_reader ensure_keyword_loc: Location
+ attr_reader :ensure_keyword_loc
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (ensure_keyword_loc: Location, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(ensure_keyword_loc, statements, end_keyword_loc, start_offset, length)
+ @ensure_keyword_loc = ensure_keyword_loc
+ @statements = statements
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_ensure_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { ensure_keyword_loc: ensure_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the literal `false` keyword.
+ #
+ # false
+ # ^^^^^
+ class FalseNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_false_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a find pattern in pattern matching.
+ #
+ # foo in *bar, baz, *qux
+ # ^^^^^^^^^^^^^^^^^^^^^^
+ #
+ # foo in [*bar, baz, *qux]
+ # ^^^^^^^^^^^^^^^^^^^^^^^^
+ #
+ # foo in Foo(*bar, baz, *qux)
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ class FindPatternNode < Node
+ # attr_reader constant: Node?
+ attr_reader :constant
+
+ # attr_reader left: Node
+ attr_reader :left
+
+ # attr_reader requireds: Array[Node]
+ attr_reader :requireds
+
+ # attr_reader right: Node
+ attr_reader :right
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (constant: Node?, left: Node, requireds: Array[Node], right: Node, opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(constant, left, requireds, right, opening_loc, closing_loc, start_offset, length)
+ @constant = constant
+ @left = left
+ @requireds = requireds
+ @right = right
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_find_pattern_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [constant, left, *requireds, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant: constant, left: left, requireds: requireds, right: right, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a floating point number literal.
+ #
+ # 1.0
+ # ^^^
+ class FloatNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_float_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the `for` keyword.
+ #
+ # for i in a end
+ # ^^^^^^^^^^^^^^
+ class ForNode < Node
+ # attr_reader index: Node
+ attr_reader :index
+
+ # attr_reader collection: Node
+ attr_reader :collection
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader for_keyword_loc: Location
+ attr_reader :for_keyword_loc
+
+ # attr_reader in_keyword_loc: Location
+ attr_reader :in_keyword_loc
+
+ # attr_reader do_keyword_loc: Location?
+ attr_reader :do_keyword_loc
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (index: Node, collection: Node, statements: Node?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, start_offset, length)
+ @index = index
+ @collection = collection
+ @statements = statements
+ @for_keyword_loc = for_keyword_loc
+ @in_keyword_loc = in_keyword_loc
+ @do_keyword_loc = do_keyword_loc
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_for_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [index, collection, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { index: index, collection: collection, statements: statements, for_keyword_loc: for_keyword_loc, in_keyword_loc: in_keyword_loc, do_keyword_loc: do_keyword_loc, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents forwarding all arguments to this method to another method.
+ #
+ # def foo(...)
+ # bar(...)
+ # ^^^^^^^^
+ # end
+ class ForwardingArgumentsNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_forwarding_arguments_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the forwarding parameter in a method, block, or lambda declaration.
+ #
+ # def foo(...)
+ # ^^^
+ # end
+ class ForwardingParameterNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_forwarding_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the `super` keyword without parentheses or arguments.
+ #
+ # super
+ # ^^^^^
+ class ForwardingSuperNode < Node
+ # attr_reader block: Node?
+ attr_reader :block
+
+ # def initialize: (block: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(block, start_offset, length)
+ @block = block
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_forwarding_super_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [block]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { block: block, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to a global variable.
+ #
+ # $target &&= value
+ # ^^^^^^^^^^^^^^^^^
+ class GlobalVariableOperatorAndWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_global_variable_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to a global variable.
+ #
+ # $target ||= value
+ # ^^^^^^^^^^^^^^^^^
+ class GlobalVariableOperatorOrWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_global_variable_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents assigning to a global variable using an operator that isn't `=`.
+ #
+ # $target += value
+ # ^^^^^^^^^^^^^^^^
+ class GlobalVariableOperatorWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator: Symbol
+ attr_reader :operator
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, operator, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @operator = operator
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_global_variable_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location }
+ end
+ end
+
+ # Represents referencing a global variable.
+ #
+ # $foo
+ # ^^^^
+ class GlobalVariableReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_global_variable_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents writing to a global variable.
+ #
+ # $foo = 1
+ # ^^^^^^^^
+ class GlobalVariableWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location?, value: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_global_variable_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents a hash literal.
+ #
+ # { a => b }
+ # ^^^^^^^^^^
+ class HashNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader elements: Array[Node]
+ attr_reader :elements
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (opening_loc: Location, elements: Array[Node], closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, elements, closing_loc, start_offset, length)
+ @opening_loc = opening_loc
+ @elements = elements
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_hash_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*elements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, elements: elements, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a hash pattern in pattern matching.
+ #
+ # foo => { a: 1, b: 2 }
+ # ^^^^^^^^^^^^^^
+ #
+ # foo => { a: 1, b: 2, **c }
+ # ^^^^^^^^^^^^^^^^^^^
+ class HashPatternNode < Node
+ # attr_reader constant: Node?
+ attr_reader :constant
+
+ # attr_reader assocs: Array[Node]
+ attr_reader :assocs
+
+ # attr_reader kwrest: Node?
+ attr_reader :kwrest
+
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (constant: Node?, assocs: Array[Node], kwrest: Node?, opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(constant, assocs, kwrest, opening_loc, closing_loc, start_offset, length)
+ @constant = constant
+ @assocs = assocs
+ @kwrest = kwrest
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_hash_pattern_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [constant, *assocs, kwrest]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant: constant, assocs: assocs, kwrest: kwrest, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `if` keyword, either in the block form or the modifier form.
+ #
+ # bar if foo
+ # ^^^^^^^^^^
+ #
+ # if foo then bar end
+ # ^^^^^^^^^^^^^^^^^^^
+ class IfNode < Node
+ # attr_reader if_keyword_loc: Location?
+ attr_reader :if_keyword_loc
+
+ # attr_reader predicate: Node
+ attr_reader :predicate
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader consequent: Node?
+ attr_reader :consequent
+
+ # attr_reader end_keyword_loc: Location?
+ attr_reader :end_keyword_loc
+
+ # def initialize: (if_keyword_loc: Location?, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, start_offset, length)
+ @if_keyword_loc = if_keyword_loc
+ @predicate = predicate
+ @statements = statements
+ @consequent = consequent
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_if_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [predicate, statements, consequent]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { if_keyword_loc: if_keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents an imaginary number literal.
+ #
+ # 1.0i
+ # ^^^^
+ class ImaginaryNode < Node
+ # attr_reader numeric: Node
+ attr_reader :numeric
+
+ # def initialize: (numeric: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(numeric, start_offset, length)
+ @numeric = numeric
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_imaginary_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [numeric]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { numeric: numeric, location: location }
+ end
+ end
+
+ # Represents the use of the `in` keyword in a case statement.
+ #
+ # case a; in b then c end
+ # ^^^^^^^^^^^
+ class InNode < Node
+ # attr_reader pattern: Node
+ attr_reader :pattern
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader in_loc: Location
+ attr_reader :in_loc
+
+ # attr_reader then_loc: Location?
+ attr_reader :then_loc
+
+ # def initialize: (pattern: Node, statements: Node?, in_loc: Location, then_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(pattern, statements, in_loc, then_loc, start_offset, length)
+ @pattern = pattern
+ @statements = statements
+ @in_loc = in_loc
+ @then_loc = then_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_in_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [pattern, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { pattern: pattern, statements: statements, in_loc: in_loc, then_loc: then_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to an instance variable.
+ #
+ # @target &&= value
+ # ^^^^^^^^^^^^^^^^^
+ class InstanceVariableOperatorAndWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_instance_variable_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to an instance variable.
+ #
+ # @target ||= value
+ # ^^^^^^^^^^^^^^^^^
+ class InstanceVariableOperatorOrWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_instance_variable_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents assigning to an instance variable using an operator that isn't `=`.
+ #
+ # @target += value
+ # ^^^^^^^^^^^^^^^^
+ class InstanceVariableOperatorWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader operator: Symbol
+ attr_reader :operator
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, operator, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @operator = operator
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_instance_variable_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location }
+ end
+ end
+
+ # Represents referencing an instance variable.
+ #
+ # @foo
+ # ^^^^
+ class InstanceVariableReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_instance_variable_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents writing to an instance variable.
+ #
+ # @foo = 1
+ # ^^^^^^^^
+ class InstanceVariableWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # def initialize: (name_loc: Location, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, value, operator_loc, start_offset, length)
+ @name_loc = name_loc
+ @value = value
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_instance_variable_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, value: value, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents an integer number literal.
+ #
+ # 1
+ # ^
+ class IntegerNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_integer_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a regular expression literal that contains interpolation.
+ #
+ # /foo #{bar} baz/
+ # ^^^^^^^^^^^^^^^^
+ class InterpolatedRegularExpressionNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader parts: Array[Node]
+ attr_reader :parts
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # attr_reader flags: Integer
+ attr_reader :flags
+
+ # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, flags: Integer, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, parts, closing_loc, flags, start_offset, length)
+ @opening_loc = opening_loc
+ @parts = parts
+ @closing_loc = closing_loc
+ @flags = flags
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_interpolated_regular_expression_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*parts]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, flags: flags, location: location }
+ end
+ end
+
+ # Represents a string literal that contains interpolation.
+ #
+ # "foo #{bar} baz"
+ # ^^^^^^^^^^^^^^^^
+ class InterpolatedStringNode < Node
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader parts: Array[Node]
+ attr_reader :parts
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, parts, closing_loc, start_offset, length)
+ @opening_loc = opening_loc
+ @parts = parts
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_interpolated_string_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*parts]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a symbol literal that contains interpolation.
+ #
+ # :"foo #{bar} baz"
+ # ^^^^^^^^^^^^^^^^^
+ class InterpolatedSymbolNode < Node
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader parts: Array[Node]
+ attr_reader :parts
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, parts, closing_loc, start_offset, length)
+ @opening_loc = opening_loc
+ @parts = parts
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_interpolated_symbol_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*parts]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents an xstring literal that contains interpolation.
+ #
+ # `foo #{bar} baz`
+ # ^^^^^^^^^^^^^^^^
+ class InterpolatedXStringNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader parts: Array[Node]
+ attr_reader :parts
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, parts, closing_loc, start_offset, length)
+ @opening_loc = opening_loc
+ @parts = parts
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_interpolated_x_string_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*parts]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a hash literal without opening and closing braces.
+ #
+ # foo(a: b)
+ # ^^^^
+ class KeywordHashNode < Node
+ # attr_reader elements: Array[Node]
+ attr_reader :elements
+
+ # def initialize: (elements: Array[Node], start_offset: Integer, length: Integer) -> void
+ def initialize(elements, start_offset, length)
+ @elements = elements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_keyword_hash_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*elements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { elements: elements, location: location }
+ end
+ end
+
+ # Represents a keyword parameter to a method, block, or lambda definition.
+ #
+ # def a(b:)
+ # ^^
+ # end
+ #
+ # def a(b: 1)
+ # ^^^^
+ # end
+ class KeywordParameterNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # def initialize: (name_loc: Location, value: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, value, start_offset, length)
+ @name_loc = name_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_keyword_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, value: value, location: location }
+ end
+ end
+
+ # Represents a keyword rest parameter to a method, block, or lambda definition.
+ #
+ # def a(**b)
+ # ^^^
+ # end
+ class KeywordRestParameterNode < Node
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader name_loc: Location?
+ attr_reader :name_loc
+
+ # def initialize: (operator_loc: Location, name_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(operator_loc, name_loc, start_offset, length)
+ @operator_loc = operator_loc
+ @name_loc = name_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_keyword_rest_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { operator_loc: operator_loc, name_loc: name_loc, location: location }
+ end
+ end
+
+ # Represents using a lambda literal (not the lambda method call).
+ #
+ # ->(value) { value * 2 }
+ # ^^^^^^^^^^^^^^^^^^^^^^^
+ class LambdaNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader parameters: Node?
+ attr_reader :parameters
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # def initialize: (locals: Array[Symbol], opening_loc: Location, parameters: Node?, statements: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, opening_loc, parameters, statements, start_offset, length)
+ @locals = locals
+ @opening_loc = opening_loc
+ @parameters = parameters
+ @statements = statements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_lambda_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [parameters, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, opening_loc: opening_loc, parameters: parameters, statements: statements, location: location }
+ end
+ end
+
+ # Represents the use of the `&&=` operator for assignment to a local variable.
+ #
+ # target &&= value
+ # ^^^^^^^^^^^^^^^^
+ class LocalVariableOperatorAndWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, constant_id, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @constant_id = constant_id
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_local_variable_operator_and_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, location: location }
+ end
+ end
+
+ # Represents the use of the `||=` operator for assignment to a local variable.
+ #
+ # target ||= value
+ # ^^^^^^^^^^^^^^^^
+ class LocalVariableOperatorOrWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, constant_id, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @constant_id = constant_id
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_local_variable_operator_or_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, location: location }
+ end
+ end
+
+ # Represents assigning to a local variable using an operator that isn't `=`.
+ #
+ # target += value
+ # ^^^^^^^^^^^^^^^
+ class LocalVariableOperatorWriteNode < Node
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # attr_reader operator_id: Symbol
+ attr_reader :operator_id
+
+ # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, operator_id: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(name_loc, operator_loc, value, constant_id, operator_id, start_offset, length)
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @constant_id = constant_id
+ @operator_id = operator_id
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_local_variable_operator_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, operator_id: operator_id, location: location }
+ end
+ end
+
+ # Represents reading a local variable. Note that this requires that a local
+ # variable of the same name has already been written to in the same scope,
+ # otherwise it is parsed as a method call.
+ #
+ # foo
+ # ^^^
+ class LocalVariableReadNode < Node
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # attr_reader depth: Integer
+ attr_reader :depth
+
+ # def initialize: (constant_id: Symbol, depth: Integer, start_offset: Integer, length: Integer) -> void
+ def initialize(constant_id, depth, start_offset, length)
+ @constant_id = constant_id
+ @depth = depth
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_local_variable_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant_id: constant_id, depth: depth, location: location }
+ end
+ end
+
+ # Represents writing to a local variable.
+ #
+ # foo = 1
+ # ^^^^^^^
+ class LocalVariableWriteNode < Node
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # attr_reader depth: Integer
+ attr_reader :depth
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # def initialize: (constant_id: Symbol, depth: Integer, value: Node?, name_loc: Location, operator_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(constant_id, depth, value, name_loc, operator_loc, start_offset, length)
+ @constant_id = constant_id
+ @depth = depth
+ @value = value
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_local_variable_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant_id: constant_id, depth: depth, value: value, name_loc: name_loc, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of the modifier `in` operator.
+ #
+ # foo in bar
+ # ^^^^^^^^^^
+ class MatchPredicateNode < Node
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader pattern: Node
+ attr_reader :pattern
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (value: Node, pattern: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(value, pattern, operator_loc, start_offset, length)
+ @value = value
+ @pattern = pattern
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_match_predicate_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value, pattern]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { value: value, pattern: pattern, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `=>` operator.
+ #
+ # foo => bar
+ # ^^^^^^^^^^
+ class MatchRequiredNode < Node
+ # attr_reader value: Node
+ attr_reader :value
+
+ # attr_reader pattern: Node
+ attr_reader :pattern
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (value: Node, pattern: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(value, pattern, operator_loc, start_offset, length)
+ @value = value
+ @pattern = pattern
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_match_required_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value, pattern]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { value: value, pattern: pattern, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents a node that is missing from the source and results in a syntax
+ # error.
+ class MissingNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_missing_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a module declaration involving the `module` keyword.
+ #
+ # module Foo end
+ # ^^^^^^^^^^^^^^
+ class ModuleNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader module_keyword_loc: Location
+ attr_reader :module_keyword_loc
+
+ # attr_reader constant_path: Node
+ attr_reader :constant_path
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (locals: Array[Symbol], module_keyword_loc: Location, constant_path: Node, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, start_offset, length)
+ @locals = locals
+ @module_keyword_loc = module_keyword_loc
+ @constant_path = constant_path
+ @statements = statements
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_module_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [constant_path, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, module_keyword_loc: module_keyword_loc, constant_path: constant_path, statements: statements, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents a multi-target expression.
+ #
+ # a, b, c = 1, 2, 3
+ # ^^^^^^^^^^^^^^^^^
+ class MultiWriteNode < Node
+ # attr_reader targets: Array[Node]
+ attr_reader :targets
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader value: Node?
+ attr_reader :value
+
+ # attr_reader lparen_loc: Location?
+ attr_reader :lparen_loc
+
+ # attr_reader rparen_loc: Location?
+ attr_reader :rparen_loc
+
+ # def initialize: (targets: Array[Node], operator_loc: Location?, value: Node?, lparen_loc: Location?, rparen_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(targets, operator_loc, value, lparen_loc, rparen_loc, start_offset, length)
+ @targets = targets
+ @operator_loc = operator_loc
+ @value = value
+ @lparen_loc = lparen_loc
+ @rparen_loc = rparen_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_multi_write_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*targets, value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { targets: targets, operator_loc: operator_loc, value: value, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `next` keyword.
+ #
+ # next 1
+ # ^^^^^^
+ class NextNode < Node
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (arguments: Node?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(arguments, keyword_loc, start_offset, length)
+ @arguments = arguments
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_next_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [arguments]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { arguments: arguments, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `nil` keyword.
+ #
+ # nil
+ # ^^^
+ class NilNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_nil_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of `**nil` inside method arguments.
+ #
+ # def a(**nil)
+ # ^^^^^
+ # end
+ class NoKeywordsParameterNode < Node
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (operator_loc: Location, keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(operator_loc, keyword_loc, start_offset, length)
+ @operator_loc = operator_loc
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_no_keywords_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { operator_loc: operator_loc, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents reading a numbered reference to a capture in the previous match.
+ #
+ # $1
+ # ^^
+ class NumberedReferenceReadNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_numbered_reference_read_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents an optional parameter to a method, block, or lambda definition.
+ #
+ # def a(b = 1)
+ # ^^^^^
+ # end
+ class OptionalParameterNode < Node
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # attr_reader name_loc: Location
+ attr_reader :name_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader value: Node
+ attr_reader :value
+
+ # def initialize: (constant_id: Symbol, name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(constant_id, name_loc, operator_loc, value, start_offset, length)
+ @constant_id = constant_id
+ @name_loc = name_loc
+ @operator_loc = operator_loc
+ @value = value
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_optional_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [value]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant_id: constant_id, name_loc: name_loc, operator_loc: operator_loc, value: value, location: location }
+ end
+ end
+
+ # Represents the use of the `||` operator or the `or` keyword.
+ #
+ # left or right
+ # ^^^^^^^^^^^^^
+ class OrNode < Node
+ # attr_reader left: Node
+ attr_reader :left
+
+ # attr_reader right: Node
+ attr_reader :right
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(left, right, operator_loc, start_offset, length)
+ @left = left
+ @right = right
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_or_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [left, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { left: left, right: right, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the list of parameters on a method, block, or lambda definition.
+ #
+ # def a(b, c, d)
+ # ^^^^^^^
+ # end
+ class ParametersNode < Node
+ # attr_reader requireds: Array[Node]
+ attr_reader :requireds
+
+ # attr_reader optionals: Array[Node]
+ attr_reader :optionals
+
+ # attr_reader posts: Array[Node]
+ attr_reader :posts
+
+ # attr_reader rest: Node?
+ attr_reader :rest
+
+ # attr_reader keywords: Array[Node]
+ attr_reader :keywords
+
+ # attr_reader keyword_rest: Node?
+ attr_reader :keyword_rest
+
+ # attr_reader block: Node?
+ attr_reader :block
+
+ # def initialize: (requireds: Array[Node], optionals: Array[Node], posts: Array[Node], rest: Node?, keywords: Array[Node], keyword_rest: Node?, block: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(requireds, optionals, posts, rest, keywords, keyword_rest, block, start_offset, length)
+ @requireds = requireds
+ @optionals = optionals
+ @posts = posts
+ @rest = rest
+ @keywords = keywords
+ @keyword_rest = keyword_rest
+ @block = block
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_parameters_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*requireds, *optionals, *posts, rest, *keywords, keyword_rest, block]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { requireds: requireds, optionals: optionals, posts: posts, rest: rest, keywords: keywords, keyword_rest: keyword_rest, block: block, location: location }
+ end
+ end
+
+ # Represents a parentesized expression
+ #
+ # (10 + 34)
+ # ^^^^^^^^^
+ class ParenthesesNode < Node
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (statements: Node?, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(statements, opening_loc, closing_loc, start_offset, length)
+ @statements = statements
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_parentheses_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { statements: statements, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `^` operator for pinning an expression in a
+ # pattern matching expression.
+ #
+ # foo in ^(bar)
+ # ^^^^^^
+ class PinnedExpressionNode < Node
+ # attr_reader expression: Node
+ attr_reader :expression
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader lparen_loc: Location
+ attr_reader :lparen_loc
+
+ # attr_reader rparen_loc: Location
+ attr_reader :rparen_loc
+
+ # def initialize: (expression: Node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(expression, operator_loc, lparen_loc, rparen_loc, start_offset, length)
+ @expression = expression
+ @operator_loc = operator_loc
+ @lparen_loc = lparen_loc
+ @rparen_loc = rparen_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_pinned_expression_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [expression]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { expression: expression, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `^` operator for pinning a variable in a pattern
+ # matching expression.
+ #
+ # foo in ^bar
+ # ^^^^
+ class PinnedVariableNode < Node
+ # attr_reader variable: Node
+ attr_reader :variable
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # def initialize: (variable: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(variable, operator_loc, start_offset, length)
+ @variable = variable
+ @operator_loc = operator_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_pinned_variable_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [variable]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { variable: variable, operator_loc: operator_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `END` keyword.
+ #
+ # END { foo }
+ # ^^^^^^^^^^^
+ class PostExecutionNode < Node
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(statements, keyword_loc, opening_loc, closing_loc, start_offset, length)
+ @statements = statements
+ @keyword_loc = keyword_loc
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_post_execution_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `BEGIN` keyword.
+ #
+ # BEGIN { foo }
+ # ^^^^^^^^^^^^^
+ class PreExecutionNode < Node
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(statements, keyword_loc, opening_loc, closing_loc, start_offset, length)
+ @statements = statements
+ @keyword_loc = keyword_loc
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_pre_execution_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # The top level node of any parse tree.
+ class ProgramNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader statements: Node
+ attr_reader :statements
+
+ # def initialize: (locals: Array[Symbol], statements: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, statements, start_offset, length)
+ @locals = locals
+ @statements = statements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_program_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, statements: statements, location: location }
+ end
+ end
+
+ # Represents the use of the `..` or `...` operators.
+ #
+ # 1..2
+ # ^^^^
+ #
+ # c if a =~ /left/ ... b =~ /right/
+ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ class RangeNode < Node
+ # attr_reader left: Node?
+ attr_reader :left
+
+ # attr_reader right: Node?
+ attr_reader :right
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader flags: Integer
+ attr_reader :flags
+
+ # def initialize: (left: Node?, right: Node?, operator_loc: Location, flags: Integer, start_offset: Integer, length: Integer) -> void
+ def initialize(left, right, operator_loc, flags, start_offset, length)
+ @left = left
+ @right = right
+ @operator_loc = operator_loc
+ @flags = flags
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_range_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [left, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { left: left, right: right, operator_loc: operator_loc, flags: flags, location: location }
+ end
+ end
+
+ # Represents a rational number literal.
+ #
+ # 1.0r
+ # ^^^^
+ class RationalNode < Node
+ # attr_reader numeric: Node
+ attr_reader :numeric
+
+ # def initialize: (numeric: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(numeric, start_offset, length)
+ @numeric = numeric
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_rational_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [numeric]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { numeric: numeric, location: location }
+ end
+ end
+
+ # Represents the use of the `redo` keyword.
+ #
+ # redo
+ # ^^^^
+ class RedoNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_redo_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a regular expression literal with no interpolation.
+ #
+ # /foo/i
+ # ^^^^^^
+ class RegularExpressionNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader content_loc: Location
+ attr_reader :content_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # attr_reader unescaped: String
+ attr_reader :unescaped
+
+ # attr_reader flags: Integer
+ attr_reader :flags
+
+ # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, flags: Integer, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, content_loc, closing_loc, unescaped, flags, start_offset, length)
+ @opening_loc = opening_loc
+ @content_loc = content_loc
+ @closing_loc = closing_loc
+ @unescaped = unescaped
+ @flags = flags
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_regular_expression_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, flags: flags, location: location }
+ end
+ end
+
+ # Represents a destructured required parameter node.
+ #
+ # def foo((bar, baz))
+ # ^^^^^^^^^^
+ # end
+ class RequiredDestructuredParameterNode < Node
+ # attr_reader parameters: Array[Node]
+ attr_reader :parameters
+
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # def initialize: (parameters: Array[Node], opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(parameters, opening_loc, closing_loc, start_offset, length)
+ @parameters = parameters
+ @opening_loc = opening_loc
+ @closing_loc = closing_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_required_destructured_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*parameters]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { parameters: parameters, opening_loc: opening_loc, closing_loc: closing_loc, location: location }
+ end
+ end
+
+ # Represents a required parameter to a method, block, or lambda definition.
+ #
+ # def a(b)
+ # ^
+ # end
+ class RequiredParameterNode < Node
+ # attr_reader constant_id: Symbol
+ attr_reader :constant_id
+
+ # def initialize: (constant_id: Symbol, start_offset: Integer, length: Integer) -> void
+ def initialize(constant_id, start_offset, length)
+ @constant_id = constant_id
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_required_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { constant_id: constant_id, location: location }
+ end
+ end
+
+ # Represents an expression modified with a rescue.
+ #
+ # foo rescue nil
+ # ^^^^^^^^^^^^^^
+ class RescueModifierNode < Node
+ # attr_reader expression: Node
+ attr_reader :expression
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader rescue_expression: Node
+ attr_reader :rescue_expression
+
+ # def initialize: (expression: Node, keyword_loc: Location, rescue_expression: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(expression, keyword_loc, rescue_expression, start_offset, length)
+ @expression = expression
+ @keyword_loc = keyword_loc
+ @rescue_expression = rescue_expression
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_rescue_modifier_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [expression, rescue_expression]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { expression: expression, keyword_loc: keyword_loc, rescue_expression: rescue_expression, location: location }
+ end
+ end
+
+ # Represents a rescue statement.
+ #
+ # begin
+ # rescue
+ # foo
+ # ^^^^^^
+ # end
+ class RescueNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader exceptions: Array[Node]
+ attr_reader :exceptions
+
+ # attr_reader operator_loc: Location?
+ attr_reader :operator_loc
+
+ # attr_reader exception: Node?
+ attr_reader :exception
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader consequent: Node?
+ attr_reader :consequent
+
+ # def initialize: (keyword_loc: Location, exceptions: Array[Node], operator_loc: Location?, exception: Node?, statements: Node?, consequent: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, exceptions, operator_loc, exception, statements, consequent, start_offset, length)
+ @keyword_loc = keyword_loc
+ @exceptions = exceptions
+ @operator_loc = operator_loc
+ @exception = exception
+ @statements = statements
+ @consequent = consequent
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_rescue_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*exceptions, exception, statements, consequent]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, exception: exception, statements: statements, consequent: consequent, location: location }
+ end
+ end
+
+ # Represents a rest parameter to a method, block, or lambda definition.
+ #
+ # def a(*b)
+ # ^^
+ # end
+ class RestParameterNode < Node
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader name_loc: Location?
+ attr_reader :name_loc
+
+ # def initialize: (operator_loc: Location, name_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(operator_loc, name_loc, start_offset, length)
+ @operator_loc = operator_loc
+ @name_loc = name_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_rest_parameter_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { operator_loc: operator_loc, name_loc: name_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `retry` keyword.
+ #
+ # retry
+ # ^^^^^
+ class RetryNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_retry_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the `return` keyword.
+ #
+ # return 1
+ # ^^^^^^^^
+ class ReturnNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # def initialize: (keyword_loc: Location, arguments: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, arguments, start_offset, length)
+ @keyword_loc = keyword_loc
+ @arguments = arguments
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_return_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [arguments]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, arguments: arguments, location: location }
+ end
+ end
+
+ # Represents the `self` keyword.
+ #
+ # self
+ # ^^^^
+ class SelfNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_self_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents a singleton class declaration involving the `class` keyword.
+ #
+ # class << self end
+ # ^^^^^^^^^^^^^^^^^
+ class SingletonClassNode < Node
+ # attr_reader locals: Array[Symbol]
+ attr_reader :locals
+
+ # attr_reader class_keyword_loc: Location
+ attr_reader :class_keyword_loc
+
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader expression: Node
+ attr_reader :expression
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader end_keyword_loc: Location
+ attr_reader :end_keyword_loc
+
+ # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Node, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, start_offset, length)
+ @locals = locals
+ @class_keyword_loc = class_keyword_loc
+ @operator_loc = operator_loc
+ @expression = expression
+ @statements = statements
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_singleton_class_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [expression, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { locals: locals, class_keyword_loc: class_keyword_loc, operator_loc: operator_loc, expression: expression, statements: statements, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `__ENCODING__` keyword.
+ #
+ # __ENCODING__
+ # ^^^^^^^^^^^^
+ class SourceEncodingNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_source_encoding_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the `__FILE__` keyword.
+ #
+ # __FILE__
+ # ^^^^^^^^
+ class SourceFileNode < Node
+ # attr_reader filepath: String
+ attr_reader :filepath
+
+ # def initialize: (filepath: String, start_offset: Integer, length: Integer) -> void
+ def initialize(filepath, start_offset, length)
+ @filepath = filepath
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_source_file_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { filepath: filepath, location: location }
+ end
+ end
+
+ # Represents the use of the `__LINE__` keyword.
+ #
+ # __LINE__
+ # ^^^^^^^^
+ class SourceLineNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_source_line_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the splat operator.
+ #
+ # [*a]
+ # ^^
+ class SplatNode < Node
+ # attr_reader operator_loc: Location
+ attr_reader :operator_loc
+
+ # attr_reader expression: Node?
+ attr_reader :expression
+
+ # def initialize: (operator_loc: Location, expression: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(operator_loc, expression, start_offset, length)
+ @operator_loc = operator_loc
+ @expression = expression
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_splat_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [expression]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { operator_loc: operator_loc, expression: expression, location: location }
+ end
+ end
+
+ # Represents a set of statements contained within some scope.
+ #
+ # foo; bar; baz
+ # ^^^^^^^^^^^^^
+ class StatementsNode < Node
+ # attr_reader body: Array[Node]
+ attr_reader :body
+
+ # def initialize: (body: Array[Node], start_offset: Integer, length: Integer) -> void
+ def initialize(body, start_offset, length)
+ @body = body
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_statements_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*body]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { body: body, location: location }
+ end
+ end
+
+ # Represents the use of compile-time string concatenation.
+ #
+ # "foo" "bar"
+ # ^^^^^^^^^^^
+ class StringConcatNode < Node
+ # attr_reader left: Node
+ attr_reader :left
+
+ # attr_reader right: Node
+ attr_reader :right
+
+ # def initialize: (left: Node, right: Node, start_offset: Integer, length: Integer) -> void
+ def initialize(left, right, start_offset, length)
+ @left = left
+ @right = right
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_string_concat_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [left, right]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { left: left, right: right, location: location }
+ end
+ end
+
+ # Represents a string literal, a string contained within a `%w` list, or
+ # plain string content within an interpolated string.
+ #
+ # "foo"
+ # ^^^^^
+ #
+ # %w[foo]
+ # ^^^
+ #
+ # "foo #{bar} baz"
+ # ^^^^ ^^^^
+ class StringNode < Node
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader content_loc: Location
+ attr_reader :content_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # attr_reader unescaped: String
+ attr_reader :unescaped
+
+ # def initialize: (opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, content_loc, closing_loc, unescaped, start_offset, length)
+ @opening_loc = opening_loc
+ @content_loc = content_loc
+ @closing_loc = closing_loc
+ @unescaped = unescaped
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_string_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
+ end
+ end
+
+ # Represents the use of the `super` keyword with parentheses or arguments.
+ #
+ # super()
+ # ^^^^^^^
+ #
+ # super foo, bar
+ # ^^^^^^^^^^^^^^
+ class SuperNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader lparen_loc: Location?
+ attr_reader :lparen_loc
+
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # attr_reader rparen_loc: Location?
+ attr_reader :rparen_loc
+
+ # attr_reader block: Node?
+ attr_reader :block
+
+ # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, block: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, block, start_offset, length)
+ @keyword_loc = keyword_loc
+ @lparen_loc = lparen_loc
+ @arguments = arguments
+ @rparen_loc = rparen_loc
+ @block = block
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_super_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [arguments, block]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, block: block, location: location }
+ end
+ end
+
+ # Represents a symbol literal or a symbol contained within a `%i` list.
+ #
+ # :foo
+ # ^^^^
+ #
+ # %i[foo]
+ # ^^^
+ class SymbolNode < Node
+ # attr_reader opening_loc: Location?
+ attr_reader :opening_loc
+
+ # attr_reader value_loc: Location
+ attr_reader :value_loc
+
+ # attr_reader closing_loc: Location?
+ attr_reader :closing_loc
+
+ # attr_reader unescaped: String
+ attr_reader :unescaped
+
+ # def initialize: (opening_loc: Location?, value_loc: Location, closing_loc: Location?, unescaped: String, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, value_loc, closing_loc, unescaped, start_offset, length)
+ @opening_loc = opening_loc
+ @value_loc = value_loc
+ @closing_loc = closing_loc
+ @unescaped = unescaped
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_symbol_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
+ end
+ end
+
+ # Represents the use of the literal `true` keyword.
+ #
+ # true
+ # ^^^^
+ class TrueNode < Node
+ # def initialize: (start_offset: Integer, length: Integer) -> void
+ def initialize(start_offset, length)
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_true_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { location: location }
+ end
+ end
+
+ # Represents the use of the `undef` keyword.
+ #
+ # undef :foo, :bar, :baz
+ # ^^^^^^^^^^^^^^^^^^^^^^
+ class UndefNode < Node
+ # attr_reader names: Array[Node]
+ attr_reader :names
+
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # def initialize: (names: Array[Node], keyword_loc: Location, start_offset: Integer, length: Integer) -> void
+ def initialize(names, keyword_loc, start_offset, length)
+ @names = names
+ @keyword_loc = keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_undef_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*names]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { names: names, keyword_loc: keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `unless` keyword, either in the block form or the modifier form.
+ #
+ # bar unless foo
+ # ^^^^^^^^^^^^^^
+ #
+ # unless foo then bar end
+ # ^^^^^^^^^^^^^^^^^^^^^^^
+ class UnlessNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader predicate: Node
+ attr_reader :predicate
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # attr_reader consequent: Node?
+ attr_reader :consequent
+
+ # attr_reader end_keyword_loc: Location?
+ attr_reader :end_keyword_loc
+
+ # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, predicate, statements, consequent, end_keyword_loc, start_offset, length)
+ @keyword_loc = keyword_loc
+ @predicate = predicate
+ @statements = statements
+ @consequent = consequent
+ @end_keyword_loc = end_keyword_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_unless_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [predicate, statements, consequent]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location }
+ end
+ end
+
+ # Represents the use of the `until` keyword, either in the block form or the modifier form.
+ #
+ # bar until foo
+ # ^^^^^^^^^^^^^
+ #
+ # until foo do bar end
+ # ^^^^^^^^^^^^^^^^^^^^
+ class UntilNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader predicate: Node
+ attr_reader :predicate
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, predicate, statements, start_offset, length)
+ @keyword_loc = keyword_loc
+ @predicate = predicate
+ @statements = statements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_until_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [predicate, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location }
+ end
+ end
+
+ # case true
+ # when true
+ # ^^^^^^^^^
+ # end
+ class WhenNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader conditions: Array[Node]
+ attr_reader :conditions
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # def initialize: (keyword_loc: Location, conditions: Array[Node], statements: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, conditions, statements, start_offset, length)
+ @keyword_loc = keyword_loc
+ @conditions = conditions
+ @statements = statements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_when_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [*conditions, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, conditions: conditions, statements: statements, location: location }
+ end
+ end
+
+ # Represents the use of the `while` keyword, either in the block form or the modifier form.
+ #
+ # bar while foo
+ # ^^^^^^^^^^^^^
+ #
+ # while foo do bar end
+ # ^^^^^^^^^^^^^^^^^^^^
+ class WhileNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader predicate: Node
+ attr_reader :predicate
+
+ # attr_reader statements: Node?
+ attr_reader :statements
+
+ # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, predicate, statements, start_offset, length)
+ @keyword_loc = keyword_loc
+ @predicate = predicate
+ @statements = statements
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_while_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [predicate, statements]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location }
+ end
+ end
+
+ # Represents an xstring literal with no interpolation.
+ #
+ # `foo`
+ # ^^^^^
+ class XStringNode < Node
+ # attr_reader opening_loc: Location
+ attr_reader :opening_loc
+
+ # attr_reader content_loc: Location
+ attr_reader :content_loc
+
+ # attr_reader closing_loc: Location
+ attr_reader :closing_loc
+
+ # attr_reader unescaped: String
+ attr_reader :unescaped
+
+ # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, start_offset: Integer, length: Integer) -> void
+ def initialize(opening_loc, content_loc, closing_loc, unescaped, start_offset, length)
+ @opening_loc = opening_loc
+ @content_loc = content_loc
+ @closing_loc = closing_loc
+ @unescaped = unescaped
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_x_string_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ []
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location }
+ end
+ end
+
+ # Represents the use of the `yield` keyword.
+ #
+ # yield 1
+ # ^^^^^^^
+ class YieldNode < Node
+ # attr_reader keyword_loc: Location
+ attr_reader :keyword_loc
+
+ # attr_reader lparen_loc: Location?
+ attr_reader :lparen_loc
+
+ # attr_reader arguments: Node?
+ attr_reader :arguments
+
+ # attr_reader rparen_loc: Location?
+ attr_reader :rparen_loc
+
+ # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, start_offset: Integer, length: Integer) -> void
+ def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, start_offset, length)
+ @keyword_loc = keyword_loc
+ @lparen_loc = lparen_loc
+ @arguments = arguments
+ @rparen_loc = rparen_loc
+ @start_offset = start_offset
+ @length = length
+ end
+
+ # def accept: (visitor: Visitor) -> void
+ def accept(visitor)
+ visitor.visit_yield_node(self)
+ end
+
+ # def child_nodes: () -> Array[nil | Node]
+ def child_nodes
+ [arguments]
+ end
+
+ # def deconstruct: () -> Array[nil | Node]
+ alias deconstruct child_nodes
+
+ # def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
+ def deconstruct_keys(keys)
+ { keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, location: location }
+ end
+ end
+
+ module CallNodeFlags
+ # &. operator
+ SAFE_NAVIGATION = 1 << 0
+ end
+
+ module RangeNodeFlags
+ # ... operator
+ EXCLUDE_END = 1 << 0
+ end
+
+ module RegularExpressionFlags
+ # i - ignores the case of characters when matching
+ IGNORE_CASE = 1 << 0
+
+ # m - allows $ to match the end of lines within strings
+ MULTI_LINE = 1 << 1
+
+ # x - ignores whitespace and allows comments in regular expressions
+ EXTENDED = 1 << 2
+
+ # e - forces the EUC-JP encoding
+ EUC_JP = 1 << 3
+
+ # n - forces the ASCII-8BIT encoding
+ ASCII_8BIT = 1 << 4
+
+ # s - forces the Windows-31J encoding
+ WINDOWS_31J = 1 << 5
+
+ # u - forces the UTF-8 encoding
+ UTF_8 = 1 << 6
+
+ # o - only interpolates values into the regular expression once
+ ONCE = 1 << 7
+ end
+
+ class Visitor < BasicVisitor
+ # Visit a AliasNode node
+ alias visit_alias_node visit_child_nodes
+
+ # Visit a AlternationPatternNode node
+ alias visit_alternation_pattern_node visit_child_nodes
+
+ # Visit a AndNode node
+ alias visit_and_node visit_child_nodes
+
+ # Visit a ArgumentsNode node
+ alias visit_arguments_node visit_child_nodes
+
+ # Visit a ArrayNode node
+ alias visit_array_node visit_child_nodes
+
+ # Visit a ArrayPatternNode node
+ alias visit_array_pattern_node visit_child_nodes
+
+ # Visit a AssocNode node
+ alias visit_assoc_node visit_child_nodes
+
+ # Visit a AssocSplatNode node
+ alias visit_assoc_splat_node visit_child_nodes
+
+ # Visit a BackReferenceReadNode node
+ alias visit_back_reference_read_node visit_child_nodes
+
+ # Visit a BeginNode node
+ alias visit_begin_node visit_child_nodes
+
+ # Visit a BlockArgumentNode node
+ alias visit_block_argument_node visit_child_nodes
+
+ # Visit a BlockNode node
+ alias visit_block_node visit_child_nodes
+
+ # Visit a BlockParameterNode node
+ alias visit_block_parameter_node visit_child_nodes
+
+ # Visit a BlockParametersNode node
+ alias visit_block_parameters_node visit_child_nodes
+
+ # Visit a BreakNode node
+ alias visit_break_node visit_child_nodes
+
+ # Visit a CallNode node
+ alias visit_call_node visit_child_nodes
+
+ # Visit a CallOperatorAndWriteNode node
+ alias visit_call_operator_and_write_node visit_child_nodes
+
+ # Visit a CallOperatorOrWriteNode node
+ alias visit_call_operator_or_write_node visit_child_nodes
+
+ # Visit a CallOperatorWriteNode node
+ alias visit_call_operator_write_node visit_child_nodes
+
+ # Visit a CapturePatternNode node
+ alias visit_capture_pattern_node visit_child_nodes
+
+ # Visit a CaseNode node
+ alias visit_case_node visit_child_nodes
+
+ # Visit a ClassNode node
+ alias visit_class_node visit_child_nodes
+
+ # Visit a ClassVariableOperatorAndWriteNode node
+ alias visit_class_variable_operator_and_write_node visit_child_nodes
+
+ # Visit a ClassVariableOperatorOrWriteNode node
+ alias visit_class_variable_operator_or_write_node visit_child_nodes
+
+ # Visit a ClassVariableOperatorWriteNode node
+ alias visit_class_variable_operator_write_node visit_child_nodes
+
+ # Visit a ClassVariableReadNode node
+ alias visit_class_variable_read_node visit_child_nodes
+
+ # Visit a ClassVariableWriteNode node
+ alias visit_class_variable_write_node visit_child_nodes
+
+ # Visit a ConstantOperatorAndWriteNode node
+ alias visit_constant_operator_and_write_node visit_child_nodes
+
+ # Visit a ConstantOperatorOrWriteNode node
+ alias visit_constant_operator_or_write_node visit_child_nodes
+
+ # Visit a ConstantOperatorWriteNode node
+ alias visit_constant_operator_write_node visit_child_nodes
+
+ # Visit a ConstantPathNode node
+ alias visit_constant_path_node visit_child_nodes
+
+ # Visit a ConstantPathOperatorAndWriteNode node
+ alias visit_constant_path_operator_and_write_node visit_child_nodes
+
+ # Visit a ConstantPathOperatorOrWriteNode node
+ alias visit_constant_path_operator_or_write_node visit_child_nodes
+
+ # Visit a ConstantPathOperatorWriteNode node
+ alias visit_constant_path_operator_write_node visit_child_nodes
+
+ # Visit a ConstantPathWriteNode node
+ alias visit_constant_path_write_node visit_child_nodes
+
+ # Visit a ConstantReadNode node
+ alias visit_constant_read_node visit_child_nodes
+
+ # Visit a DefNode node
+ alias visit_def_node visit_child_nodes
+
+ # Visit a DefinedNode node
+ alias visit_defined_node visit_child_nodes
+
+ # Visit a ElseNode node
+ alias visit_else_node visit_child_nodes
+
+ # Visit a EmbeddedStatementsNode node
+ alias visit_embedded_statements_node visit_child_nodes
+
+ # Visit a EmbeddedVariableNode node
+ alias visit_embedded_variable_node visit_child_nodes
+
+ # Visit a EnsureNode node
+ alias visit_ensure_node visit_child_nodes
+
+ # Visit a FalseNode node
+ alias visit_false_node visit_child_nodes
+
+ # Visit a FindPatternNode node
+ alias visit_find_pattern_node visit_child_nodes
+
+ # Visit a FloatNode node
+ alias visit_float_node visit_child_nodes
+
+ # Visit a ForNode node
+ alias visit_for_node visit_child_nodes
+
+ # Visit a ForwardingArgumentsNode node
+ alias visit_forwarding_arguments_node visit_child_nodes
+
+ # Visit a ForwardingParameterNode node
+ alias visit_forwarding_parameter_node visit_child_nodes
+
+ # Visit a ForwardingSuperNode node
+ alias visit_forwarding_super_node visit_child_nodes
+
+ # Visit a GlobalVariableOperatorAndWriteNode node
+ alias visit_global_variable_operator_and_write_node visit_child_nodes
+
+ # Visit a GlobalVariableOperatorOrWriteNode node
+ alias visit_global_variable_operator_or_write_node visit_child_nodes
+
+ # Visit a GlobalVariableOperatorWriteNode node
+ alias visit_global_variable_operator_write_node visit_child_nodes
+
+ # Visit a GlobalVariableReadNode node
+ alias visit_global_variable_read_node visit_child_nodes
+
+ # Visit a GlobalVariableWriteNode node
+ alias visit_global_variable_write_node visit_child_nodes
+
+ # Visit a HashNode node
+ alias visit_hash_node visit_child_nodes
+
+ # Visit a HashPatternNode node
+ alias visit_hash_pattern_node visit_child_nodes
+
+ # Visit a IfNode node
+ alias visit_if_node visit_child_nodes
+
+ # Visit a ImaginaryNode node
+ alias visit_imaginary_node visit_child_nodes
+
+ # Visit a InNode node
+ alias visit_in_node visit_child_nodes
+
+ # Visit a InstanceVariableOperatorAndWriteNode node
+ alias visit_instance_variable_operator_and_write_node visit_child_nodes
+
+ # Visit a InstanceVariableOperatorOrWriteNode node
+ alias visit_instance_variable_operator_or_write_node visit_child_nodes
+
+ # Visit a InstanceVariableOperatorWriteNode node
+ alias visit_instance_variable_operator_write_node visit_child_nodes
+
+ # Visit a InstanceVariableReadNode node
+ alias visit_instance_variable_read_node visit_child_nodes
+
+ # Visit a InstanceVariableWriteNode node
+ alias visit_instance_variable_write_node visit_child_nodes
+
+ # Visit a IntegerNode node
+ alias visit_integer_node visit_child_nodes
+
+ # Visit a InterpolatedRegularExpressionNode node
+ alias visit_interpolated_regular_expression_node visit_child_nodes
+
+ # Visit a InterpolatedStringNode node
+ alias visit_interpolated_string_node visit_child_nodes
+
+ # Visit a InterpolatedSymbolNode node
+ alias visit_interpolated_symbol_node visit_child_nodes
+
+ # Visit a InterpolatedXStringNode node
+ alias visit_interpolated_x_string_node visit_child_nodes
+
+ # Visit a KeywordHashNode node
+ alias visit_keyword_hash_node visit_child_nodes
+
+ # Visit a KeywordParameterNode node
+ alias visit_keyword_parameter_node visit_child_nodes
+
+ # Visit a KeywordRestParameterNode node
+ alias visit_keyword_rest_parameter_node visit_child_nodes
+
+ # Visit a LambdaNode node
+ alias visit_lambda_node visit_child_nodes
+
+ # Visit a LocalVariableOperatorAndWriteNode node
+ alias visit_local_variable_operator_and_write_node visit_child_nodes
+
+ # Visit a LocalVariableOperatorOrWriteNode node
+ alias visit_local_variable_operator_or_write_node visit_child_nodes
+
+ # Visit a LocalVariableOperatorWriteNode node
+ alias visit_local_variable_operator_write_node visit_child_nodes
+
+ # Visit a LocalVariableReadNode node
+ alias visit_local_variable_read_node visit_child_nodes
+
+ # Visit a LocalVariableWriteNode node
+ alias visit_local_variable_write_node visit_child_nodes
+
+ # Visit a MatchPredicateNode node
+ alias visit_match_predicate_node visit_child_nodes
+
+ # Visit a MatchRequiredNode node
+ alias visit_match_required_node visit_child_nodes
+
+ # Visit a MissingNode node
+ alias visit_missing_node visit_child_nodes
+
+ # Visit a ModuleNode node
+ alias visit_module_node visit_child_nodes
+
+ # Visit a MultiWriteNode node
+ alias visit_multi_write_node visit_child_nodes
+
+ # Visit a NextNode node
+ alias visit_next_node visit_child_nodes
+
+ # Visit a NilNode node
+ alias visit_nil_node visit_child_nodes
+
+ # Visit a NoKeywordsParameterNode node
+ alias visit_no_keywords_parameter_node visit_child_nodes
+
+ # Visit a NumberedReferenceReadNode node
+ alias visit_numbered_reference_read_node visit_child_nodes
+
+ # Visit a OptionalParameterNode node
+ alias visit_optional_parameter_node visit_child_nodes
+
+ # Visit a OrNode node
+ alias visit_or_node visit_child_nodes
+
+ # Visit a ParametersNode node
+ alias visit_parameters_node visit_child_nodes
+
+ # Visit a ParenthesesNode node
+ alias visit_parentheses_node visit_child_nodes
+
+ # Visit a PinnedExpressionNode node
+ alias visit_pinned_expression_node visit_child_nodes
+
+ # Visit a PinnedVariableNode node
+ alias visit_pinned_variable_node visit_child_nodes
+
+ # Visit a PostExecutionNode node
+ alias visit_post_execution_node visit_child_nodes
+
+ # Visit a PreExecutionNode node
+ alias visit_pre_execution_node visit_child_nodes
+
+ # Visit a ProgramNode node
+ alias visit_program_node visit_child_nodes
+
+ # Visit a RangeNode node
+ alias visit_range_node visit_child_nodes
+
+ # Visit a RationalNode node
+ alias visit_rational_node visit_child_nodes
+
+ # Visit a RedoNode node
+ alias visit_redo_node visit_child_nodes
+
+ # Visit a RegularExpressionNode node
+ alias visit_regular_expression_node visit_child_nodes
+
+ # Visit a RequiredDestructuredParameterNode node
+ alias visit_required_destructured_parameter_node visit_child_nodes
+
+ # Visit a RequiredParameterNode node
+ alias visit_required_parameter_node visit_child_nodes
+
+ # Visit a RescueModifierNode node
+ alias visit_rescue_modifier_node visit_child_nodes
+
+ # Visit a RescueNode node
+ alias visit_rescue_node visit_child_nodes
+
+ # Visit a RestParameterNode node
+ alias visit_rest_parameter_node visit_child_nodes
+
+ # Visit a RetryNode node
+ alias visit_retry_node visit_child_nodes
+
+ # Visit a ReturnNode node
+ alias visit_return_node visit_child_nodes
+
+ # Visit a SelfNode node
+ alias visit_self_node visit_child_nodes
+
+ # Visit a SingletonClassNode node
+ alias visit_singleton_class_node visit_child_nodes
+
+ # Visit a SourceEncodingNode node
+ alias visit_source_encoding_node visit_child_nodes
+
+ # Visit a SourceFileNode node
+ alias visit_source_file_node visit_child_nodes
+
+ # Visit a SourceLineNode node
+ alias visit_source_line_node visit_child_nodes
+
+ # Visit a SplatNode node
+ alias visit_splat_node visit_child_nodes
+
+ # Visit a StatementsNode node
+ alias visit_statements_node visit_child_nodes
+
+ # Visit a StringConcatNode node
+ alias visit_string_concat_node visit_child_nodes
+
+ # Visit a StringNode node
+ alias visit_string_node visit_child_nodes
+
+ # Visit a SuperNode node
+ alias visit_super_node visit_child_nodes
+
+ # Visit a SymbolNode node
+ alias visit_symbol_node visit_child_nodes
+
+ # Visit a TrueNode node
+ alias visit_true_node visit_child_nodes
+
+ # Visit a UndefNode node
+ alias visit_undef_node visit_child_nodes
+
+ # Visit a UnlessNode node
+ alias visit_unless_node visit_child_nodes
+
+ # Visit a UntilNode node
+ alias visit_until_node visit_child_nodes
+
+ # Visit a WhenNode node
+ alias visit_when_node visit_child_nodes
+
+ # Visit a WhileNode node
+ alias visit_while_node visit_child_nodes
+
+ # Visit a XStringNode node
+ alias visit_x_string_node visit_child_nodes
+
+ # Visit a YieldNode node
+ alias visit_yield_node visit_child_nodes
+ end
+
+ module DSL
+ private
+
+ # Create a new Location object
+ def Location(start_offset = 0, length = 0)
+ Location.new(start_offset, length)
+ end
+
+ # Create a new AliasNode node
+ def AliasNode(new_name, old_name, keyword_loc)
+ AliasNode.new(new_name, old_name, keyword_loc, 0, 0)
+ end
+
+ # Create a new AlternationPatternNode node
+ def AlternationPatternNode(left, right, operator_loc)
+ AlternationPatternNode.new(left, right, operator_loc, 0, 0)
+ end
+
+ # Create a new AndNode node
+ def AndNode(left, right, operator_loc)
+ AndNode.new(left, right, operator_loc, 0, 0)
+ end
+
+ # Create a new ArgumentsNode node
+ def ArgumentsNode(arguments)
+ ArgumentsNode.new(arguments, 0, 0)
+ end
+
+ # Create a new ArrayNode node
+ def ArrayNode(elements, opening_loc, closing_loc)
+ ArrayNode.new(elements, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new ArrayPatternNode node
+ def ArrayPatternNode(constant, requireds, rest, posts, opening_loc, closing_loc)
+ ArrayPatternNode.new(constant, requireds, rest, posts, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new AssocNode node
+ def AssocNode(key, value, operator_loc)
+ AssocNode.new(key, value, operator_loc, 0, 0)
+ end
+
+ # Create a new AssocSplatNode node
+ def AssocSplatNode(value, operator_loc)
+ AssocSplatNode.new(value, operator_loc, 0, 0)
+ end
+
+ # Create a new BackReferenceReadNode node
+ def BackReferenceReadNode()
+ BackReferenceReadNode.new(0, 0)
+ end
+
+ # Create a new BeginNode node
+ def BeginNode(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc)
+ BeginNode.new(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new BlockArgumentNode node
+ def BlockArgumentNode(expression, operator_loc)
+ BlockArgumentNode.new(expression, operator_loc, 0, 0)
+ end
+
+ # Create a new BlockNode node
+ def BlockNode(locals, parameters, statements, opening_loc, closing_loc)
+ BlockNode.new(locals, parameters, statements, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new BlockParameterNode node
+ def BlockParameterNode(name_loc, operator_loc)
+ BlockParameterNode.new(name_loc, operator_loc, 0, 0)
+ end
+
+ # Create a new BlockParametersNode node
+ def BlockParametersNode(parameters, locals, opening_loc, closing_loc)
+ BlockParametersNode.new(parameters, locals, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new BreakNode node
+ def BreakNode(arguments, keyword_loc)
+ BreakNode.new(arguments, keyword_loc, 0, 0)
+ end
+
+ # Create a new CallNode node
+ def CallNode(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name)
+ CallNode.new(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, 0, 0)
+ end
+
+ # Create a new CallOperatorAndWriteNode node
+ def CallOperatorAndWriteNode(target, operator_loc, value)
+ CallOperatorAndWriteNode.new(target, operator_loc, value, 0, 0)
+ end
+
+ # Create a new CallOperatorOrWriteNode node
+ def CallOperatorOrWriteNode(target, value, operator_loc)
+ CallOperatorOrWriteNode.new(target, value, operator_loc, 0, 0)
+ end
+
+ # Create a new CallOperatorWriteNode node
+ def CallOperatorWriteNode(target, operator_loc, value, operator_id)
+ CallOperatorWriteNode.new(target, operator_loc, value, operator_id, 0, 0)
+ end
+
+ # Create a new CapturePatternNode node
+ def CapturePatternNode(value, target, operator_loc)
+ CapturePatternNode.new(value, target, operator_loc, 0, 0)
+ end
+
+ # Create a new CaseNode node
+ def CaseNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc)
+ CaseNode.new(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new ClassNode node
+ def ClassNode(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc)
+ ClassNode.new(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new ClassVariableOperatorAndWriteNode node
+ def ClassVariableOperatorAndWriteNode(name_loc, operator_loc, value)
+ ClassVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ClassVariableOperatorOrWriteNode node
+ def ClassVariableOperatorOrWriteNode(name_loc, operator_loc, value)
+ ClassVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ClassVariableOperatorWriteNode node
+ def ClassVariableOperatorWriteNode(name_loc, operator_loc, value, operator)
+ ClassVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0)
+ end
+
+ # Create a new ClassVariableReadNode node
+ def ClassVariableReadNode()
+ ClassVariableReadNode.new(0, 0)
+ end
+
+ # Create a new ClassVariableWriteNode node
+ def ClassVariableWriteNode(name_loc, value, operator_loc)
+ ClassVariableWriteNode.new(name_loc, value, operator_loc, 0, 0)
+ end
+
+ # Create a new ConstantOperatorAndWriteNode node
+ def ConstantOperatorAndWriteNode(name_loc, operator_loc, value)
+ ConstantOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ConstantOperatorOrWriteNode node
+ def ConstantOperatorOrWriteNode(name_loc, operator_loc, value)
+ ConstantOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ConstantOperatorWriteNode node
+ def ConstantOperatorWriteNode(name_loc, operator_loc, value, operator)
+ ConstantOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0)
+ end
+
+ # Create a new ConstantPathNode node
+ def ConstantPathNode(parent, child, delimiter_loc)
+ ConstantPathNode.new(parent, child, delimiter_loc, 0, 0)
+ end
+
+ # Create a new ConstantPathOperatorAndWriteNode node
+ def ConstantPathOperatorAndWriteNode(target, operator_loc, value)
+ ConstantPathOperatorAndWriteNode.new(target, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ConstantPathOperatorOrWriteNode node
+ def ConstantPathOperatorOrWriteNode(target, operator_loc, value)
+ ConstantPathOperatorOrWriteNode.new(target, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ConstantPathOperatorWriteNode node
+ def ConstantPathOperatorWriteNode(target, operator_loc, value, operator)
+ ConstantPathOperatorWriteNode.new(target, operator_loc, value, operator, 0, 0)
+ end
+
+ # Create a new ConstantPathWriteNode node
+ def ConstantPathWriteNode(target, operator_loc, value)
+ ConstantPathWriteNode.new(target, operator_loc, value, 0, 0)
+ end
+
+ # Create a new ConstantReadNode node
+ def ConstantReadNode()
+ ConstantReadNode.new(0, 0)
+ end
+
+ # Create a new DefNode node
+ def DefNode(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc)
+ DefNode.new(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new DefinedNode node
+ def DefinedNode(lparen_loc, value, rparen_loc, keyword_loc)
+ DefinedNode.new(lparen_loc, value, rparen_loc, keyword_loc, 0, 0)
+ end
+
+ # Create a new ElseNode node
+ def ElseNode(else_keyword_loc, statements, end_keyword_loc)
+ ElseNode.new(else_keyword_loc, statements, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new EmbeddedStatementsNode node
+ def EmbeddedStatementsNode(opening_loc, statements, closing_loc)
+ EmbeddedStatementsNode.new(opening_loc, statements, closing_loc, 0, 0)
+ end
+
+ # Create a new EmbeddedVariableNode node
+ def EmbeddedVariableNode(operator_loc, variable)
+ EmbeddedVariableNode.new(operator_loc, variable, 0, 0)
+ end
+
+ # Create a new EnsureNode node
+ def EnsureNode(ensure_keyword_loc, statements, end_keyword_loc)
+ EnsureNode.new(ensure_keyword_loc, statements, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new FalseNode node
+ def FalseNode()
+ FalseNode.new(0, 0)
+ end
+
+ # Create a new FindPatternNode node
+ def FindPatternNode(constant, left, requireds, right, opening_loc, closing_loc)
+ FindPatternNode.new(constant, left, requireds, right, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new FloatNode node
+ def FloatNode()
+ FloatNode.new(0, 0)
+ end
+
+ # Create a new ForNode node
+ def ForNode(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc)
+ ForNode.new(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new ForwardingArgumentsNode node
+ def ForwardingArgumentsNode()
+ ForwardingArgumentsNode.new(0, 0)
+ end
+
+ # Create a new ForwardingParameterNode node
+ def ForwardingParameterNode()
+ ForwardingParameterNode.new(0, 0)
+ end
+
+ # Create a new ForwardingSuperNode node
+ def ForwardingSuperNode(block)
+ ForwardingSuperNode.new(block, 0, 0)
+ end
+
+ # Create a new GlobalVariableOperatorAndWriteNode node
+ def GlobalVariableOperatorAndWriteNode(name_loc, operator_loc, value)
+ GlobalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new GlobalVariableOperatorOrWriteNode node
+ def GlobalVariableOperatorOrWriteNode(name_loc, operator_loc, value)
+ GlobalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new GlobalVariableOperatorWriteNode node
+ def GlobalVariableOperatorWriteNode(name_loc, operator_loc, value, operator)
+ GlobalVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0)
+ end
+
+ # Create a new GlobalVariableReadNode node
+ def GlobalVariableReadNode()
+ GlobalVariableReadNode.new(0, 0)
+ end
+
+ # Create a new GlobalVariableWriteNode node
+ def GlobalVariableWriteNode(name_loc, operator_loc, value)
+ GlobalVariableWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new HashNode node
+ def HashNode(opening_loc, elements, closing_loc)
+ HashNode.new(opening_loc, elements, closing_loc, 0, 0)
+ end
+
+ # Create a new HashPatternNode node
+ def HashPatternNode(constant, assocs, kwrest, opening_loc, closing_loc)
+ HashPatternNode.new(constant, assocs, kwrest, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new IfNode node
+ def IfNode(if_keyword_loc, predicate, statements, consequent, end_keyword_loc)
+ IfNode.new(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new ImaginaryNode node
+ def ImaginaryNode(numeric)
+ ImaginaryNode.new(numeric, 0, 0)
+ end
+
+ # Create a new InNode node
+ def InNode(pattern, statements, in_loc, then_loc)
+ InNode.new(pattern, statements, in_loc, then_loc, 0, 0)
+ end
+
+ # Create a new InstanceVariableOperatorAndWriteNode node
+ def InstanceVariableOperatorAndWriteNode(name_loc, operator_loc, value)
+ InstanceVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new InstanceVariableOperatorOrWriteNode node
+ def InstanceVariableOperatorOrWriteNode(name_loc, operator_loc, value)
+ InstanceVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new InstanceVariableOperatorWriteNode node
+ def InstanceVariableOperatorWriteNode(name_loc, operator_loc, value, operator)
+ InstanceVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0)
+ end
+
+ # Create a new InstanceVariableReadNode node
+ def InstanceVariableReadNode()
+ InstanceVariableReadNode.new(0, 0)
+ end
+
+ # Create a new InstanceVariableWriteNode node
+ def InstanceVariableWriteNode(name_loc, value, operator_loc)
+ InstanceVariableWriteNode.new(name_loc, value, operator_loc, 0, 0)
+ end
+
+ # Create a new IntegerNode node
+ def IntegerNode()
+ IntegerNode.new(0, 0)
+ end
+
+ # Create a new InterpolatedRegularExpressionNode node
+ def InterpolatedRegularExpressionNode(opening_loc, parts, closing_loc, flags)
+ InterpolatedRegularExpressionNode.new(opening_loc, parts, closing_loc, flags, 0, 0)
+ end
+
+ # Create a new InterpolatedStringNode node
+ def InterpolatedStringNode(opening_loc, parts, closing_loc)
+ InterpolatedStringNode.new(opening_loc, parts, closing_loc, 0, 0)
+ end
+
+ # Create a new InterpolatedSymbolNode node
+ def InterpolatedSymbolNode(opening_loc, parts, closing_loc)
+ InterpolatedSymbolNode.new(opening_loc, parts, closing_loc, 0, 0)
+ end
+
+ # Create a new InterpolatedXStringNode node
+ def InterpolatedXStringNode(opening_loc, parts, closing_loc)
+ InterpolatedXStringNode.new(opening_loc, parts, closing_loc, 0, 0)
+ end
+
+ # Create a new KeywordHashNode node
+ def KeywordHashNode(elements)
+ KeywordHashNode.new(elements, 0, 0)
+ end
+
+ # Create a new KeywordParameterNode node
+ def KeywordParameterNode(name_loc, value)
+ KeywordParameterNode.new(name_loc, value, 0, 0)
+ end
+
+ # Create a new KeywordRestParameterNode node
+ def KeywordRestParameterNode(operator_loc, name_loc)
+ KeywordRestParameterNode.new(operator_loc, name_loc, 0, 0)
+ end
+
+ # Create a new LambdaNode node
+ def LambdaNode(locals, opening_loc, parameters, statements)
+ LambdaNode.new(locals, opening_loc, parameters, statements, 0, 0)
+ end
+
+ # Create a new LocalVariableOperatorAndWriteNode node
+ def LocalVariableOperatorAndWriteNode(name_loc, operator_loc, value, constant_id)
+ LocalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, constant_id, 0, 0)
+ end
+
+ # Create a new LocalVariableOperatorOrWriteNode node
+ def LocalVariableOperatorOrWriteNode(name_loc, operator_loc, value, constant_id)
+ LocalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, constant_id, 0, 0)
+ end
+
+ # Create a new LocalVariableOperatorWriteNode node
+ def LocalVariableOperatorWriteNode(name_loc, operator_loc, value, constant_id, operator_id)
+ LocalVariableOperatorWriteNode.new(name_loc, operator_loc, value, constant_id, operator_id, 0, 0)
+ end
+
+ # Create a new LocalVariableReadNode node
+ def LocalVariableReadNode(constant_id, depth)
+ LocalVariableReadNode.new(constant_id, depth, 0, 0)
+ end
+
+ # Create a new LocalVariableWriteNode node
+ def LocalVariableWriteNode(constant_id, depth, value, name_loc, operator_loc)
+ LocalVariableWriteNode.new(constant_id, depth, value, name_loc, operator_loc, 0, 0)
+ end
+
+ # Create a new MatchPredicateNode node
+ def MatchPredicateNode(value, pattern, operator_loc)
+ MatchPredicateNode.new(value, pattern, operator_loc, 0, 0)
+ end
+
+ # Create a new MatchRequiredNode node
+ def MatchRequiredNode(value, pattern, operator_loc)
+ MatchRequiredNode.new(value, pattern, operator_loc, 0, 0)
+ end
+
+ # Create a new MissingNode node
+ def MissingNode()
+ MissingNode.new(0, 0)
+ end
+
+ # Create a new ModuleNode node
+ def ModuleNode(locals, module_keyword_loc, constant_path, statements, end_keyword_loc)
+ ModuleNode.new(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new MultiWriteNode node
+ def MultiWriteNode(targets, operator_loc, value, lparen_loc, rparen_loc)
+ MultiWriteNode.new(targets, operator_loc, value, lparen_loc, rparen_loc, 0, 0)
+ end
+
+ # Create a new NextNode node
+ def NextNode(arguments, keyword_loc)
+ NextNode.new(arguments, keyword_loc, 0, 0)
+ end
+
+ # Create a new NilNode node
+ def NilNode()
+ NilNode.new(0, 0)
+ end
+
+ # Create a new NoKeywordsParameterNode node
+ def NoKeywordsParameterNode(operator_loc, keyword_loc)
+ NoKeywordsParameterNode.new(operator_loc, keyword_loc, 0, 0)
+ end
+
+ # Create a new NumberedReferenceReadNode node
+ def NumberedReferenceReadNode()
+ NumberedReferenceReadNode.new(0, 0)
+ end
+
+ # Create a new OptionalParameterNode node
+ def OptionalParameterNode(constant_id, name_loc, operator_loc, value)
+ OptionalParameterNode.new(constant_id, name_loc, operator_loc, value, 0, 0)
+ end
+
+ # Create a new OrNode node
+ def OrNode(left, right, operator_loc)
+ OrNode.new(left, right, operator_loc, 0, 0)
+ end
+
+ # Create a new ParametersNode node
+ def ParametersNode(requireds, optionals, posts, rest, keywords, keyword_rest, block)
+ ParametersNode.new(requireds, optionals, posts, rest, keywords, keyword_rest, block, 0, 0)
+ end
+
+ # Create a new ParenthesesNode node
+ def ParenthesesNode(statements, opening_loc, closing_loc)
+ ParenthesesNode.new(statements, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new PinnedExpressionNode node
+ def PinnedExpressionNode(expression, operator_loc, lparen_loc, rparen_loc)
+ PinnedExpressionNode.new(expression, operator_loc, lparen_loc, rparen_loc, 0, 0)
+ end
+
+ # Create a new PinnedVariableNode node
+ def PinnedVariableNode(variable, operator_loc)
+ PinnedVariableNode.new(variable, operator_loc, 0, 0)
+ end
+
+ # Create a new PostExecutionNode node
+ def PostExecutionNode(statements, keyword_loc, opening_loc, closing_loc)
+ PostExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new PreExecutionNode node
+ def PreExecutionNode(statements, keyword_loc, opening_loc, closing_loc)
+ PreExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new ProgramNode node
+ def ProgramNode(locals, statements)
+ ProgramNode.new(locals, statements, 0, 0)
+ end
+
+ # Create a new RangeNode node
+ def RangeNode(left, right, operator_loc, flags)
+ RangeNode.new(left, right, operator_loc, flags, 0, 0)
+ end
+
+ # Create a new RationalNode node
+ def RationalNode(numeric)
+ RationalNode.new(numeric, 0, 0)
+ end
+
+ # Create a new RedoNode node
+ def RedoNode()
+ RedoNode.new(0, 0)
+ end
+
+ # Create a new RegularExpressionNode node
+ def RegularExpressionNode(opening_loc, content_loc, closing_loc, unescaped, flags)
+ RegularExpressionNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, 0, 0)
+ end
+
+ # Create a new RequiredDestructuredParameterNode node
+ def RequiredDestructuredParameterNode(parameters, opening_loc, closing_loc)
+ RequiredDestructuredParameterNode.new(parameters, opening_loc, closing_loc, 0, 0)
+ end
+
+ # Create a new RequiredParameterNode node
+ def RequiredParameterNode(constant_id)
+ RequiredParameterNode.new(constant_id, 0, 0)
+ end
+
+ # Create a new RescueModifierNode node
+ def RescueModifierNode(expression, keyword_loc, rescue_expression)
+ RescueModifierNode.new(expression, keyword_loc, rescue_expression, 0, 0)
+ end
+
+ # Create a new RescueNode node
+ def RescueNode(keyword_loc, exceptions, operator_loc, exception, statements, consequent)
+ RescueNode.new(keyword_loc, exceptions, operator_loc, exception, statements, consequent, 0, 0)
+ end
+
+ # Create a new RestParameterNode node
+ def RestParameterNode(operator_loc, name_loc)
+ RestParameterNode.new(operator_loc, name_loc, 0, 0)
+ end
+
+ # Create a new RetryNode node
+ def RetryNode()
+ RetryNode.new(0, 0)
+ end
+
+ # Create a new ReturnNode node
+ def ReturnNode(keyword_loc, arguments)
+ ReturnNode.new(keyword_loc, arguments, 0, 0)
+ end
+
+ # Create a new SelfNode node
+ def SelfNode()
+ SelfNode.new(0, 0)
+ end
+
+ # Create a new SingletonClassNode node
+ def SingletonClassNode(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc)
+ SingletonClassNode.new(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new SourceEncodingNode node
+ def SourceEncodingNode()
+ SourceEncodingNode.new(0, 0)
+ end
+
+ # Create a new SourceFileNode node
+ def SourceFileNode(filepath)
+ SourceFileNode.new(filepath, 0, 0)
+ end
+
+ # Create a new SourceLineNode node
+ def SourceLineNode()
+ SourceLineNode.new(0, 0)
+ end
+
+ # Create a new SplatNode node
+ def SplatNode(operator_loc, expression)
+ SplatNode.new(operator_loc, expression, 0, 0)
+ end
+
+ # Create a new StatementsNode node
+ def StatementsNode(body)
+ StatementsNode.new(body, 0, 0)
+ end
+
+ # Create a new StringConcatNode node
+ def StringConcatNode(left, right)
+ StringConcatNode.new(left, right, 0, 0)
+ end
+
+ # Create a new StringNode node
+ def StringNode(opening_loc, content_loc, closing_loc, unescaped)
+ StringNode.new(opening_loc, content_loc, closing_loc, unescaped, 0, 0)
+ end
+
+ # Create a new SuperNode node
+ def SuperNode(keyword_loc, lparen_loc, arguments, rparen_loc, block)
+ SuperNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, block, 0, 0)
+ end
+
+ # Create a new SymbolNode node
+ def SymbolNode(opening_loc, value_loc, closing_loc, unescaped)
+ SymbolNode.new(opening_loc, value_loc, closing_loc, unescaped, 0, 0)
+ end
+
+ # Create a new TrueNode node
+ def TrueNode()
+ TrueNode.new(0, 0)
+ end
+
+ # Create a new UndefNode node
+ def UndefNode(names, keyword_loc)
+ UndefNode.new(names, keyword_loc, 0, 0)
+ end
+
+ # Create a new UnlessNode node
+ def UnlessNode(keyword_loc, predicate, statements, consequent, end_keyword_loc)
+ UnlessNode.new(keyword_loc, predicate, statements, consequent, end_keyword_loc, 0, 0)
+ end
+
+ # Create a new UntilNode node
+ def UntilNode(keyword_loc, predicate, statements)
+ UntilNode.new(keyword_loc, predicate, statements, 0, 0)
+ end
+
+ # Create a new WhenNode node
+ def WhenNode(keyword_loc, conditions, statements)
+ WhenNode.new(keyword_loc, conditions, statements, 0, 0)
+ end
+
+ # Create a new WhileNode node
+ def WhileNode(keyword_loc, predicate, statements)
+ WhileNode.new(keyword_loc, predicate, statements, 0, 0)
+ end
+
+ # Create a new XStringNode node
+ def XStringNode(opening_loc, content_loc, closing_loc, unescaped)
+ XStringNode.new(opening_loc, content_loc, closing_loc, unescaped, 0, 0)
+ end
+
+ # Create a new YieldNode node
+ def YieldNode(keyword_loc, lparen_loc, arguments, rparen_loc)
+ YieldNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, 0, 0)
+ end
+ end
+end
diff --git a/lib/yarp/pack.rb b/lib/yarp/pack.rb
new file mode 100644
index 0000000000..83f5569923
--- /dev/null
+++ b/lib/yarp/pack.rb
@@ -0,0 +1,185 @@
+# frozen_string_literal: true
+
+module YARP
+ module Pack
+ %i[
+ SPACE
+ COMMENT
+ INTEGER
+ UTF8
+ BER
+ FLOAT
+ STRING_SPACE_PADDED
+ STRING_NULL_PADDED
+ STRING_NULL_TERMINATED
+ STRING_MSB
+ STRING_LSB
+ STRING_HEX_HIGH
+ STRING_HEX_LOW
+ STRING_UU
+ STRING_MIME
+ STRING_BASE64
+ STRING_FIXED
+ STRING_POINTER
+ MOVE
+ BACK
+ NULL
+
+ UNSIGNED
+ SIGNED
+ SIGNED_NA
+
+ AGNOSTIC_ENDIAN
+ LITTLE_ENDIAN
+ BIG_ENDIAN
+ NATIVE_ENDIAN
+ ENDIAN_NA
+
+ SIZE_SHORT
+ SIZE_INT
+ SIZE_LONG
+ SIZE_LONG_LONG
+ SIZE_8
+ SIZE_16
+ SIZE_32
+ SIZE_64
+ SIZE_P
+ SIZE_NA
+
+ LENGTH_FIXED
+ LENGTH_MAX
+ LENGTH_RELATIVE
+ LENGTH_NA
+ ].each do |const|
+ const_set(const, const)
+ end
+
+ class Directive
+ attr_reader :version, :variant, :source, :type, :signed, :endian, :size, :length_type, :length
+
+ def initialize(version, variant, source, type, signed, endian, size, length_type, length)
+ @version = version
+ @variant = variant
+ @source = source
+ @type = type
+ @signed = signed
+ @endian = endian
+ @size = size
+ @length_type = length_type
+ @length = length
+ end
+
+ ENDIAN_DESCRIPTIONS = {
+ AGNOSTIC_ENDIAN: 'agnostic',
+ LITTLE_ENDIAN: 'little-endian (VAX)',
+ BIG_ENDIAN: 'big-endian (network)',
+ NATIVE_ENDIAN: 'native-endian',
+ ENDIAN_NA: 'n/a'
+ }
+
+ SIGNED_DESCRIPTIONS = {
+ UNSIGNED: 'unsigned',
+ SIGNED: 'signed',
+ SIGNED_NA: 'n/a'
+ }
+
+ SIZE_DESCRIPTIONS = {
+ SIZE_SHORT: 'short',
+ SIZE_INT: 'int-width',
+ SIZE_LONG: 'long',
+ SIZE_LONG_LONG: 'long long',
+ SIZE_8: '8-bit',
+ SIZE_16: '16-bit',
+ SIZE_32: '32-bit',
+ SIZE_64: '64-bit',
+ SIZE_P: 'pointer-width'
+ }
+
+ def describe
+ case type
+ when SPACE
+ 'whitespace'
+ when COMMENT
+ 'comment'
+ when INTEGER
+ if size == SIZE_8
+ base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} integer"
+ else
+ base = "#{SIGNED_DESCRIPTIONS[signed]} #{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} integer"
+ end
+ case length_type
+ when LENGTH_FIXED
+ if length > 1
+ base + ", x#{length}"
+ else
+ base
+ end
+ when LENGTH_MAX
+ base + ', as many as possible'
+ end
+ when UTF8
+ 'UTF-8 character'
+ when BER
+ 'BER-compressed integer'
+ when FLOAT
+ "#{SIZE_DESCRIPTIONS[size]} #{ENDIAN_DESCRIPTIONS[endian]} float"
+ when STRING_SPACE_PADDED
+ 'arbitrary binary string (space padded)'
+ when STRING_NULL_PADDED
+ 'arbitrary binary string (null padded, count is width)'
+ when STRING_NULL_TERMINATED
+ 'arbitrary binary string (null padded, count is width), except that null is added with *'
+ when STRING_MSB
+ 'bit string (MSB first)'
+ when STRING_LSB
+ 'bit string (LSB first)'
+ when STRING_HEX_HIGH
+ 'hex string (high nibble first)'
+ when STRING_HEX_LOW
+ 'hex string (low nibble first)'
+ when STRING_UU
+ 'UU-encoded string'
+ when STRING_MIME
+ 'quoted printable, MIME encoding'
+ when STRING_BASE64
+ 'base64 encoded string'
+ when STRING_FIXED
+ 'pointer to a structure (fixed-length string)'
+ when STRING_POINTER
+ 'pointer to a null-terminated string'
+ when MOVE
+ 'move to absolute position'
+ when BACK
+ 'back up a byte'
+ when NULL
+ 'null byte'
+ else
+ raise
+ end
+ end
+ end
+
+ class Format
+ attr_reader :directives, :encoding
+
+ def initialize(directives, encoding)
+ @directives = directives
+ @encoding = encoding
+ end
+
+ def describe
+ source_width = directives.map { |d| d.source.inspect.length }.max
+ directive_lines = directives.map do |directive|
+ if directive.type == SPACE
+ source = directive.source.inspect
+ else
+ source = directive.source
+ end
+ " #{source.ljust(source_width)} #{directive.describe}"
+ end
+
+ (['Directives:'] + directive_lines + ['Encoding:', " #{encoding}"]).join("\n")
+ end
+ end
+ end
+end
diff --git a/lib/yarp/ripper_compat.rb b/lib/yarp/ripper_compat.rb
new file mode 100644
index 0000000000..f29f7a1bf1
--- /dev/null
+++ b/lib/yarp/ripper_compat.rb
@@ -0,0 +1,174 @@
+# frozen_string_literal: true
+
+require "ripper"
+
+module YARP
+ # This class is meant to provide a compatibility layer between YARP and
+ # Ripper. It functions by parsing the entire tree first and then walking it
+ # and executing each of the Ripper callbacks as it goes.
+ #
+ # This class is going to necessarily be slower than the native Ripper API. It
+ # is meant as a stopgap until developers migrate to using YARP. It is also
+ # meant as a test harness for the YARP parser.
+ class RipperCompat
+ # This class mirrors the ::Ripper::SexpBuilder subclass of ::Ripper that
+ # returns the arrays of [type, *children].
+ class SexpBuilder < RipperCompat
+ private
+
+ Ripper::PARSER_EVENTS.each do |event|
+ define_method(:"on_#{event}") do |*args|
+ [event, *args]
+ end
+ end
+
+ Ripper::SCANNER_EVENTS.each do |event|
+ define_method(:"on_#{event}") do |value|
+ [:"@#{event}", value, [lineno, column]]
+ end
+ end
+ end
+
+ # This class mirrors the ::Ripper::SexpBuilderPP subclass of ::Ripper that
+ # returns the same values as ::Ripper::SexpBuilder except with a couple of
+ # niceties that flatten linked lists into arrays.
+ class SexpBuilderPP < SexpBuilder
+ private
+
+ def _dispatch_event_new
+ []
+ end
+
+ def _dispatch_event_push(list, item)
+ list << item
+ list
+ end
+
+ Ripper::PARSER_EVENT_TABLE.each do |event, arity|
+ case event
+ when /_new\z/
+ alias :"on_#{event}" :_dispatch_event_new if arity == 0
+ when /_add\z/
+ alias :"on_#{event}" :_dispatch_event_push
+ end
+ end
+ end
+
+ attr_reader :source, :lineno, :column
+
+ def initialize(source)
+ @source = source
+ @result = nil
+ @lineno = nil
+ @column = nil
+ end
+
+ ############################################################################
+ # Public interface
+ ############################################################################
+
+ def error?
+ result.errors.any?
+ end
+
+ def parse
+ result.value.accept(self) unless error?
+ end
+
+ ############################################################################
+ # Visitor methods
+ ############################################################################
+
+ def visit(node)
+ node&.accept(self)
+ end
+
+ def visit_call_node(node)
+ if !node.opening_loc && node.arguments.arguments.length == 1
+ bounds(node.receiver.location)
+ left = visit(node.receiver)
+
+ bounds(node.arguments.arguments.first.location)
+ right = visit(node.arguments.arguments.first)
+
+ on_binary(left, source[node.message_loc.start_offset...node.message_loc.end_offset].to_sym, right)
+ else
+ raise NotImplementedError
+ end
+ end
+
+ def visit_integer_node(node)
+ bounds(node.location)
+ on_int(source[node.location.start_offset...node.location.end_offset])
+ end
+
+ def visit_statements_node(node)
+ bounds(node.location)
+ node.body.inject(on_stmts_new) do |stmts, stmt|
+ on_stmts_add(stmts, visit(stmt))
+ end
+ end
+
+ def visit_token(node)
+ bounds(node.location)
+
+ case node.type
+ when :MINUS
+ on_op(node.value)
+ when :PLUS
+ on_op(node.value)
+ else
+ raise NotImplementedError, "Unknown token: #{node.type}"
+ end
+ end
+
+ def visit_program_node(node)
+ bounds(node.location)
+ on_program(visit(node.statements))
+ end
+
+ ############################################################################
+ # Entrypoints for subclasses
+ ############################################################################
+
+ # This is a convenience method that runs the SexpBuilder subclass parser.
+ def self.sexp_raw(source)
+ SexpBuilder.new(source).parse
+ end
+
+ # This is a convenience method that runs the SexpBuilderPP subclass parser.
+ def self.sexp(source)
+ SexpBuilderPP.new(source).parse
+ end
+
+ private
+
+ # This method is responsible for updating lineno and column information
+ # to reflect the current node.
+ #
+ # This method could be drastically improved with some caching on the start
+ # of every line, but for now it's good enough.
+ def bounds(location)
+ start_offset = location.start_offset
+
+ @lineno = source[0..start_offset].count("\n") + 1
+ @column = start_offset - (source.rindex("\n", start_offset) || 0)
+ end
+
+ def result
+ @result ||= YARP.parse(source)
+ end
+
+ def _dispatch0; end
+ def _dispatch1(_); end
+ def _dispatch2(_, _); end
+ def _dispatch3(_, _, _); end
+ def _dispatch4(_, _, _, _); end
+ def _dispatch5(_, _, _, _, _); end
+ def _dispatch7(_, _, _, _, _, _, _); end
+
+ (Ripper::SCANNER_EVENT_TABLE.merge(Ripper::PARSER_EVENT_TABLE)).each do |event, arity|
+ alias :"on_#{event}" :"_dispatch#{arity}"
+ end
+ end
+end
diff --git a/lib/yarp/serialize.rb b/lib/yarp/serialize.rb
new file mode 100644
index 0000000000..f6861f24b5
--- /dev/null
+++ b/lib/yarp/serialize.rb
@@ -0,0 +1,367 @@
+# frozen_string_literal: true
+=begin
+This file is generated by the bin/template script and should not be
+modified manually. See templates/lib/yarp/serialize.rb.erb
+if you are looking to modify the template
+=end
+
+require "stringio"
+
+module YARP
+ module Serialize
+ def self.load(source, serialized)
+ io = StringIO.new(serialized)
+ io.set_encoding(Encoding::BINARY)
+
+ Loader.new(source, serialized, io).load
+ end
+
+ class Loader
+ attr_reader :encoding, :source, :serialized, :io
+ attr_reader :constant_pool_offset, :constant_pool
+
+ def initialize(source, serialized, io)
+ @encoding = Encoding::UTF_8
+
+ @source = source.dup
+ @serialized = serialized
+ @io = io
+
+ @constant_pool_offset = nil
+ @constant_pool = nil
+ end
+
+ def load
+ io.read(4) => "YARP"
+ io.read(3).unpack("C3") => [0, 4, 0]
+
+ @encoding = Encoding.find(io.read(load_varint))
+ @source = source.force_encoding(@encoding).freeze
+
+ @constant_pool_offset = io.read(4).unpack1("L")
+ @constant_pool = Array.new(load_varint, nil)
+
+ load_node
+ end
+
+ private
+
+ # variable-length integer using https://en.wikipedia.org/wiki/LEB128
+ # This is also what protobuf uses: https://protobuf.dev/programming-guides/encoding/#varints
+ def load_varint
+ n = io.getbyte
+ if n < 128
+ n
+ else
+ n -= 128
+ shift = 0
+ while (b = io.getbyte) >= 128
+ n += (b - 128) << (shift += 7)
+ end
+ n + (b << (shift + 7))
+ end
+ end
+
+ def load_serialized_length
+ io.read(4).unpack1("L")
+ end
+
+ def load_optional_node
+ if io.getbyte != 0
+ io.pos -= 1
+ load_node
+ end
+ end
+
+ def load_string
+ io.read(load_varint).force_encoding(encoding)
+ end
+
+ def load_location
+ Location.new(load_varint, load_varint)
+ end
+
+ def load_optional_location
+ load_location if io.getbyte != 0
+ end
+
+ def load_constant
+ index = load_varint - 1
+ constant = constant_pool[index]
+
+ unless constant
+ offset = constant_pool_offset + index * 8
+
+ start = serialized.unpack1("L", offset: offset)
+ length = serialized.unpack1("L", offset: offset + 4)
+
+ constant = source.byteslice(start, length).to_sym
+ constant_pool[index] = constant
+ end
+
+ constant
+ end
+
+ def load_node
+ type = io.getbyte
+ start_offset, length = load_varint, load_varint
+
+ case type
+ when 1 then
+ AliasNode.new(load_node, load_node, load_location, start_offset, length)
+ when 2 then
+ AlternationPatternNode.new(load_node, load_node, load_location, start_offset, length)
+ when 3 then
+ AndNode.new(load_node, load_node, load_location, start_offset, length)
+ when 4 then
+ ArgumentsNode.new(Array.new(load_varint) { load_node }, start_offset, length)
+ when 5 then
+ ArrayNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length)
+ when 6 then
+ ArrayPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length)
+ when 7 then
+ AssocNode.new(load_node, load_optional_node, load_optional_location, start_offset, length)
+ when 8 then
+ AssocSplatNode.new(load_optional_node, load_location, start_offset, length)
+ when 9 then
+ BackReferenceReadNode.new(start_offset, length)
+ when 10 then
+ BeginNode.new(load_optional_location, load_optional_node, load_optional_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length)
+ when 11 then
+ BlockArgumentNode.new(load_optional_node, load_location, start_offset, length)
+ when 12 then
+ BlockNode.new(Array.new(load_varint) { load_constant }, load_optional_node, load_optional_node, load_location, load_location, start_offset, length)
+ when 13 then
+ BlockParameterNode.new(load_optional_location, load_location, start_offset, length)
+ when 14 then
+ BlockParametersNode.new(load_optional_node, Array.new(load_varint) { load_location }, load_optional_location, load_optional_location, start_offset, length)
+ when 15 then
+ BreakNode.new(load_optional_node, load_location, start_offset, length)
+ when 16 then
+ CallNode.new(load_optional_node, load_optional_location, load_optional_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, load_varint, load_string, start_offset, length)
+ when 17 then
+ CallOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length)
+ when 18 then
+ CallOperatorOrWriteNode.new(load_node, load_node, load_location, start_offset, length)
+ when 19 then
+ CallOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length)
+ when 20 then
+ CapturePatternNode.new(load_node, load_node, load_location, start_offset, length)
+ when 21 then
+ CaseNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_location, load_location, start_offset, length)
+ when 22 then
+ ClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_location, load_optional_node, load_optional_node, load_location, start_offset, length)
+ when 23 then
+ ClassVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 24 then
+ ClassVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 25 then
+ ClassVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 26 then
+ ClassVariableReadNode.new(start_offset, length)
+ when 27 then
+ ClassVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length)
+ when 28 then
+ ConstantOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 29 then
+ ConstantOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 30 then
+ ConstantOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 31 then
+ ConstantPathNode.new(load_optional_node, load_node, load_location, start_offset, length)
+ when 32 then
+ ConstantPathOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length)
+ when 33 then
+ ConstantPathOperatorOrWriteNode.new(load_node, load_location, load_node, start_offset, length)
+ when 34 then
+ ConstantPathOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length)
+ when 35 then
+ ConstantPathWriteNode.new(load_node, load_optional_location, load_optional_node, start_offset, length)
+ when 36 then
+ ConstantReadNode.new(start_offset, length)
+ when 37 then
+ load_serialized_length
+ DefNode.new(load_location, load_optional_node, load_optional_node, load_optional_node, Array.new(load_varint) { load_constant }, load_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, start_offset, length)
+ when 38 then
+ DefinedNode.new(load_optional_location, load_node, load_optional_location, load_location, start_offset, length)
+ when 39 then
+ ElseNode.new(load_location, load_optional_node, load_optional_location, start_offset, length)
+ when 40 then
+ EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, start_offset, length)
+ when 41 then
+ EmbeddedVariableNode.new(load_location, load_node, start_offset, length)
+ when 42 then
+ EnsureNode.new(load_location, load_optional_node, load_location, start_offset, length)
+ when 43 then
+ FalseNode.new(start_offset, length)
+ when 44 then
+ FindPatternNode.new(load_optional_node, load_node, Array.new(load_varint) { load_node }, load_node, load_optional_location, load_optional_location, start_offset, length)
+ when 45 then
+ FloatNode.new(start_offset, length)
+ when 46 then
+ ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, start_offset, length)
+ when 47 then
+ ForwardingArgumentsNode.new(start_offset, length)
+ when 48 then
+ ForwardingParameterNode.new(start_offset, length)
+ when 49 then
+ ForwardingSuperNode.new(load_optional_node, start_offset, length)
+ when 50 then
+ GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 51 then
+ GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 52 then
+ GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 53 then
+ GlobalVariableReadNode.new(start_offset, length)
+ when 54 then
+ GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, start_offset, length)
+ when 55 then
+ HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length)
+ when 56 then
+ HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, start_offset, length)
+ when 57 then
+ IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length)
+ when 58 then
+ ImaginaryNode.new(load_node, start_offset, length)
+ when 59 then
+ InNode.new(load_node, load_optional_node, load_location, load_optional_location, start_offset, length)
+ when 60 then
+ InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 61 then
+ InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length)
+ when 62 then
+ InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 63 then
+ InstanceVariableReadNode.new(start_offset, length)
+ when 64 then
+ InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length)
+ when 65 then
+ IntegerNode.new(start_offset, length)
+ when 66 then
+ InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, start_offset, length)
+ when 67 then
+ InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length)
+ when 68 then
+ InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length)
+ when 69 then
+ InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length)
+ when 70 then
+ KeywordHashNode.new(Array.new(load_varint) { load_node }, start_offset, length)
+ when 71 then
+ KeywordParameterNode.new(load_location, load_optional_node, start_offset, length)
+ when 72 then
+ KeywordRestParameterNode.new(load_location, load_optional_location, start_offset, length)
+ when 73 then
+ LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, start_offset, length)
+ when 74 then
+ LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 75 then
+ LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length)
+ when 76 then
+ LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, start_offset, length)
+ when 77 then
+ LocalVariableReadNode.new(load_constant, load_varint, start_offset, length)
+ when 78 then
+ LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, start_offset, length)
+ when 79 then
+ MatchPredicateNode.new(load_node, load_node, load_location, start_offset, length)
+ when 80 then
+ MatchRequiredNode.new(load_node, load_node, load_location, start_offset, length)
+ when 81 then
+ MissingNode.new(start_offset, length)
+ when 82 then
+ ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_node, load_location, start_offset, length)
+ when 83 then
+ MultiWriteNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_location, load_optional_location, start_offset, length)
+ when 84 then
+ NextNode.new(load_optional_node, load_location, start_offset, length)
+ when 85 then
+ NilNode.new(start_offset, length)
+ when 86 then
+ NoKeywordsParameterNode.new(load_location, load_location, start_offset, length)
+ when 87 then
+ NumberedReferenceReadNode.new(start_offset, length)
+ when 88 then
+ OptionalParameterNode.new(load_constant, load_location, load_location, load_node, start_offset, length)
+ when 89 then
+ OrNode.new(load_node, load_node, load_location, start_offset, length)
+ when 90 then
+ ParametersNode.new(Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_node, start_offset, length)
+ when 91 then
+ ParenthesesNode.new(load_optional_node, load_location, load_location, start_offset, length)
+ when 92 then
+ PinnedExpressionNode.new(load_node, load_location, load_location, load_location, start_offset, length)
+ when 93 then
+ PinnedVariableNode.new(load_node, load_location, start_offset, length)
+ when 94 then
+ PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length)
+ when 95 then
+ PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length)
+ when 96 then
+ ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, start_offset, length)
+ when 97 then
+ RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, start_offset, length)
+ when 98 then
+ RationalNode.new(load_node, start_offset, length)
+ when 99 then
+ RedoNode.new(start_offset, length)
+ when 100 then
+ RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, start_offset, length)
+ when 101 then
+ RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, start_offset, length)
+ when 102 then
+ RequiredParameterNode.new(load_constant, start_offset, length)
+ when 103 then
+ RescueModifierNode.new(load_node, load_location, load_node, start_offset, length)
+ when 104 then
+ RescueNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_node, load_optional_node, start_offset, length)
+ when 105 then
+ RestParameterNode.new(load_location, load_optional_location, start_offset, length)
+ when 106 then
+ RetryNode.new(start_offset, length)
+ when 107 then
+ ReturnNode.new(load_location, load_optional_node, start_offset, length)
+ when 108 then
+ SelfNode.new(start_offset, length)
+ when 109 then
+ SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, start_offset, length)
+ when 110 then
+ SourceEncodingNode.new(start_offset, length)
+ when 111 then
+ SourceFileNode.new(load_string, start_offset, length)
+ when 112 then
+ SourceLineNode.new(start_offset, length)
+ when 113 then
+ SplatNode.new(load_location, load_optional_node, start_offset, length)
+ when 114 then
+ StatementsNode.new(Array.new(load_varint) { load_node }, start_offset, length)
+ when 115 then
+ StringConcatNode.new(load_node, load_node, start_offset, length)
+ when 116 then
+ StringNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length)
+ when 117 then
+ SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, start_offset, length)
+ when 118 then
+ SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length)
+ when 119 then
+ TrueNode.new(start_offset, length)
+ when 120 then
+ UndefNode.new(Array.new(load_varint) { load_node }, load_location, start_offset, length)
+ when 121 then
+ UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length)
+ when 122 then
+ UntilNode.new(load_location, load_node, load_optional_node, start_offset, length)
+ when 123 then
+ WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, start_offset, length)
+ when 124 then
+ WhileNode.new(load_location, load_node, load_optional_node, start_offset, length)
+ when 125 then
+ XStringNode.new(load_location, load_location, load_location, load_string, start_offset, length)
+ when 126 then
+ YieldNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, start_offset, length)
+ end
+ end
+ end
+ end
+end