# frozen_string_literal: true =begin This file is generated by the templates/template.rb script and should not be modified manually. See templates/lib/prism/node.rb.erb if you are looking to modify the template =end module Prism # This represents a node in the tree. It is the parent class of all of the # various node types. class Node # A pointer to the source that this node was created from. attr_reader :source private :source # A unique identifier for this node. This is used in a very specific # use case where you want to keep around a reference to a node without # having to keep around the syntax tree in memory. This unique identifier # will be consistent across multiple parses of the same source code. attr_reader :node_id # Save this node using a saved source so that it can be retrieved later. def save(repository) repository.enter(node_id, :itself) end # A Location instance that represents the location of this node in the # source. def location location = @location return location if location.is_a?(Location) @location = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the location using a saved source so that it can be retrieved later. def save_location(repository) repository.enter(node_id, :location) end # Delegates to the start_line of the associated location object. def start_line location.start_line end # Delegates to the end_line of the associated location object. def end_line location.end_line end # The start offset of the node in the source. This method is effectively a # delegate method to the location object. def start_offset location = @location location.is_a?(Location) ? location.start_offset : location >> 32 end # The end offset of the node in the source. This method is effectively a # delegate method to the location object. def end_offset location = @location location.is_a?(Location) ? location.end_offset : ((location >> 32) + (location & 0xFFFFFFFF)) end # Delegates to the start_character_offset of the associated location object. def start_character_offset location.start_character_offset end # Delegates to the end_character_offset of the associated location object. def end_character_offset location.end_character_offset end # Delegates to the cached_start_code_units_offset of the associated location # object. def cached_start_code_units_offset(cache) location.cached_start_code_units_offset(cache) end # Delegates to the cached_end_code_units_offset of the associated location # object. def cached_end_code_units_offset(cache) location.cached_end_code_units_offset(cache) end # Delegates to the start_column of the associated location object. def start_column location.start_column end # Delegates to the end_column of the associated location object. def end_column location.end_column end # Delegates to the start_character_column of the associated location object. def start_character_column location.start_character_column end # Delegates to the end_character_column of the associated location object. def end_character_column location.end_character_column end # Delegates to the cached_start_code_units_column of the associated location # object. def cached_start_code_units_column(cache) location.cached_start_code_units_column(cache) end # Delegates to the cached_end_code_units_column of the associated location # object. def cached_end_code_units_column(cache) location.cached_end_code_units_column(cache) end # Delegates to the leading_comments of the associated location object. def leading_comments location.leading_comments end # Delegates to the trailing_comments of the associated location object. def trailing_comments location.trailing_comments end # Delegates to the comments of the associated location object. def comments location.comments end # Returns all of the lines of the source code associated with this node. def source_lines location.source_lines end # An alias for source_lines, used to mimic the API from # RubyVM::AbstractSyntaxTree to make it easier to migrate. alias script_lines source_lines # Slice the location of the node from the source. def slice location.slice end # Slice the location of the node from the source, starting at the beginning # of the line that the location starts on, ending at the end of the line # that the location ends on. def slice_lines location.slice_lines end # An bitset of flags for this node. There are certain flags that are common # for all nodes, and then some nodes have specific flags. attr_reader :flags protected :flags # Returns true if the node has the newline flag set. def newline? flags.anybits?(NodeFlags::NEWLINE) end # Returns true if the node has the static literal flag set. def static_literal? flags.anybits?(NodeFlags::STATIC_LITERAL) end # Similar to inspect, but respects the current level of indentation given by # the pretty print object. def pretty_print(q) q.seplist(inspect.chomp.each_line, -> { q.breakable }) do |line| q.text(line.chomp) end q.current_group.break end # Convert this node into a graphviz dot graph string. def to_dot # @type self: node DotVisitor.new.tap { |visitor| accept(visitor) }.to_dot end # Returns a list of nodes that are descendants of this node that contain the # given line and column. This is useful for locating a node that is selected # based on the line and column of the source code. # # Important to note is that the column given to this method should be in # bytes, as opposed to characters or code units. def tunnel(line, column) queue = [self] #: Array[Prism::node] result = [] #: Array[Prism::node] while (node = queue.shift) result << node node.compact_child_nodes.each do |child_node| child_location = child_node.location start_line = child_location.start_line end_line = child_location.end_line if start_line == end_line if line == start_line && column >= child_location.start_column && column < child_location.end_column queue << child_node break end elsif (line == start_line && column >= child_location.start_column) || (line == end_line && column < child_location.end_column) queue << child_node break elsif line > start_line && line < end_line queue << child_node break end end end result end # Returns the first node that matches the given block when visited in a # depth-first search. This is useful for finding a node that matches a # particular condition. # # node.breadth_first_search { |node| node.node_id == node_id } # def breadth_first_search(&block) queue = [self] #: Array[Prism::node] while (node = queue.shift) return node if yield node queue.concat(node.compact_child_nodes) end nil end # Returns a list of the fields that exist for this node class. Fields # describe the structure of the node. This kind of reflection is useful for # things like recursively visiting each node _and_ field in the tree. def self.fields # This method should only be called on subclasses of Node, not Node # itself. raise NoMethodError, "undefined method `fields' for #{inspect}" if self == Node Reflection.fields_for(self) end # -------------------------------------------------------------------------- # :section: Node interface # These methods are effectively abstract methods that must be implemented by # the various subclasses of Node. They are here to make it easier to work # with typecheckers. # -------------------------------------------------------------------------- # Accepts a visitor and calls back into the specialized visit function. def accept(visitor) raise NoMethodError, "undefined method `accept' for #{inspect}" end # Returns an array of child nodes, including `nil`s in the place of optional # nodes that were not present. def child_nodes raise NoMethodError, "undefined method `child_nodes' for #{inspect}" end alias deconstruct child_nodes # Returns an array of child nodes, excluding any `nil`s in the place of # optional nodes that were not present. def compact_child_nodes raise NoMethodError, "undefined method `compact_child_nodes' for #{inspect}" end # Returns an array of child nodes and locations that could potentially have # comments attached to them. def comment_targets raise NoMethodError, "undefined method `comment_targets' for #{inspect}" end # Returns a string representation of the node. def inspect raise NoMethodError, "undefined method `inspect' for #{inspect}" end # Sometimes you want to check an instance of a node against a list of # classes to see what kind of behavior to perform. Usually this is done by # calling `[cls1, cls2].include?(node.class)` or putting the node into a # case statement and doing `case node; when cls1; when cls2; end`. Both of # these approaches are relatively slow because of the constant lookups, # method calls, and/or array allocations. # # Instead, you can call #type, which will return to you a symbol that you # can use for comparison. This is faster than the other approaches because # it uses a single integer comparison, but also because if you're on CRuby # you can take advantage of the fact that case statements with all symbol # keys will use a jump table. def type raise NoMethodError, "undefined method `type' for #{inspect}" end # Similar to #type, this method returns a symbol that you can use for # splitting on the type of the node without having to do a long === chain. # Note that like #type, it will still be slower than using == for a single # class, but should be faster in a case statement or an array comparison. def self.type raise NoMethodError, "undefined method `type' for #{inspect}" end end # Represents the use of the `alias` keyword to alias a global variable. # # alias $foo $bar # ^^^^^^^^^^^^^^^ class AliasGlobalVariableNode < Node # Initialize a new AliasGlobalVariableNode node. def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @new_name = new_name @old_name = old_name @keyword_loc = keyword_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_alias_global_variable_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [new_name, old_name] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [new_name, old_name] end # def comment_targets: () -> Array[Node | Location] def comment_targets [new_name, old_name, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, ?old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, ?keyword_loc: Location) -> AliasGlobalVariableNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc) AliasGlobalVariableNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode, old_name: GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | SymbolNode | MissingNode, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, new_name: new_name, old_name: old_name, keyword_loc: keyword_loc } end # Represents the new name of the global variable that can be used after aliasing. # # alias $foo $bar # ^^^^ attr_reader :new_name # Represents the old name of the global variable that can be used before aliasing. # # alias $foo $bar # ^^^^ attr_reader :old_name # The location of the `alias` keyword. # # alias $foo $bar # ^^^^^ def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :alias_global_variable_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :alias_global_variable_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AliasGlobalVariableNode) && (new_name === other.new_name) && (old_name === other.old_name) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents the use of the `alias` keyword to alias a method. # # alias foo bar # ^^^^^^^^^^^^^ class AliasMethodNode < Node # Initialize a new AliasMethodNode node. def initialize(source, node_id, location, flags, new_name, old_name, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @new_name = new_name @old_name = old_name @keyword_loc = keyword_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_alias_method_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [new_name, old_name] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [new_name, old_name] end # def comment_targets: () -> Array[Node | Location] def comment_targets [new_name, old_name, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?new_name: SymbolNode | InterpolatedSymbolNode, ?old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, ?keyword_loc: Location) -> AliasMethodNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, new_name: self.new_name, old_name: self.old_name, keyword_loc: self.keyword_loc) AliasMethodNode.new(source, node_id, location, flags, new_name, old_name, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, new_name: SymbolNode | InterpolatedSymbolNode, old_name: SymbolNode | InterpolatedSymbolNode | GlobalVariableReadNode | MissingNode, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, new_name: new_name, old_name: old_name, keyword_loc: keyword_loc } end # Represents the new name of the method that will be aliased. # # alias foo bar # ^^^ # # alias :foo :bar # ^^^^ # # alias :"#{foo}" :"#{bar}" # ^^^^^^^^^ attr_reader :new_name # Represents the old name of the method that will be aliased. # # alias foo bar # ^^^ # # alias :foo :bar # ^^^^ # # alias :"#{foo}" :"#{bar}" # ^^^^^^^^^ attr_reader :old_name # Represents the location of the `alias` keyword. # # alias foo bar # ^^^^^ def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :alias_method_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :alias_method_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AliasMethodNode) && (new_name === other.new_name) && (old_name === other.old_name) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents an alternation pattern in pattern matching. # # foo => bar | baz # ^^^^^^^^^ class AlternationPatternNode < Node # Initialize a new AlternationPatternNode node. def initialize(source, node_id, location, flags, left, right, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @left = left @right = right @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [left, right] end # def comment_targets: () -> Array[Node | Location] def comment_targets [left, right, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AlternationPatternNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) AlternationPatternNode.new(source, node_id, location, flags, left, right, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } end # Represents the left side of the expression. # # foo => bar | baz # ^^^ attr_reader :left # Represents the right side of the expression. # # foo => bar | baz # ^^^ attr_reader :right # Represents the alternation operator location. # # foo => bar | baz # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :alternation_pattern_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :alternation_pattern_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AlternationPatternNode) && (left === other.left) && (right === other.right) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of the `&&` operator or the `and` keyword. # # left and right # ^^^^^^^^^^^^^^ class AndNode < Node # Initialize a new AndNode node. def initialize(source, node_id, location, flags, left, right, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @left = left @right = right @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [left, right] end # def comment_targets: () -> Array[Node | Location] def comment_targets [left, right, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> AndNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) AndNode.new(source, node_id, location, flags, left, right, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } end # Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # left and right # ^^^^ # # 1 && 2 # ^ attr_reader :left # Represents the right side of the expression. # # left && right # ^^^^^ # # 1 and 2 # ^ attr_reader :right # The location of the `and` keyword or the `&&` operator. # # left and right # ^^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :and_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :and_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AndNode) && (left === other.left) && (right === other.right) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a set of arguments to a method or a keyword. # # return foo, bar, baz # ^^^^^^^^^^^^^ class ArgumentsNode < Node # Initialize a new ArgumentsNode node. def initialize(source, node_id, location, flags, arguments) @source = source @node_id = node_id @location = location @flags = flags @arguments = arguments 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*arguments] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*arguments] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: Array[Prism::node]) -> ArgumentsNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments) ArgumentsNode.new(source, node_id, location, flags, arguments) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: Array[Prism::node] } def deconstruct_keys(keys) { node_id: node_id, location: location, arguments: arguments } end # def contains_forwarding?: () -> bool def contains_forwarding? flags.anybits?(ArgumentsNodeFlags::CONTAINS_FORWARDING) end # def contains_keywords?: () -> bool def contains_keywords? flags.anybits?(ArgumentsNodeFlags::CONTAINS_KEYWORDS) end # def contains_keyword_splat?: () -> bool def contains_keyword_splat? flags.anybits?(ArgumentsNodeFlags::CONTAINS_KEYWORD_SPLAT) end # def contains_splat?: () -> bool def contains_splat? flags.anybits?(ArgumentsNodeFlags::CONTAINS_SPLAT) end # def contains_multiple_splats?: () -> bool def contains_multiple_splats? flags.anybits?(ArgumentsNodeFlags::CONTAINS_MULTIPLE_SPLATS) end # The list of arguments, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo(bar, baz) # ^^^^^^^^ attr_reader :arguments # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :arguments_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :arguments_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ArgumentsNode) && (flags === other.flags) && (arguments.length == other.arguments.length) && arguments.zip(other.arguments).all? { |left, right| left === right } 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 # Initialize a new ArrayNode node. def initialize(source, node_id, location, flags, elements, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @elements = elements @opening_loc = opening_loc @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*elements] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*elements, *opening_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements, opening_loc: self.opening_loc, closing_loc: self.closing_loc) ArrayNode.new(source, node_id, location, flags, elements, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, elements: elements, opening_loc: opening_loc, closing_loc: closing_loc } end # def contains_splat?: () -> bool def contains_splat? flags.anybits?(ArrayNodeFlags::CONTAINS_SPLAT) end # Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array. attr_reader :elements # Represents the optional source location for the opening token. # # [1,2,3] # "[" # %w[foo bar baz] # "%w[" # %I(apple orange banana) # "%I(" # foo = 1, 2, 3 # nil def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # Represents the optional source location for the closing token. # # [1,2,3] # "]" # %w[foo bar baz] # "]" # %I(apple orange banana) # ")" # foo = 1, 2, 3 # nil def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :array_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :array_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ArrayNode) && (flags === other.flags) && (elements.length == other.elements.length) && elements.zip(other.elements).all? { |left, right| left === right } && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents an array pattern in pattern matching. # # foo in 1, 2 # ^^^^^^^^^^^ # # foo in [1, 2] # ^^^^^^^^^^^^^ # # foo in *bar # ^^^^^^^^^^^ # # foo in Bar[] # ^^^^^^^^^^^^ # # foo in Bar[1, 2, 3] # ^^^^^^^^^^^^^^^^^^^ class ArrayPatternNode < Node # Initialize a new ArrayPatternNode node. def initialize(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @constant = constant @requireds = requireds @rest = rest @posts = posts @opening_loc = opening_loc @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << constant if constant compact.concat(requireds) compact << rest if rest compact.concat(posts) compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*constant, *requireds, *rest, *posts, *opening_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?requireds: Array[Prism::node], ?rest: Prism::node?, ?posts: Array[Prism::node], ?opening_loc: Location?, ?closing_loc: Location?) -> ArrayPatternNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, requireds: self.requireds, rest: self.rest, posts: self.posts, opening_loc: self.opening_loc, closing_loc: self.closing_loc) ArrayPatternNode.new(source, node_id, location, flags, constant, requireds, rest, posts, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, requireds: Array[Prism::node], rest: Prism::node?, posts: Array[Prism::node], opening_loc: Location?, closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, constant: constant, requireds: requireds, rest: rest, posts: posts, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader constant: ConstantReadNode | ConstantPathNode | nil attr_reader :constant # Represents the required elements of the array pattern. # # foo in [1, 2] # ^ ^ attr_reader :requireds # Represents the rest element of the array pattern. # # foo in *bar # ^^^^ attr_reader :rest # Represents the elements after the rest element of the array pattern. # # foo in *bar, baz # ^^^ attr_reader :posts # Represents the opening location of the array pattern. # # foo in [1, 2] # ^ def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # Represents the closing location of the array pattern. # # foo in [1, 2] # ^ def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :array_pattern_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :array_pattern_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ArrayPatternNode) && (constant === other.constant) && (requireds.length == other.requireds.length) && requireds.zip(other.requireds).all? { |left, right| left === right } && (rest === other.rest) && (posts.length == other.posts.length) && posts.zip(other.posts).all? { |left, right| left === right } && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a hash key/value pair. # # { a => b } # ^^^^^^ class AssocNode < Node # Initialize a new AssocNode node. def initialize(source, node_id, location, flags, key, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @key = key @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [key, value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [key, value, *operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?key: Prism::node, ?value: Prism::node, ?operator_loc: Location?) -> AssocNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, key: self.key, value: self.value, operator_loc: self.operator_loc) AssocNode.new(source, node_id, location, flags, key, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, key: Prism::node, value: Prism::node, operator_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, key: key, value: value, operator_loc: operator_loc } end # The key of the association. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # { a: b } # ^ # # { foo => bar } # ^^^ # # { def a; end => 1 } # ^^^^^^^^^^ attr_reader :key # The value of the association, if present. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # { foo => bar } # ^^^ # # { x: 1 } # ^ attr_reader :value # The location of the `=>` operator, if present. # # { foo => bar } # ^^ def operator_loc location = @operator_loc case location when nil nil when Location location else @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) unless @operator_loc.nil? end # def operator: () -> String? def operator operator_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :assoc_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :assoc_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AssocNode) && (key === other.key) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a splat in a hash literal. # # { **foo } # ^^^^^ class AssocSplatNode < Node # Initialize a new AssocSplatNode node. def initialize(source, node_id, location, flags, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << value if value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node?, ?operator_loc: Location) -> AssocSplatNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, operator_loc: self.operator_loc) AssocSplatNode.new(source, node_id, location, flags, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value, operator_loc: operator_loc } end # The value to be splatted, if present. Will be missing when keyword rest argument forwarding is used. # # { **foo } # ^^^ attr_reader :value # The location of the `**` operator. # # { **x } # ^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :assoc_splat_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :assoc_splat_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(AssocSplatNode) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents reading a reference to a field in the previous match. # # $' # ^^ class BackReferenceReadNode < Node # Initialize a new BackReferenceReadNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BackReferenceReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) BackReferenceReadNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # The name of the back-reference variable, including the leading `$`. # # $& # name `:$&` # # $+ # name `:$+` attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :back_reference_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :back_reference_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BackReferenceReadNode) && (name === other.name) end end # Represents a begin statement. # # begin # foo # end # ^^^^^ class BeginNode < Node # Initialize a new BeginNode node. def initialize(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @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 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact << rescue_clause if rescue_clause compact << else_clause if else_clause compact << ensure_clause if ensure_clause compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*begin_keyword_loc, *statements, *rescue_clause, *else_clause, *ensure_clause, *end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?begin_keyword_loc: Location?, ?statements: StatementsNode?, ?rescue_clause: RescueNode?, ?else_clause: ElseNode?, ?ensure_clause: EnsureNode?, ?end_keyword_loc: Location?) -> BeginNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, begin_keyword_loc: self.begin_keyword_loc, statements: self.statements, rescue_clause: self.rescue_clause, else_clause: self.else_clause, ensure_clause: self.ensure_clause, end_keyword_loc: self.end_keyword_loc) BeginNode.new(source, node_id, location, flags, begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, begin_keyword_loc: Location?, statements: StatementsNode?, rescue_clause: RescueNode?, else_clause: ElseNode?, ensure_clause: EnsureNode?, end_keyword_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, 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 } end # Represents the location of the `begin` keyword. # # begin x end # ^^^^^ def begin_keyword_loc location = @begin_keyword_loc case location when nil nil when Location location else @begin_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the begin_keyword_loc location using the given saved source so that # it can be retrieved later. def save_begin_keyword_loc(repository) repository.enter(node_id, :begin_keyword_loc) unless @begin_keyword_loc.nil? end # Represents the statements within the begin block. # # begin x end # ^ attr_reader :statements # Represents the rescue clause within the begin block. # # begin x; rescue y; end # ^^^^^^^^ attr_reader :rescue_clause # Represents the else clause within the begin block. # # begin x; rescue y; else z; end # ^^^^^^ attr_reader :else_clause # Represents the ensure clause within the begin block. # # begin x; ensure y; end # ^^^^^^^^ attr_reader :ensure_clause # Represents the location of the `end` keyword. # # begin x end # ^^^ def end_keyword_loc location = @end_keyword_loc case location when nil nil when Location location else @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? end # def begin_keyword: () -> String? def begin_keyword begin_keyword_loc&.slice end # def end_keyword: () -> String? def end_keyword end_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :begin_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :begin_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BeginNode) && (begin_keyword_loc.nil? == other.begin_keyword_loc.nil?) && (statements === other.statements) && (rescue_clause === other.rescue_clause) && (else_clause === other.else_clause) && (ensure_clause === other.ensure_clause) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents a block argument using `&`. # # bar(&args) # ^^^^^^^^^^ class BlockArgumentNode < Node # Initialize a new BlockArgumentNode node. def initialize(source, node_id, location, flags, expression, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @expression = expression @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << expression if expression compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*expression, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node?, ?operator_loc: Location) -> BlockArgumentNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc) BlockArgumentNode.new(source, node_id, location, flags, expression, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, expression: expression, operator_loc: operator_loc } end # The expression that is being passed as a block argument. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo(&args) # ^^^^^ attr_reader :expression # Represents the location of the `&` operator. # # foo(&args) # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :block_argument_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :block_argument_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BlockArgumentNode) && (expression === other.expression) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a block local variable. # # a { |; b| } # ^ class BlockLocalVariableNode < Node # Initialize a new BlockLocalVariableNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_block_local_variable_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> BlockLocalVariableNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) BlockLocalVariableNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # The name of the block local variable. # # a { |; b| } # name `:b` # ^ attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :block_local_variable_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :block_local_variable_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BlockLocalVariableNode) && (flags === other.flags) && (name === other.name) end end # Represents a block of ruby code. # # [1, 2, 3].each { |i| puts x } # ^^^^^^^^^^^^^^ class BlockNode < Node # Initialize a new BlockNode node. def initialize(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @parameters = parameters @body = body @opening_loc = opening_loc @closing_loc = closing_loc 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << parameters if parameters compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*parameters, *body, opening_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil, ?opening_loc: Location, ?closing_loc: Location) -> BlockNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, parameters: self.parameters, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc) BlockNode.new(source, node_id, location, flags, locals, parameters, body, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil, opening_loc: Location, closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, parameters: parameters, body: body, opening_loc: opening_loc, closing_loc: closing_loc } end # The local variables declared in the block. # # [1, 2, 3].each { |i| puts x } # locals: [:i] # ^ attr_reader :locals # The parameters of the block. # # [1, 2, 3].each { |i| puts x } # ^^^ # [1, 2, 3].each { puts _1 } # ^^^^^^^^^^^ # [1, 2, 3].each { puts it } # ^^^^^^^^^^^ attr_reader :parameters # The body of the block. # # [1, 2, 3].each { |i| puts x } # ^^^^^^ attr_reader :body # Represents the location of the opening `|`. # # [1, 2, 3].each { |i| puts x } # ^ def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # Represents the location of the closing `|`. # # [1, 2, 3].each { |i| puts x } # ^ def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :block_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :block_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BlockNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (parameters === other.parameters) && (body === other.body) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a block parameter of a method, block, or lambda definition. # # def a(&b) # ^^ # end class BlockParameterNode < Node # Initialize a new BlockParameterNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*name_loc, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> BlockParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) BlockParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # The name of the block parameter. # # def a(&b) # name `:b` # ^ # end attr_reader :name # Represents the location of the block parameter name. # # def a(&b) # ^ def name_loc location = @name_loc case location when nil nil when Location location else @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) unless @name_loc.nil? end # Represents the location of the `&` operator. # # def a(&b) # ^ # end def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :block_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :block_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BlockParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a block's parameters declaration. # # -> (a, b = 1; local) { } # ^^^^^^^^^^^^^^^^^ # # foo do |a, b = 1; local| # ^^^^^^^^^^^^^^^^^ # end class BlockParametersNode < Node # Initialize a new BlockParametersNode node. def initialize(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @parameters = parameters @locals = locals @opening_loc = opening_loc @closing_loc = closing_loc 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, *locals] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << parameters if parameters compact.concat(locals) compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*parameters, *locals, *opening_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parameters: ParametersNode?, ?locals: Array[BlockLocalVariableNode], ?opening_loc: Location?, ?closing_loc: Location?) -> BlockParametersNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, parameters: self.parameters, locals: self.locals, opening_loc: self.opening_loc, closing_loc: self.closing_loc) BlockParametersNode.new(source, node_id, location, flags, parameters, locals, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parameters: ParametersNode?, locals: Array[BlockLocalVariableNode], opening_loc: Location?, closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, parameters: parameters, locals: locals, opening_loc: opening_loc, closing_loc: closing_loc } end # Represents the parameters of the block. # # -> (a, b = 1; local) { } # ^^^^^^^^ # # foo do |a, b = 1; local| # ^^^^^^^^ # end attr_reader :parameters # Represents the local variables of the block. # # -> (a, b = 1; local) { } # ^^^^^ # # foo do |a, b = 1; local| # ^^^^^ # end attr_reader :locals # Represents the opening location of the block parameters. # # -> (a, b = 1; local) { } # ^ # # foo do |a, b = 1; local| # ^ # end def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # Represents the closing location of the block parameters. # # -> (a, b = 1; local) { } # ^ # # foo do |a, b = 1; local| # ^ # end def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :block_parameters_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :block_parameters_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BlockParametersNode) && (parameters === other.parameters) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents the use of the `break` keyword. # # break foo # ^^^^^^^^^ class BreakNode < Node # Initialize a new BreakNode node. def initialize(source, node_id, location, flags, arguments, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @arguments = arguments @keyword_loc = keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << arguments if arguments compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*arguments, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> BreakNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc) BreakNode.new(source, node_id, location, flags, arguments, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, arguments: arguments, keyword_loc: keyword_loc } end # The arguments to the break statement, if present. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # break foo # ^^^ attr_reader :arguments # The location of the `break` keyword. # # break foo # ^^^^^ def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :break_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :break_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(BreakNode) && (arguments === other.arguments) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents the use of the `&&=` operator on a call. # # foo.bar &&= value # ^^^^^^^^^^^^^^^^^ class CallAndWriteNode < Node # Initialize a new CallAndWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @message_loc = message_loc @read_name = read_name @write_name = write_name @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_call_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, *message_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value) CallAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo.bar &&= value # ^^^ attr_reader :receiver # Represents the location of the call operator. # # foo.bar &&= value # ^ def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # Represents the location of the message. # # foo.bar &&= value # ^^^ def message_loc location = @message_loc case location when nil nil when Location location else @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the message_loc location using the given saved source so that # it can be retrieved later. def save_message_loc(repository) repository.enter(node_id, :message_loc) unless @message_loc.nil? end # Represents the name of the method being called. # # foo.bar &&= value # read_name `:bar` # ^^^ attr_reader :read_name # Represents the name of the method being written to. # # foo.bar &&= value # write_name `:bar=` # ^^^ attr_reader :write_name # Represents the location of the operator. # # foo.bar &&= value # ^^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # Represents the value being assigned. # # foo.bar &&= value # ^^^^^ attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def message: () -> String? def message message_loc&.slice end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :call_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :call_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CallAndWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (message_loc.nil? == other.message_loc.nil?) && (read_name === other.read_name) && (write_name === other.write_name) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) 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 # Initialize a new CallNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @name = name @message_loc = message_loc @opening_loc = opening_loc @arguments = arguments @closing_loc = closing_loc @block = block 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << arguments if arguments compact << block if block compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, *message_loc, *opening_loc, *arguments, *closing_loc, *block] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?name: Symbol, ?message_loc: Location?, ?opening_loc: Location?, ?arguments: ArgumentsNode?, ?closing_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> CallNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block) CallNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc, opening_loc, arguments, closing_loc, block) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, name: Symbol, message_loc: Location?, opening_loc: Location?, arguments: ArgumentsNode?, closing_loc: Location?, block: BlockNode | BlockArgumentNode | nil } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # The object that the method is being called on. This can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo.bar # ^^^ # # +foo # ^^^ # # foo + bar # ^^^ attr_reader :receiver # Represents the location of the call operator. # # foo.bar # ^ # # foo&.bar # ^^ def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # Represents the name of the method being called. # # foo.bar # name `:foo` # ^^^ attr_reader :name # Represents the location of the message. # # foo.bar # ^^^ def message_loc location = @message_loc case location when nil nil when Location location else @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the message_loc location using the given saved source so that # it can be retrieved later. def save_message_loc(repository) repository.enter(node_id, :message_loc) unless @message_loc.nil? end # Represents the location of the left parenthesis. # foo(bar) # ^ def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # Represents the arguments to the method call. These can be any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo(bar) # ^^^ attr_reader :arguments # Represents the location of the right parenthesis. # # foo(bar) # ^ def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # Represents the block that is being passed to the method. # # foo { |a| a } # ^^^^^^^^^ attr_reader :block # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def message: () -> String? def message message_loc&.slice end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :call_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :call_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CallNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (name === other.name) && (message_loc.nil? == other.message_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (arguments === other.arguments) && (closing_loc.nil? == other.closing_loc.nil?) && (block === other.block) end end # Represents the use of an assignment operator on a call. # # foo.bar += baz # ^^^^^^^^^^^^^^ class CallOperatorWriteNode < Node # Initialize a new CallOperatorWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @message_loc = message_loc @read_name = read_name @write_name = write_name @binary_operator = binary_operator @binary_operator_loc = binary_operator_loc @value = value 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 [receiver, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, *message_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> CallOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value) CallOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, binary_operator, binary_operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, binary_operator: binary_operator, binary_operator_loc: binary_operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo.bar += value # ^^^ attr_reader :receiver # Represents the location of the call operator. # # foo.bar += value # ^ def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # Represents the location of the message. # # foo.bar += value # ^^^ def message_loc location = @message_loc case location when nil nil when Location location else @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the message_loc location using the given saved source so that # it can be retrieved later. def save_message_loc(repository) repository.enter(node_id, :message_loc) unless @message_loc.nil? end # Represents the name of the method being called. # # foo.bar += value # read_name `:bar` # ^^^ attr_reader :read_name # Represents the name of the method being written to. # # foo.bar += value # write_name `:bar=` # ^^^ attr_reader :write_name # Represents the binary operator being used. # # foo.bar += value # binary_operator `:+` # ^ attr_reader :binary_operator # Represents the location of the binary operator. # # foo.bar += value # ^^ def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # Represents the value being assigned. # # foo.bar += value # ^^^^^ attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def message: () -> String? def message message_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :call_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :call_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CallOperatorWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (message_loc.nil? == other.message_loc.nil?) && (read_name === other.read_name) && (write_name === other.write_name) && (binary_operator === other.binary_operator) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) end end # Represents the use of the `||=` operator on a call. # # foo.bar ||= value # ^^^^^^^^^^^^^^^^^ class CallOrWriteNode < Node # Initialize a new CallOrWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @message_loc = message_loc @read_name = read_name @write_name = write_name @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_call_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, *message_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?message_loc: Location?, ?read_name: Symbol, ?write_name: Symbol, ?operator_loc: Location, ?value: Prism::node) -> CallOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, message_loc: self.message_loc, read_name: self.read_name, write_name: self.write_name, operator_loc: self.operator_loc, value: self.value) CallOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, message_loc, read_name, write_name, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, message_loc: Location?, read_name: Symbol, write_name: Symbol, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, message_loc: message_loc, read_name: read_name, write_name: write_name, operator_loc: operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # The object that the method is being called on. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo.bar ||= value # ^^^ attr_reader :receiver # Represents the location of the call operator. # # foo.bar ||= value # ^ def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # Represents the location of the message. # # foo.bar ||= value # ^^^ def message_loc location = @message_loc case location when nil nil when Location location else @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the message_loc location using the given saved source so that # it can be retrieved later. def save_message_loc(repository) repository.enter(node_id, :message_loc) unless @message_loc.nil? end # Represents the name of the method being called. # # foo.bar ||= value # read_name `:bar` # ^^^ attr_reader :read_name # Represents the name of the method being written to. # # foo.bar ||= value # write_name `:bar=` # ^^^ attr_reader :write_name # Represents the location of the operator. # # foo.bar ||= value # ^^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # Represents the value being assigned. # # foo.bar ||= value # ^^^^^ attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def message: () -> String? def message message_loc&.slice end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :call_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :call_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CallOrWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (message_loc.nil? == other.message_loc.nil?) && (read_name === other.read_name) && (write_name === other.write_name) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to a method call. # # foo.bar, = 1 # ^^^^^^^ # # begin # rescue => foo.bar # ^^^^^^^ # end # # for foo.bar in baz do end # ^^^^^^^ class CallTargetNode < Node # Initialize a new CallTargetNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @name = name @message_loc = message_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_call_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [receiver] end # def comment_targets: () -> Array[Node | Location] def comment_targets [receiver, call_operator_loc, message_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?call_operator_loc: Location, ?name: Symbol, ?message_loc: Location) -> CallTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, name: self.name, message_loc: self.message_loc) CallTargetNode.new(source, node_id, location, flags, receiver, call_operator_loc, name, message_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, call_operator_loc: Location, name: Symbol, message_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, name: name, message_loc: message_loc } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # The object that the method is being called on. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo.bar = 1 # ^^^ attr_reader :receiver # Represents the location of the call operator. # # foo.bar = 1 # ^ def call_operator_loc location = @call_operator_loc return location if location.is_a?(Location) @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) end # Represents the name of the method being called. # # foo.bar = 1 # name `:foo` # ^^^ attr_reader :name # Represents the location of the message. # # foo.bar = 1 # ^^^ def message_loc location = @message_loc return location if location.is_a?(Location) @message_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the message_loc location using the given saved source so that # it can be retrieved later. def save_message_loc(repository) repository.enter(node_id, :message_loc) end # def call_operator: () -> String def call_operator call_operator_loc.slice end # def message: () -> String def message message_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :call_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :call_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CallTargetNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (name === other.name) && (message_loc.nil? == other.message_loc.nil?) end end # Represents assigning to a local variable in pattern matching. # # foo => [bar => baz] # ^^^^^^^^^^^^ class CapturePatternNode < Node # Initialize a new CapturePatternNode node. def initialize(source, node_id, location, flags, value, target, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @value = value @target = target @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value, target] end # def comment_targets: () -> Array[Node | Location] def comment_targets [value, target, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?target: LocalVariableTargetNode, ?operator_loc: Location) -> CapturePatternNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, target: self.target, operator_loc: self.operator_loc) CapturePatternNode.new(source, node_id, location, flags, value, target, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, target: LocalVariableTargetNode, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value, target: target, operator_loc: operator_loc } end # Represents the value to capture. # # foo => bar # ^^^ attr_reader :value # Represents the target of the capture. # # foo => bar # ^^^ attr_reader :target # Represents the location of the `=>` operator. # # foo => bar # ^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :capture_pattern_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :capture_pattern_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CapturePatternNode) && (value === other.value) && (target === other.target) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of a case statement for pattern matching. # # case true # in false # end # ^^^^^^^^^ class CaseMatchNode < Node # Initialize a new CaseMatchNode node. def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @predicate = predicate @conditions = conditions @else_clause = else_clause @case_keyword_loc = case_keyword_loc @end_keyword_loc = end_keyword_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_case_match_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [predicate, *conditions, else_clause] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate if predicate compact.concat(conditions) compact << else_clause if else_clause compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*predicate, *conditions, *else_clause, case_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[InNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseMatchNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc) CaseMatchNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[InNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, predicate: predicate, conditions: conditions, else_clause: else_clause, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc } end # Represents the predicate of the case match. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # case true; in false; end # ^^^^ attr_reader :predicate # Represents the conditions of the case match. # # case true; in false; end # ^^^^^^^^ attr_reader :conditions # Represents the else clause of the case match. # # case true; in false; else; end # ^^^^ attr_reader :else_clause # Represents the location of the `case` keyword. # # case true; in false; end # ^^^^ def case_keyword_loc location = @case_keyword_loc return location if location.is_a?(Location) @case_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the case_keyword_loc location using the given saved source so that # it can be retrieved later. def save_case_keyword_loc(repository) repository.enter(node_id, :case_keyword_loc) end # Represents the location of the `end` keyword. # # case true; in false; end # ^^^ def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # def case_keyword: () -> String def case_keyword case_keyword_loc.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :case_match_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :case_match_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CaseMatchNode) && (predicate === other.predicate) && (conditions.length == other.conditions.length) && conditions.zip(other.conditions).all? { |left, right| left === right } && (else_clause === other.else_clause) && (case_keyword_loc.nil? == other.case_keyword_loc.nil?) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents the use of a case statement. # # case true # when false # end # ^^^^^^^^^^ class CaseNode < Node # Initialize a new CaseNode node. def initialize(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @predicate = predicate @conditions = conditions @else_clause = else_clause @case_keyword_loc = case_keyword_loc @end_keyword_loc = end_keyword_loc 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, else_clause] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate if predicate compact.concat(conditions) compact << else_clause if else_clause compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*predicate, *conditions, *else_clause, case_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?predicate: Prism::node?, ?conditions: Array[WhenNode], ?else_clause: ElseNode?, ?case_keyword_loc: Location, ?end_keyword_loc: Location) -> CaseNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, predicate: self.predicate, conditions: self.conditions, else_clause: self.else_clause, case_keyword_loc: self.case_keyword_loc, end_keyword_loc: self.end_keyword_loc) CaseNode.new(source, node_id, location, flags, predicate, conditions, else_clause, case_keyword_loc, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, predicate: Prism::node?, conditions: Array[WhenNode], else_clause: ElseNode?, case_keyword_loc: Location, end_keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, predicate: predicate, conditions: conditions, else_clause: else_clause, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc } end # Represents the predicate of the case statement. This can be either `nil` or any [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # case true; when false; end # ^^^^ attr_reader :predicate # Represents the conditions of the case statement. # # case true; when false; end # ^^^^^^^^^^ attr_reader :conditions # Represents the else clause of the case statement. # # case true; when false; else; end # ^^^^ attr_reader :else_clause # Represents the location of the `case` keyword. # # case true; when false; end # ^^^^ def case_keyword_loc location = @case_keyword_loc return location if location.is_a?(Location) @case_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the case_keyword_loc location using the given saved source so that # it can be retrieved later. def save_case_keyword_loc(repository) repository.enter(node_id, :case_keyword_loc) end # Represents the location of the `end` keyword. # # case true; when false; end # ^^^ def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # def case_keyword: () -> String def case_keyword case_keyword_loc.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :case_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :case_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(CaseNode) && (predicate === other.predicate) && (conditions.length == other.conditions.length) && conditions.zip(other.conditions).all? { |left, right| left === right } && (else_clause === other.else_clause) && (case_keyword_loc.nil? == other.case_keyword_loc.nil?) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents a class declaration involving the `class` keyword. # # class Foo end # ^^^^^^^^^^^^^ class ClassNode < Node # Initialize a new ClassNode node. def initialize(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @class_keyword_loc = class_keyword_loc @constant_path = constant_path @inheritance_operator_loc = inheritance_operator_loc @superclass = superclass @body = body @end_keyword_loc = end_keyword_loc @name = name 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << constant_path compact << superclass if superclass compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [class_keyword_loc, constant_path, *inheritance_operator_loc, *superclass, *body, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | CallNode, ?inheritance_operator_loc: Location?, ?superclass: Prism::node?, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ClassNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, constant_path: self.constant_path, inheritance_operator_loc: self.inheritance_operator_loc, superclass: self.superclass, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name) ClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, body, end_keyword_loc, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | CallNode, inheritance_operator_loc: Location?, superclass: Prism::node?, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, class_keyword_loc: class_keyword_loc, constant_path: constant_path, inheritance_operator_loc: inheritance_operator_loc, superclass: superclass, body: body, end_keyword_loc: end_keyword_loc, name: name } end # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader class_keyword_loc: Location def class_keyword_loc location = @class_keyword_loc return location if location.is_a?(Location) @class_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the class_keyword_loc location using the given saved source so that # it can be retrieved later. def save_class_keyword_loc(repository) repository.enter(node_id, :class_keyword_loc) end # attr_reader constant_path: ConstantReadNode | ConstantPathNode | CallNode attr_reader :constant_path # attr_reader inheritance_operator_loc: Location? def inheritance_operator_loc location = @inheritance_operator_loc case location when nil nil when Location location else @inheritance_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the inheritance_operator_loc location using the given saved source so that # it can be retrieved later. def save_inheritance_operator_loc(repository) repository.enter(node_id, :inheritance_operator_loc) unless @inheritance_operator_loc.nil? end # attr_reader superclass: Prism::node? attr_reader :superclass # attr_reader body: StatementsNode | BeginNode | nil attr_reader :body # attr_reader end_keyword_loc: Location def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # attr_reader name: Symbol attr_reader :name # def class_keyword: () -> String def class_keyword class_keyword_loc.slice end # def inheritance_operator: () -> String? def inheritance_operator inheritance_operator_loc&.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (class_keyword_loc.nil? == other.class_keyword_loc.nil?) && (constant_path === other.constant_path) && (inheritance_operator_loc.nil? == other.inheritance_operator_loc.nil?) && (superclass === other.superclass) && (body === other.body) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) && (name === other.name) end end # Represents the use of the `&&=` operator for assignment to a class variable. # # @@target &&= value # ^^^^^^^^^^^^^^^^^^ class ClassVariableAndWriteNode < Node # Initialize a new ClassVariableAndWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_class_variable_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) ClassVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # @@target &&= value # name `:@@target` # ^^^^^^^^ attr_reader :name # Represents the location of the variable name. # # @@target &&= value # ^^^^^^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # Represents the location of the `&&=` operator. # # @@target &&= value # ^^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # Represents the value being assigned. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # @@target &&= value # ^^^^^ attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableAndWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to a class variable using an operator that isn't `=`. # # @@target += value # ^^^^^^^^^^^^^^^^^ class ClassVariableOperatorWriteNode < Node # Initialize a new ClassVariableOperatorWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @binary_operator_loc = binary_operator_loc @value = value @binary_operator = binary_operator 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ClassVariableOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) ClassVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader binary_operator: Symbol attr_reader :binary_operator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableOperatorWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (binary_operator === other.binary_operator) end end # Represents the use of the `||=` operator for assignment to a class variable. # # @@target ||= value # ^^^^^^^^^^^^^^^^^^ class ClassVariableOrWriteNode < Node # Initialize a new ClassVariableOrWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_class_variable_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ClassVariableOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) ClassVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableOrWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents referencing a class variable. # # @@foo # ^^^^^ class ClassVariableReadNode < Node # Initialize a new ClassVariableReadNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) ClassVariableReadNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # @@abc # name `:@@abc` # # @@_test # name `:@@_test` attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableReadNode) && (name === other.name) end end # Represents writing to a class variable in a context that doesn't have an explicit value. # # @@foo, @@bar = baz # ^^^^^ ^^^^^ class ClassVariableTargetNode < Node # Initialize a new ClassVariableTargetNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_class_variable_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ClassVariableTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) ClassVariableTargetNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # attr_reader name: Symbol attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableTargetNode) && (name === other.name) end end # Represents writing to a class variable. # # @@foo = 1 # ^^^^^^^^^ class ClassVariableWriteNode < Node # Initialize a new ClassVariableWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ClassVariableWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) ClassVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } end # The name of the class variable, which is a `@@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # @@abc = 123 # name `@@abc` # # @@_test = :test # name `@@_test` attr_reader :name # The location of the variable name. # # @@foo = :bar # ^^^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # The value to write to the class variable. This can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # @@foo = :bar # ^^^^ # # @@_xyz = 123 # ^^^ attr_reader :value # The location of the `=` operator. # # @@foo = :bar # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :class_variable_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :class_variable_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ClassVariableWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of the `&&=` operator for assignment to a constant. # # Target &&= value # ^^^^^^^^^^^^^^^^ class ConstantAndWriteNode < Node # Initialize a new ConstantAndWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) ConstantAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantAndWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to a constant using an operator that isn't `=`. # # Target += value # ^^^^^^^^^^^^^^^ class ConstantOperatorWriteNode < Node # Initialize a new ConstantOperatorWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @binary_operator_loc = binary_operator_loc @value = value @binary_operator = binary_operator 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) ConstantOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader binary_operator: Symbol attr_reader :binary_operator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantOperatorWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (binary_operator === other.binary_operator) end end # Represents the use of the `||=` operator for assignment to a constant. # # Target ||= value # ^^^^^^^^^^^^^^^^ class ConstantOrWriteNode < Node # Initialize a new ConstantOrWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> ConstantOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) ConstantOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantOrWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents the use of the `&&=` operator for assignment to a constant path. # # Parent::Child &&= value # ^^^^^^^^^^^^^^^^^^^^^^^ class ConstantPathAndWriteNode < Node # Initialize a new ConstantPathAndWriteNode node. def initialize(source, node_id, location, flags, target, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @target = target @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_path_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [target, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [target, value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [target, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) ConstantPathAndWriteNode.new(source, node_id, location, flags, target, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } end # attr_reader target: ConstantPathNode attr_reader :target # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathAndWriteNode) && (target === other.target) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents accessing a constant through a path of `::` operators. # # Foo::Bar # ^^^^^^^^ class ConstantPathNode < Node # Initialize a new ConstantPathNode node. def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) @source = source @node_id = node_id @location = location @flags = flags @parent = parent @name = name @delimiter_loc = delimiter_loc @name_loc = name_loc 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] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << parent if parent compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*parent, delimiter_loc, name_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc) ConstantPathNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, parent: parent, name: name, delimiter_loc: delimiter_loc, name_loc: name_loc } end # The left-hand node of the path, if present. It can be `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). It will be `nil` when the constant lookup is at the root of the module tree. # # Foo::Bar # ^^^ # # self::Test # ^^^^ # # a.b::C # ^^^ attr_reader :parent # The name of the constant being accessed. This could be `nil` in the event of a syntax error. attr_reader :name # The location of the `::` delimiter. # # ::Foo # ^^ # # One::Two # ^^ def delimiter_loc location = @delimiter_loc return location if location.is_a?(Location) @delimiter_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the delimiter_loc location using the given saved source so that # it can be retrieved later. def save_delimiter_loc(repository) repository.enter(node_id, :delimiter_loc) end # The location of the name of the constant. # # ::Foo # ^^^ # # One::Two # ^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # def delimiter: () -> String def delimiter delimiter_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathNode) && (parent === other.parent) && (name === other.name) && (delimiter_loc.nil? == other.delimiter_loc.nil?) && (name_loc.nil? == other.name_loc.nil?) end end # Represents assigning to a constant path using an operator that isn't `=`. # # Parent::Child += value # ^^^^^^^^^^^^^^^^^^^^^^ class ConstantPathOperatorWriteNode < Node # Initialize a new ConstantPathOperatorWriteNode node. def initialize(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator) @source = source @node_id = node_id @location = location @flags = flags @target = target @binary_operator_loc = binary_operator_loc @value = value @binary_operator = binary_operator 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [target, value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [target, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> ConstantPathOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) ConstantPathOperatorWriteNode.new(source, node_id, location, flags, target, binary_operator_loc, value, binary_operator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, target: target, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } end # attr_reader target: ConstantPathNode attr_reader :target # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader binary_operator: Symbol attr_reader :binary_operator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathOperatorWriteNode) && (target === other.target) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (binary_operator === other.binary_operator) end end # Represents the use of the `||=` operator for assignment to a constant path. # # Parent::Child ||= value # ^^^^^^^^^^^^^^^^^^^^^^^ class ConstantPathOrWriteNode < Node # Initialize a new ConstantPathOrWriteNode node. def initialize(source, node_id, location, flags, target, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @target = target @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_path_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [target, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [target, value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [target, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) ConstantPathOrWriteNode.new(source, node_id, location, flags, target, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } end # attr_reader target: ConstantPathNode attr_reader :target # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathOrWriteNode) && (target === other.target) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents writing to a constant path in a context that doesn't have an explicit value. # # Foo::Foo, Bar::Bar = baz # ^^^^^^^^ ^^^^^^^^ class ConstantPathTargetNode < Node # Initialize a new ConstantPathTargetNode node. def initialize(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) @source = source @node_id = node_id @location = location @flags = flags @parent = parent @name = name @delimiter_loc = delimiter_loc @name_loc = name_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_path_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [parent] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << parent if parent compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*parent, delimiter_loc, name_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?parent: Prism::node?, ?name: Symbol?, ?delimiter_loc: Location, ?name_loc: Location) -> ConstantPathTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, parent: self.parent, name: self.name, delimiter_loc: self.delimiter_loc, name_loc: self.name_loc) ConstantPathTargetNode.new(source, node_id, location, flags, parent, name, delimiter_loc, name_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, parent: Prism::node?, name: Symbol?, delimiter_loc: Location, name_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, parent: parent, name: name, delimiter_loc: delimiter_loc, name_loc: name_loc } end # attr_reader parent: Prism::node? attr_reader :parent # attr_reader name: Symbol? attr_reader :name # attr_reader delimiter_loc: Location def delimiter_loc location = @delimiter_loc return location if location.is_a?(Location) @delimiter_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the delimiter_loc location using the given saved source so that # it can be retrieved later. def save_delimiter_loc(repository) repository.enter(node_id, :delimiter_loc) end # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # def delimiter: () -> String def delimiter delimiter_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathTargetNode) && (parent === other.parent) && (name === other.name) && (delimiter_loc.nil? == other.delimiter_loc.nil?) && (name_loc.nil? == other.name_loc.nil?) end end # Represents writing to a constant path. # # ::Foo = 1 # ^^^^^^^^^ # # Foo::Bar = 1 # ^^^^^^^^^^^^ # # ::Foo::Bar = 1 # ^^^^^^^^^^^^^^ class ConstantPathWriteNode < Node # Initialize a new ConstantPathWriteNode node. def initialize(source, node_id, location, flags, target, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @target = target @operator_loc = operator_loc @value = value 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [target, value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [target, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?target: ConstantPathNode, ?operator_loc: Location, ?value: Prism::node) -> ConstantPathWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, target: self.target, operator_loc: self.operator_loc, value: self.value) ConstantPathWriteNode.new(source, node_id, location, flags, target, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, target: ConstantPathNode, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, target: target, operator_loc: operator_loc, value: value } end # A node representing the constant path being written to. # # Foo::Bar = 1 # ^^^^^^^^ # # ::Foo = :abc # ^^^^^ attr_reader :target # The location of the `=` operator. # # ::ABC = 123 # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # The value to write to the constant path. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # FOO::BAR = :abc # ^^^^ attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_path_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_path_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantPathWriteNode) && (target === other.target) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents referencing a constant. # # Foo # ^^^ class ConstantReadNode < Node # Initialize a new ConstantReadNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) ConstantReadNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). # # X # name `:X` # # SOME_CONSTANT # name `:SOME_CONSTANT` attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantReadNode) && (name === other.name) end end # Represents writing to a constant in a context that doesn't have an explicit value. # # Foo, Bar = baz # ^^^ ^^^ class ConstantTargetNode < Node # Initialize a new ConstantTargetNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> ConstantTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) ConstantTargetNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # attr_reader name: Symbol attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantTargetNode) && (name === other.name) end end # Represents writing to a constant. # # Foo = 1 # ^^^^^^^ class ConstantWriteNode < Node # Initialize a new ConstantWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @value = value @operator_loc = operator_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_constant_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> ConstantWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) ConstantWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } end # The name of the [constant](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#constants). # # Foo = :bar # name `:Foo` # # XYZ = 1 # name `:XYZ` attr_reader :name # The location of the constant name. # # FOO = 1 # ^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # The value to write to the constant. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # FOO = :bar # ^^^^ # # MyClass = Class.new # ^^^^^^^^^ attr_reader :value # The location of the `=` operator. # # FOO = :bar # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :constant_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :constant_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ConstantWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a method definition. # # def method # end # ^^^^^^^^^^ class DefNode < Node # Initialize a new DefNode node. def initialize(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @receiver = receiver @parameters = parameters @body = body @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 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << parameters if parameters compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, *receiver, *parameters, *body, def_keyword_loc, *operator_loc, *lparen_loc, *rparen_loc, *equal_loc, *end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?receiver: Prism::node?, ?parameters: ParametersNode?, ?body: StatementsNode | BeginNode | nil, ?locals: Array[Symbol], ?def_keyword_loc: Location, ?operator_loc: Location?, ?lparen_loc: Location?, ?rparen_loc: Location?, ?equal_loc: Location?, ?end_keyword_loc: Location?) -> DefNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, receiver: self.receiver, parameters: self.parameters, body: self.body, locals: self.locals, def_keyword_loc: self.def_keyword_loc, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, equal_loc: self.equal_loc, end_keyword_loc: self.end_keyword_loc) DefNode.new(source, node_id, location, flags, name, name_loc, receiver, parameters, body, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, receiver: Prism::node?, parameters: ParametersNode?, body: StatementsNode | BeginNode | nil, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, receiver: receiver, parameters: parameters, body: body, 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 } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader receiver: Prism::node? attr_reader :receiver # attr_reader parameters: ParametersNode? attr_reader :parameters # attr_reader body: StatementsNode | BeginNode | nil attr_reader :body # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader def_keyword_loc: Location def def_keyword_loc location = @def_keyword_loc return location if location.is_a?(Location) @def_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the def_keyword_loc location using the given saved source so that # it can be retrieved later. def save_def_keyword_loc(repository) repository.enter(node_id, :def_keyword_loc) end # attr_reader operator_loc: Location? def operator_loc location = @operator_loc case location when nil nil when Location location else @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) unless @operator_loc.nil? end # attr_reader lparen_loc: Location? def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # attr_reader rparen_loc: Location? def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # attr_reader equal_loc: Location? def equal_loc location = @equal_loc case location when nil nil when Location location else @equal_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the equal_loc location using the given saved source so that # it can be retrieved later. def save_equal_loc(repository) repository.enter(node_id, :equal_loc) unless @equal_loc.nil? end # attr_reader end_keyword_loc: Location? def end_keyword_loc location = @end_keyword_loc case location when nil nil when Location location else @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? end # def def_keyword: () -> String def def_keyword def_keyword_loc.slice end # def operator: () -> String? def operator operator_loc&.slice end # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def equal: () -> String? def equal equal_loc&.slice end # def end_keyword: () -> String? def end_keyword end_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :def_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :def_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(DefNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (receiver === other.receiver) && (parameters === other.parameters) && (body === other.body) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (def_keyword_loc.nil? == other.def_keyword_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (lparen_loc.nil? == other.lparen_loc.nil?) && (rparen_loc.nil? == other.rparen_loc.nil?) && (equal_loc.nil? == other.equal_loc.nil?) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents the use of the `defined?` keyword. # # defined?(a) # ^^^^^^^^^^^ class DefinedNode < Node # Initialize a new DefinedNode node. def initialize(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @lparen_loc = lparen_loc @value = value @rparen_loc = rparen_loc @keyword_loc = keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*lparen_loc, value, *rparen_loc, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lparen_loc: Location?, ?value: Prism::node, ?rparen_loc: Location?, ?keyword_loc: Location) -> DefinedNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, lparen_loc: self.lparen_loc, value: self.value, rparen_loc: self.rparen_loc, keyword_loc: self.keyword_loc) DefinedNode.new(source, node_id, location, flags, lparen_loc, value, rparen_loc, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lparen_loc: Location?, value: Prism::node, rparen_loc: Location?, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, lparen_loc: lparen_loc, value: value, rparen_loc: rparen_loc, keyword_loc: keyword_loc } end # attr_reader lparen_loc: Location? def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # attr_reader value: Prism::node attr_reader :value # attr_reader rparen_loc: Location? def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :defined_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :defined_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(DefinedNode) && (lparen_loc.nil? == other.lparen_loc.nil?) && (value === other.value) && (rparen_loc.nil? == other.rparen_loc.nil?) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents an `else` clause in a `case`, `if`, or `unless` statement. # # if a then b else c end # ^^^^^^^^^^ class ElseNode < Node # Initialize a new ElseNode node. def initialize(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @else_keyword_loc = else_keyword_loc @statements = statements @end_keyword_loc = end_keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [else_keyword_loc, *statements, *end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?else_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location?) -> ElseNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, else_keyword_loc: self.else_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc) ElseNode.new(source, node_id, location, flags, else_keyword_loc, statements, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, else_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, else_keyword_loc: else_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc } end # attr_reader else_keyword_loc: Location def else_keyword_loc location = @else_keyword_loc return location if location.is_a?(Location) @else_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the else_keyword_loc location using the given saved source so that # it can be retrieved later. def save_else_keyword_loc(repository) repository.enter(node_id, :else_keyword_loc) end # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader end_keyword_loc: Location? def end_keyword_loc location = @end_keyword_loc case location when nil nil when Location location else @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? end # def else_keyword: () -> String def else_keyword else_keyword_loc.slice end # def end_keyword: () -> String? def end_keyword end_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :else_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :else_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ElseNode) && (else_keyword_loc.nil? == other.else_keyword_loc.nil?) && (statements === other.statements) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents an interpolated set of statements. # # "foo #{bar}" # ^^^^^^ class EmbeddedStatementsNode < Node # Initialize a new EmbeddedStatementsNode node. def initialize(source, node_id, location, flags, opening_loc, statements, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @statements = statements @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, *statements, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?statements: StatementsNode?, ?closing_loc: Location) -> EmbeddedStatementsNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, statements: self.statements, closing_loc: self.closing_loc) EmbeddedStatementsNode.new(source, node_id, location, flags, opening_loc, statements, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, statements: StatementsNode?, closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, statements: statements, closing_loc: closing_loc } end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :embedded_statements_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :embedded_statements_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(EmbeddedStatementsNode) && (opening_loc.nil? == other.opening_loc.nil?) && (statements === other.statements) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents an interpolated variable. # # "foo #@bar" # ^^^^^ class EmbeddedVariableNode < Node # Initialize a new EmbeddedVariableNode node. def initialize(source, node_id, location, flags, operator_loc, variable) @source = source @node_id = node_id @location = location @flags = flags @operator_loc = operator_loc @variable = variable 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [variable] end # def comment_targets: () -> Array[Node | Location] def comment_targets [operator_loc, variable] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode) -> EmbeddedVariableNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, variable: self.variable) EmbeddedVariableNode.new(source, node_id, location, flags, operator_loc, variable) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode } def deconstruct_keys(keys) { node_id: node_id, location: location, operator_loc: operator_loc, variable: variable } end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader variable: InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode attr_reader :variable # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :embedded_variable_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :embedded_variable_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(EmbeddedVariableNode) && (operator_loc.nil? == other.operator_loc.nil?) && (variable === other.variable) end end # Represents an `ensure` clause in a `begin` statement. # # begin # foo # ensure # ^^^^^^ # bar # end class EnsureNode < Node # Initialize a new EnsureNode node. def initialize(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @ensure_keyword_loc = ensure_keyword_loc @statements = statements @end_keyword_loc = end_keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [ensure_keyword_loc, *statements, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?ensure_keyword_loc: Location, ?statements: StatementsNode?, ?end_keyword_loc: Location) -> EnsureNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, ensure_keyword_loc: self.ensure_keyword_loc, statements: self.statements, end_keyword_loc: self.end_keyword_loc) EnsureNode.new(source, node_id, location, flags, ensure_keyword_loc, statements, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, ensure_keyword_loc: Location, statements: StatementsNode?, end_keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, ensure_keyword_loc: ensure_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc } end # attr_reader ensure_keyword_loc: Location def ensure_keyword_loc location = @ensure_keyword_loc return location if location.is_a?(Location) @ensure_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the ensure_keyword_loc location using the given saved source so that # it can be retrieved later. def save_ensure_keyword_loc(repository) repository.enter(node_id, :ensure_keyword_loc) end # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader end_keyword_loc: Location def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # def ensure_keyword: () -> String def ensure_keyword ensure_keyword_loc.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :ensure_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :ensure_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(EnsureNode) && (ensure_keyword_loc.nil? == other.ensure_keyword_loc.nil?) && (statements === other.statements) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents the use of the literal `false` keyword. # # false # ^^^^^ class FalseNode < Node # Initialize a new FalseNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> FalseNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) FalseNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :false_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :false_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(FalseNode) 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 # Initialize a new FindPatternNode node. def initialize(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @constant = constant @left = left @requireds = requireds @right = right @opening_loc = opening_loc @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << constant if constant compact << left compact.concat(requireds) compact << right compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*constant, left, *requireds, right, *opening_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?left: SplatNode, ?requireds: Array[Prism::node], ?right: SplatNode | MissingNode, ?opening_loc: Location?, ?closing_loc: Location?) -> FindPatternNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, left: self.left, requireds: self.requireds, right: self.right, opening_loc: self.opening_loc, closing_loc: self.closing_loc) FindPatternNode.new(source, node_id, location, flags, constant, left, requireds, right, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, left: SplatNode, requireds: Array[Prism::node], right: SplatNode | MissingNode, opening_loc: Location?, closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, constant: constant, left: left, requireds: requireds, right: right, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader constant: ConstantReadNode | ConstantPathNode | nil attr_reader :constant # attr_reader left: SplatNode attr_reader :left # attr_reader requireds: Array[Prism::node] attr_reader :requireds # attr_reader right: SplatNode | MissingNode attr_reader :right # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :find_pattern_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :find_pattern_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(FindPatternNode) && (constant === other.constant) && (left === other.left) && (requireds.length == other.requireds.length) && requireds.zip(other.requireds).all? { |left, right| left === right } && (right === other.right) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents the use of the `..` or `...` operators to create flip flops. # # baz if foo .. bar # ^^^^^^^^^^ class FlipFlopNode < Node # Initialize a new FlipFlopNode node. def initialize(source, node_id, location, flags, left, right, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @left = left @right = right @operator_loc = operator_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_flip_flop_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [left, right] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << left if left compact << right if right compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*left, *right, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> FlipFlopNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) FlipFlopNode.new(source, node_id, location, flags, left, right, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } end # def exclude_end?: () -> bool def exclude_end? flags.anybits?(RangeFlags::EXCLUDE_END) end # attr_reader left: Prism::node? attr_reader :left # attr_reader right: Prism::node? attr_reader :right # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :flip_flop_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :flip_flop_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(FlipFlopNode) && (flags === other.flags) && (left === other.left) && (right === other.right) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a floating point number literal. # # 1.0 # ^^^ class FloatNode < Node # Initialize a new FloatNode node. def initialize(source, node_id, location, flags, value) @source = source @node_id = node_id @location = location @flags = flags @value = value 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Float) -> FloatNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) FloatNode.new(source, node_id, location, flags, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Float } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value } end # The value of the floating point number as a Float. attr_reader :value # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :float_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :float_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(FloatNode) && (value === other.value) end end # Represents the use of the `for` keyword. # # for i in a end # ^^^^^^^^^^^^^^ class ForNode < Node # Initialize a new ForNode node. def initialize(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @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 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << index compact << collection compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [index, collection, *statements, for_keyword_loc, in_keyword_loc, *do_keyword_loc, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, ?collection: Prism::node, ?statements: StatementsNode?, ?for_keyword_loc: Location, ?in_keyword_loc: Location, ?do_keyword_loc: Location?, ?end_keyword_loc: Location) -> ForNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, index: self.index, collection: self.collection, statements: self.statements, for_keyword_loc: self.for_keyword_loc, in_keyword_loc: self.in_keyword_loc, do_keyword_loc: self.do_keyword_loc, end_keyword_loc: self.end_keyword_loc) ForNode.new(source, node_id, location, flags, index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, index: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode, collection: Prism::node, statements: StatementsNode?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, 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 } end # The index expression for `for` loops. # # for i in a end # ^ attr_reader :index # The collection to iterate over. # # for i in a end # ^ attr_reader :collection # Represents the body of statements to execute for each iteration of the loop. # # for i in a # foo(i) # ^^^^^^ # end attr_reader :statements # The location of the `for` keyword. # # for i in a end # ^^^ def for_keyword_loc location = @for_keyword_loc return location if location.is_a?(Location) @for_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the for_keyword_loc location using the given saved source so that # it can be retrieved later. def save_for_keyword_loc(repository) repository.enter(node_id, :for_keyword_loc) end # The location of the `in` keyword. # # for i in a end # ^^ def in_keyword_loc location = @in_keyword_loc return location if location.is_a?(Location) @in_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the in_keyword_loc location using the given saved source so that # it can be retrieved later. def save_in_keyword_loc(repository) repository.enter(node_id, :in_keyword_loc) end # The location of the `do` keyword, if present. # # for i in a do end # ^^ def do_keyword_loc location = @do_keyword_loc case location when nil nil when Location location else @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the do_keyword_loc location using the given saved source so that # it can be retrieved later. def save_do_keyword_loc(repository) repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? end # The location of the `end` keyword. # # for i in a end # ^^^ def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # def for_keyword: () -> String def for_keyword for_keyword_loc.slice end # def in_keyword: () -> String def in_keyword in_keyword_loc.slice end # def do_keyword: () -> String? def do_keyword do_keyword_loc&.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :for_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :for_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ForNode) && (index === other.index) && (collection === other.collection) && (statements === other.statements) && (for_keyword_loc.nil? == other.for_keyword_loc.nil?) && (in_keyword_loc.nil? == other.in_keyword_loc.nil?) && (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents forwarding all arguments to this method to another method. # # def foo(...) # bar(...) # ^^^ # end class ForwardingArgumentsNode < Node # Initialize a new ForwardingArgumentsNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingArgumentsNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) ForwardingArgumentsNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :forwarding_arguments_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :forwarding_arguments_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ForwardingArgumentsNode) end end # Represents the use of the forwarding parameter in a method, block, or lambda declaration. # # def foo(...) # ^^^ # end class ForwardingParameterNode < Node # Initialize a new ForwardingParameterNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ForwardingParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) ForwardingParameterNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :forwarding_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :forwarding_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ForwardingParameterNode) end end # Represents the use of the `super` keyword without parentheses or arguments. # # super # ^^^^^ class ForwardingSuperNode < Node # Initialize a new ForwardingSuperNode node. def initialize(source, node_id, location, flags, block) @source = source @node_id = node_id @location = location @flags = flags @block = block 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << block if block compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*block] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?block: BlockNode?) -> ForwardingSuperNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, block: self.block) ForwardingSuperNode.new(source, node_id, location, flags, block) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, block: BlockNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, block: block } end # attr_reader block: BlockNode? attr_reader :block # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :forwarding_super_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :forwarding_super_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ForwardingSuperNode) && (block === other.block) end end # Represents the use of the `&&=` operator for assignment to a global variable. # # $target &&= value # ^^^^^^^^^^^^^^^^^ class GlobalVariableAndWriteNode < Node # Initialize a new GlobalVariableAndWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_global_variable_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) GlobalVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableAndWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to a global variable using an operator that isn't `=`. # # $target += value # ^^^^^^^^^^^^^^^^ class GlobalVariableOperatorWriteNode < Node # Initialize a new GlobalVariableOperatorWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @binary_operator_loc = binary_operator_loc @value = value @binary_operator = binary_operator 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> GlobalVariableOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) GlobalVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader binary_operator: Symbol attr_reader :binary_operator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableOperatorWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (binary_operator === other.binary_operator) end end # Represents the use of the `||=` operator for assignment to a global variable. # # $target ||= value # ^^^^^^^^^^^^^^^^^ class GlobalVariableOrWriteNode < Node # Initialize a new GlobalVariableOrWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_global_variable_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> GlobalVariableOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) GlobalVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableOrWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents referencing a global variable. # # $foo # ^^^^ class GlobalVariableReadNode < Node # Initialize a new GlobalVariableReadNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) GlobalVariableReadNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. # # $foo # name `:$foo` # # $_Test # name `:$_Test` attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableReadNode) && (name === other.name) end end # Represents writing to a global variable in a context that doesn't have an explicit value. # # $foo, $bar = baz # ^^^^ ^^^^ class GlobalVariableTargetNode < Node # Initialize a new GlobalVariableTargetNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_global_variable_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> GlobalVariableTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) GlobalVariableTargetNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # attr_reader name: Symbol attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableTargetNode) && (name === other.name) end end # Represents writing to a global variable. # # $foo = 1 # ^^^^^^^^ class GlobalVariableWriteNode < Node # Initialize a new GlobalVariableWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> GlobalVariableWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) GlobalVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } end # The name of the global variable, which is a `$` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifier). Alternatively, it can be one of the special global variables designated by a symbol. # # $foo = :bar # name `:$foo` # # $_Test = 123 # name `:$_Test` attr_reader :name # The location of the global variable's name. # # $foo = :bar # ^^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # The value to write to the global variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # $foo = :bar # ^^^^ # # $-xyz = 123 # ^^^ attr_reader :value # The location of the `=` operator. # # $foo = :bar # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :global_variable_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :global_variable_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(GlobalVariableWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a hash literal. # # { a => b } # ^^^^^^^^^^ class HashNode < Node # Initialize a new HashNode node. def initialize(source, node_id, location, flags, opening_loc, elements, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @elements = elements @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*elements] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, *elements, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?elements: Array[AssocNode | AssocSplatNode], ?closing_loc: Location) -> HashNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, elements: self.elements, closing_loc: self.closing_loc) HashNode.new(source, node_id, location, flags, opening_loc, elements, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, elements: Array[AssocNode | AssocSplatNode], closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, elements: elements, closing_loc: closing_loc } end # The location of the opening brace. # # { a => b } # ^ def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # The elements of the hash. These can be either `AssocNode`s or `AssocSplatNode`s. # # { a: b } # ^^^^ # # { **foo } # ^^^^^ attr_reader :elements # The location of the closing brace. # # { a => b } # ^ def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :hash_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :hash_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(HashNode) && (opening_loc.nil? == other.opening_loc.nil?) && (elements.length == other.elements.length) && elements.zip(other.elements).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a hash pattern in pattern matching. # # foo => { a: 1, b: 2 } # ^^^^^^^^^^^^^^ # # foo => { a: 1, b: 2, **c } # ^^^^^^^^^^^^^^^^^^^ class HashPatternNode < Node # Initialize a new HashPatternNode node. def initialize(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @constant = constant @elements = elements @rest = rest @opening_loc = opening_loc @closing_loc = closing_loc 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, *elements, rest] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << constant if constant compact.concat(elements) compact << rest if rest compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*constant, *elements, *rest, *opening_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?constant: ConstantReadNode | ConstantPathNode | nil, ?elements: Array[AssocNode], ?rest: AssocSplatNode | NoKeywordsParameterNode | nil, ?opening_loc: Location?, ?closing_loc: Location?) -> HashPatternNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, constant: self.constant, elements: self.elements, rest: self.rest, opening_loc: self.opening_loc, closing_loc: self.closing_loc) HashPatternNode.new(source, node_id, location, flags, constant, elements, rest, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, constant: ConstantReadNode | ConstantPathNode | nil, elements: Array[AssocNode], rest: AssocSplatNode | NoKeywordsParameterNode | nil, opening_loc: Location?, closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, constant: constant, elements: elements, rest: rest, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader constant: ConstantReadNode | ConstantPathNode | nil attr_reader :constant # attr_reader elements: Array[AssocNode] attr_reader :elements # attr_reader rest: AssocSplatNode | NoKeywordsParameterNode | nil attr_reader :rest # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :hash_pattern_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :hash_pattern_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(HashPatternNode) && (constant === other.constant) && (elements.length == other.elements.length) && elements.zip(other.elements).all? { |left, right| left === right } && (rest === other.rest) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents the use of the `if` keyword, either in the block form or the modifier form, or a ternary expression. # # bar if foo # ^^^^^^^^^^ # # if foo then bar end # ^^^^^^^^^^^^^^^^^^^ # # foo ? bar : baz # ^^^^^^^^^^^^^^^ class IfNode < Node # Initialize a new IfNode node. def initialize(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @if_keyword_loc = if_keyword_loc @predicate = predicate @then_keyword_loc = then_keyword_loc @statements = statements @subsequent = subsequent @end_keyword_loc = end_keyword_loc 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, subsequent] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate compact << statements if statements compact << subsequent if subsequent compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*if_keyword_loc, predicate, *then_keyword_loc, *statements, *subsequent, *end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?if_keyword_loc: Location?, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?subsequent: ElseNode | IfNode | nil, ?end_keyword_loc: Location?) -> IfNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, if_keyword_loc: self.if_keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, subsequent: self.subsequent, end_keyword_loc: self.end_keyword_loc) IfNode.new(source, node_id, location, flags, if_keyword_loc, predicate, then_keyword_loc, statements, subsequent, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, if_keyword_loc: Location?, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, subsequent: ElseNode | IfNode | nil, end_keyword_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, if_keyword_loc: if_keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, subsequent: subsequent, end_keyword_loc: end_keyword_loc } end # The location of the `if` keyword if present. # # bar if foo # ^^ # # The `if_keyword_loc` field will be `nil` when the `IfNode` represents a ternary expression. def if_keyword_loc location = @if_keyword_loc case location when nil nil when Location location else @if_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the if_keyword_loc location using the given saved source so that # it can be retrieved later. def save_if_keyword_loc(repository) repository.enter(node_id, :if_keyword_loc) unless @if_keyword_loc.nil? end # The node for the condition the `IfNode` is testing. # # if foo # ^^^ # bar # end # # bar if foo # ^^^ # # foo ? bar : baz # ^^^ attr_reader :predicate # The location of the `then` keyword (if present) or the `?` in a ternary expression, `nil` otherwise. # # if foo then bar end # ^^^^ # # a ? b : c # ^ def then_keyword_loc location = @then_keyword_loc case location when nil nil when Location location else @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the then_keyword_loc location using the given saved source so that # it can be retrieved later. def save_then_keyword_loc(repository) repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? end # Represents the body of statements that will be executed when the predicate is evaluated as truthy. Will be `nil` when no body is provided. # # if foo # bar # ^^^ # baz # ^^^ # end attr_reader :statements # Represents an `ElseNode` or an `IfNode` when there is an `else` or an `elsif` in the `if` statement. # # if foo # bar # elsif baz # ^^^^^^^^^ # qux # ^^^ # end # ^^^ # # if foo then bar else baz end # ^^^^^^^^^^^^ attr_reader :subsequent # The location of the `end` keyword if present, `nil` otherwise. # # if foo # bar # end # ^^^ def end_keyword_loc location = @end_keyword_loc case location when nil nil when Location location else @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? end # def if_keyword: () -> String? def if_keyword if_keyword_loc&.slice end # def then_keyword: () -> String? def then_keyword then_keyword_loc&.slice end # def end_keyword: () -> String? def end_keyword end_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :if_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :if_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IfNode) && (if_keyword_loc.nil? == other.if_keyword_loc.nil?) && (predicate === other.predicate) && (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && (statements === other.statements) && (subsequent === other.subsequent) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents an imaginary number literal. # # 1.0i # ^^^^ class ImaginaryNode < Node # Initialize a new ImaginaryNode node. def initialize(source, node_id, location, flags, numeric) @source = source @node_id = node_id @location = location @flags = flags @numeric = numeric 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [numeric] end # def comment_targets: () -> Array[Node | Location] def comment_targets [numeric] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numeric: FloatNode | IntegerNode | RationalNode) -> ImaginaryNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, numeric: self.numeric) ImaginaryNode.new(source, node_id, location, flags, numeric) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numeric: FloatNode | IntegerNode | RationalNode } def deconstruct_keys(keys) { node_id: node_id, location: location, numeric: numeric } end # attr_reader numeric: FloatNode | IntegerNode | RationalNode attr_reader :numeric # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :imaginary_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :imaginary_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ImaginaryNode) && (numeric === other.numeric) end end # Represents a node that is implicitly being added to the tree but doesn't correspond directly to a node in the source. # # { foo: } # ^^^^ # # { Foo: } # ^^^^ # # foo in { bar: } # ^^^^ class ImplicitNode < Node # Initialize a new ImplicitNode node. def initialize(source, node_id, location, flags, value) @source = source @node_id = node_id @location = location @flags = flags @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_implicit_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode) -> ImplicitNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) ImplicitNode.new(source, node_id, location, flags, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value } end # attr_reader value: LocalVariableReadNode | CallNode | ConstantReadNode | LocalVariableTargetNode attr_reader :value # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :implicit_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :implicit_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ImplicitNode) && (value === other.value) end end # Represents using a trailing comma to indicate an implicit rest parameter. # # foo { |bar,| } # ^ # # foo in [bar,] # ^ # # for foo, in bar do end # ^ # # foo, = bar # ^ class ImplicitRestNode < Node # Initialize a new ImplicitRestNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_implicit_rest_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ImplicitRestNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) ImplicitRestNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :implicit_rest_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :implicit_rest_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ImplicitRestNode) end end # Represents the use of the `in` keyword in a case statement. # # case a; in b then c end # ^^^^^^^^^^^ class InNode < Node # Initialize a new InNode node. def initialize(source, node_id, location, flags, pattern, statements, in_loc, then_loc) @source = source @node_id = node_id @location = location @flags = flags @pattern = pattern @statements = statements @in_loc = in_loc @then_loc = then_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << pattern compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [pattern, *statements, in_loc, *then_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?pattern: Prism::node, ?statements: StatementsNode?, ?in_loc: Location, ?then_loc: Location?) -> InNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, pattern: self.pattern, statements: self.statements, in_loc: self.in_loc, then_loc: self.then_loc) InNode.new(source, node_id, location, flags, pattern, statements, in_loc, then_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, pattern: Prism::node, statements: StatementsNode?, in_loc: Location, then_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, pattern: pattern, statements: statements, in_loc: in_loc, then_loc: then_loc } end # attr_reader pattern: Prism::node attr_reader :pattern # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader in_loc: Location def in_loc location = @in_loc return location if location.is_a?(Location) @in_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the in_loc location using the given saved source so that # it can be retrieved later. def save_in_loc(repository) repository.enter(node_id, :in_loc) end # attr_reader then_loc: Location? def then_loc location = @then_loc case location when nil nil when Location location else @then_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the then_loc location using the given saved source so that # it can be retrieved later. def save_then_loc(repository) repository.enter(node_id, :then_loc) unless @then_loc.nil? end # def in: () -> String def in in_loc.slice end # def then: () -> String? def then then_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :in_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :in_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InNode) && (pattern === other.pattern) && (statements === other.statements) && (in_loc.nil? == other.in_loc.nil?) && (then_loc.nil? == other.then_loc.nil?) end end # Represents the use of the `&&=` operator on a call to the `[]` method. # # foo.bar[baz] &&= value # ^^^^^^^^^^^^^^^^^^^^^^ class IndexAndWriteNode < Node # Initialize a new IndexAndWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @opening_loc = opening_loc @arguments = arguments @closing_loc = closing_loc @block = block @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_index_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, arguments, block, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << arguments if arguments compact << block if block compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value) IndexAndWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # attr_reader receiver: Prism::node? attr_reader :receiver # attr_reader call_operator_loc: Location? def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader block: BlockArgumentNode? attr_reader :block # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :index_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :index_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IndexAndWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (arguments === other.arguments) && (closing_loc.nil? == other.closing_loc.nil?) && (block === other.block) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents the use of an assignment operator on a call to `[]`. # # foo.bar[baz] += value # ^^^^^^^^^^^^^^^^^^^^^ class IndexOperatorWriteNode < Node # Initialize a new IndexOperatorWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @opening_loc = opening_loc @arguments = arguments @closing_loc = closing_loc @block = block @binary_operator = binary_operator @binary_operator_loc = binary_operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_index_operator_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, arguments, block, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << arguments if arguments compact << block if block compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?binary_operator: Symbol, ?binary_operator_loc: Location, ?value: Prism::node) -> IndexOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, binary_operator: self.binary_operator, binary_operator_loc: self.binary_operator_loc, value: self.value) IndexOperatorWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, binary_operator, binary_operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, binary_operator: Symbol, binary_operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, binary_operator: binary_operator, binary_operator_loc: binary_operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # attr_reader receiver: Prism::node? attr_reader :receiver # attr_reader call_operator_loc: Location? def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader block: BlockArgumentNode? attr_reader :block # attr_reader binary_operator: Symbol attr_reader :binary_operator # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :index_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :index_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IndexOperatorWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (arguments === other.arguments) && (closing_loc.nil? == other.closing_loc.nil?) && (block === other.block) && (binary_operator === other.binary_operator) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) end end # Represents the use of the `||=` operator on a call to `[]`. # # foo.bar[baz] ||= value # ^^^^^^^^^^^^^^^^^^^^^^ class IndexOrWriteNode < Node # Initialize a new IndexOrWriteNode node. def initialize(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @call_operator_loc = call_operator_loc @opening_loc = opening_loc @arguments = arguments @closing_loc = closing_loc @block = block @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_index_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, arguments, block, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver if receiver compact << arguments if arguments compact << block if block compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node?, ?call_operator_loc: Location?, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?, ?operator_loc: Location, ?value: Prism::node) -> IndexOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, call_operator_loc: self.call_operator_loc, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block, operator_loc: self.operator_loc, value: self.value) IndexOrWriteNode.new(source, node_id, location, flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode?, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, call_operator_loc: call_operator_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, operator_loc: operator_loc, value: value } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # attr_reader receiver: Prism::node? attr_reader :receiver # attr_reader call_operator_loc: Location? def call_operator_loc location = @call_operator_loc case location when nil nil when Location location else @call_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the call_operator_loc location using the given saved source so that # it can be retrieved later. def save_call_operator_loc(repository) repository.enter(node_id, :call_operator_loc) unless @call_operator_loc.nil? end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader block: BlockArgumentNode? attr_reader :block # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def call_operator: () -> String? def call_operator call_operator_loc&.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :index_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :index_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IndexOrWriteNode) && (flags === other.flags) && (receiver === other.receiver) && (call_operator_loc.nil? == other.call_operator_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (arguments === other.arguments) && (closing_loc.nil? == other.closing_loc.nil?) && (block === other.block) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to an index. # # foo[bar], = 1 # ^^^^^^^^ # # begin # rescue => foo[bar] # ^^^^^^^^ # end # # for foo[bar] in baz do end # ^^^^^^^^ class IndexTargetNode < Node # Initialize a new IndexTargetNode node. def initialize(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block) @source = source @node_id = node_id @location = location @flags = flags @receiver = receiver @opening_loc = opening_loc @arguments = arguments @closing_loc = closing_loc @block = block end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_index_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [receiver, arguments, block] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << receiver compact << arguments if arguments compact << block if block compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [receiver, opening_loc, *arguments, closing_loc, *block] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?receiver: Prism::node, ?opening_loc: Location, ?arguments: ArgumentsNode?, ?closing_loc: Location, ?block: BlockArgumentNode?) -> IndexTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, receiver: self.receiver, opening_loc: self.opening_loc, arguments: self.arguments, closing_loc: self.closing_loc, block: self.block) IndexTargetNode.new(source, node_id, location, flags, receiver, opening_loc, arguments, closing_loc, block) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, receiver: Prism::node, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: BlockArgumentNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, receiver: receiver, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block } end # def safe_navigation?: () -> bool def safe_navigation? flags.anybits?(CallNodeFlags::SAFE_NAVIGATION) end # def variable_call?: () -> bool def variable_call? flags.anybits?(CallNodeFlags::VARIABLE_CALL) end # def attribute_write?: () -> bool def attribute_write? flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE) end # def ignore_visibility?: () -> bool def ignore_visibility? flags.anybits?(CallNodeFlags::IGNORE_VISIBILITY) end # attr_reader receiver: Prism::node attr_reader :receiver # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader block: BlockArgumentNode? attr_reader :block # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :index_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :index_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IndexTargetNode) && (flags === other.flags) && (receiver === other.receiver) && (opening_loc.nil? == other.opening_loc.nil?) && (arguments === other.arguments) && (closing_loc.nil? == other.closing_loc.nil?) && (block === other.block) end end # Represents the use of the `&&=` operator for assignment to an instance variable. # # @target &&= value # ^^^^^^^^^^^^^^^^^ class InstanceVariableAndWriteNode < Node # Initialize a new InstanceVariableAndWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_instance_variable_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) InstanceVariableAndWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableAndWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents assigning to an instance variable using an operator that isn't `=`. # # @target += value # ^^^^^^^^^^^^^^^^ class InstanceVariableOperatorWriteNode < Node # Initialize a new InstanceVariableOperatorWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @binary_operator_loc = binary_operator_loc @value = value @binary_operator = binary_operator 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?binary_operator: Symbol) -> InstanceVariableOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, binary_operator: self.binary_operator) InstanceVariableOperatorWriteNode.new(source, node_id, location, flags, name, name_loc, binary_operator_loc, value, binary_operator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, binary_operator_loc: Location, value: Prism::node, binary_operator: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, binary_operator: binary_operator } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader binary_operator: Symbol attr_reader :binary_operator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableOperatorWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (binary_operator === other.binary_operator) end end # Represents the use of the `||=` operator for assignment to an instance variable. # # @target ||= value # ^^^^^^^^^^^^^^^^^ class InstanceVariableOrWriteNode < Node # Initialize a new InstanceVariableOrWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_instance_variable_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> InstanceVariableOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) InstanceVariableOrWriteNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableOrWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents referencing an instance variable. # # @foo # ^^^^ class InstanceVariableReadNode < Node # Initialize a new InstanceVariableReadNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) InstanceVariableReadNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # @x # name `:@x` # # @_test # name `:@_test` attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableReadNode) && (name === other.name) end end # Represents writing to an instance variable in a context that doesn't have an explicit value. # # @foo, @bar = baz # ^^^^ ^^^^ class InstanceVariableTargetNode < Node # Initialize a new InstanceVariableTargetNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_instance_variable_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> InstanceVariableTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) InstanceVariableTargetNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # attr_reader name: Symbol attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableTargetNode) && (name === other.name) end end # Represents writing to an instance variable. # # @foo = 1 # ^^^^^^^^ class InstanceVariableWriteNode < Node # Initialize a new InstanceVariableWriteNode node. def initialize(source, node_id, location, flags, name, name_loc, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> InstanceVariableWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) InstanceVariableWriteNode.new(source, node_id, location, flags, name, name_loc, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value, operator_loc: operator_loc } end # The name of the instance variable, which is a `@` followed by an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # @x = :y # name `:@x` # # @_foo = "bar" # name `@_foo` attr_reader :name # The location of the variable name. # # @_x = 1 # ^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # The value to write to the instance variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # @foo = :bar # ^^^^ # # @_x = 1234 # ^^^^ attr_reader :value # The location of the `=` operator. # # @x = y # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :instance_variable_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :instance_variable_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InstanceVariableWriteNode) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents an integer number literal. # # 1 # ^ class IntegerNode < Node # Initialize a new IntegerNode node. def initialize(source, node_id, location, flags, value) @source = source @node_id = node_id @location = location @flags = flags @value = value 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Integer) -> IntegerNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value) IntegerNode.new(source, node_id, location, flags, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value } end # def binary?: () -> bool def binary? flags.anybits?(IntegerBaseFlags::BINARY) end # def decimal?: () -> bool def decimal? flags.anybits?(IntegerBaseFlags::DECIMAL) end # def octal?: () -> bool def octal? flags.anybits?(IntegerBaseFlags::OCTAL) end # def hexadecimal?: () -> bool def hexadecimal? flags.anybits?(IntegerBaseFlags::HEXADECIMAL) end # The value of the integer literal as a number. attr_reader :value # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :integer_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :integer_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(IntegerNode) && (flags === other.flags) && (value === other.value) end end # Represents a regular expression literal that contains interpolation that is being used in the predicate of a conditional to implicitly match against the last line read by an IO object. # # if /foo #{bar} baz/ then end # ^^^^^^^^^^^^^^^^ class InterpolatedMatchLastLineNode < Node # Initialize a new InterpolatedMatchLastLineNode node. def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_interpolated_match_last_line_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [*parts] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [*parts] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedMatchLastLineNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) InterpolatedMatchLastLineNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } end # def ignore_case?: () -> bool def ignore_case? flags.anybits?(RegularExpressionFlags::IGNORE_CASE) end # def extended?: () -> bool def extended? flags.anybits?(RegularExpressionFlags::EXTENDED) end # def multi_line?: () -> bool def multi_line? flags.anybits?(RegularExpressionFlags::MULTI_LINE) end # def once?: () -> bool def once? flags.anybits?(RegularExpressionFlags::ONCE) end # def euc_jp?: () -> bool def euc_jp? flags.anybits?(RegularExpressionFlags::EUC_JP) end # def ascii_8bit?: () -> bool def ascii_8bit? flags.anybits?(RegularExpressionFlags::ASCII_8BIT) end # def windows_31j?: () -> bool def windows_31j? flags.anybits?(RegularExpressionFlags::WINDOWS_31J) end # def utf_8?: () -> bool def utf_8? flags.anybits?(RegularExpressionFlags::UTF_8) end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) end # def forced_us_ascii_encoding?: () -> bool def forced_us_ascii_encoding? flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] attr_reader :parts # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :interpolated_match_last_line_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :interpolated_match_last_line_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InterpolatedMatchLastLineNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (parts.length == other.parts.length) && parts.zip(other.parts).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a regular expression literal that contains interpolation. # # /foo #{bar} baz/ # ^^^^^^^^^^^^^^^^ class InterpolatedRegularExpressionNode < Node # Initialize a new InterpolatedRegularExpressionNode node. def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*parts] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedRegularExpressionNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) InterpolatedRegularExpressionNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } end # def ignore_case?: () -> bool def ignore_case? flags.anybits?(RegularExpressionFlags::IGNORE_CASE) end # def extended?: () -> bool def extended? flags.anybits?(RegularExpressionFlags::EXTENDED) end # def multi_line?: () -> bool def multi_line? flags.anybits?(RegularExpressionFlags::MULTI_LINE) end # def once?: () -> bool def once? flags.anybits?(RegularExpressionFlags::ONCE) end # def euc_jp?: () -> bool def euc_jp? flags.anybits?(RegularExpressionFlags::EUC_JP) end # def ascii_8bit?: () -> bool def ascii_8bit? flags.anybits?(RegularExpressionFlags::ASCII_8BIT) end # def windows_31j?: () -> bool def windows_31j? flags.anybits?(RegularExpressionFlags::WINDOWS_31J) end # def utf_8?: () -> bool def utf_8? flags.anybits?(RegularExpressionFlags::UTF_8) end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) end # def forced_us_ascii_encoding?: () -> bool def forced_us_ascii_encoding? flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] attr_reader :parts # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :interpolated_regular_expression_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :interpolated_regular_expression_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InterpolatedRegularExpressionNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (parts.length == other.parts.length) && parts.zip(other.parts).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a string literal that contains interpolation. # # "foo #{bar} baz" # ^^^^^^^^^^^^^^^^ class InterpolatedStringNode < Node # Initialize a new InterpolatedStringNode node. def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*parts] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode], ?closing_loc: Location?) -> InterpolatedStringNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) InterpolatedStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode], closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } end # def frozen?: () -> bool def frozen? flags.anybits?(InterpolatedStringNodeFlags::FROZEN) end # def mutable?: () -> bool def mutable? flags.anybits?(InterpolatedStringNodeFlags::MUTABLE) end # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode | InterpolatedStringNode] attr_reader :parts # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :interpolated_string_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :interpolated_string_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InterpolatedStringNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (parts.length == other.parts.length) && parts.zip(other.parts).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents a symbol literal that contains interpolation. # # :"foo #{bar} baz" # ^^^^^^^^^^^^^^^^^ class InterpolatedSymbolNode < Node # Initialize a new InterpolatedSymbolNode node. def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*parts] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*opening_loc, *parts, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location?) -> InterpolatedSymbolNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) InterpolatedSymbolNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } end # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] attr_reader :parts # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # def opening: () -> String? def opening opening_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :interpolated_symbol_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :interpolated_symbol_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InterpolatedSymbolNode) && (opening_loc.nil? == other.opening_loc.nil?) && (parts.length == other.parts.length) && parts.zip(other.parts).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents an xstring literal that contains interpolation. # # `foo #{bar} baz` # ^^^^^^^^^^^^^^^^ class InterpolatedXStringNode < Node # Initialize a new InterpolatedXStringNode node. def initialize(source, node_id, location, flags, opening_loc, parts, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*parts] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, *parts, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], ?closing_loc: Location) -> InterpolatedXStringNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, parts: self.parts, closing_loc: self.closing_loc) InterpolatedXStringNode.new(source, node_id, location, flags, opening_loc, parts, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode], closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, parts: parts, closing_loc: closing_loc } end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader parts: Array[StringNode | EmbeddedStatementsNode | EmbeddedVariableNode] attr_reader :parts # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :interpolated_x_string_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :interpolated_x_string_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(InterpolatedXStringNode) && (opening_loc.nil? == other.opening_loc.nil?) && (parts.length == other.parts.length) && parts.zip(other.parts).all? { |left, right| left === right } && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents reading from the implicit `it` local variable. # # -> { it } # ^^ class ItLocalVariableReadNode < Node # Initialize a new ItLocalVariableReadNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_it_local_variable_read_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItLocalVariableReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) ItLocalVariableReadNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :it_local_variable_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :it_local_variable_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ItLocalVariableReadNode) end end # Represents an implicit set of parameters through the use of the `it` keyword within a block or lambda. # # -> { it + it } # ^^^^^^^^^^^^^^ class ItParametersNode < Node # Initialize a new ItParametersNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_it_parameters_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> ItParametersNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) ItParametersNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :it_parameters_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :it_parameters_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ItParametersNode) end end # Represents a hash literal without opening and closing braces. # # foo(a: b) # ^^^^ class KeywordHashNode < Node # Initialize a new KeywordHashNode node. def initialize(source, node_id, location, flags, elements) @source = source @node_id = node_id @location = location @flags = flags @elements = elements 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*elements] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*elements] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?elements: Array[AssocNode | AssocSplatNode]) -> KeywordHashNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, elements: self.elements) KeywordHashNode.new(source, node_id, location, flags, elements) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, elements: Array[AssocNode | AssocSplatNode] } def deconstruct_keys(keys) { node_id: node_id, location: location, elements: elements } end # def symbol_keys?: () -> bool def symbol_keys? flags.anybits?(KeywordHashNodeFlags::SYMBOL_KEYS) end # attr_reader elements: Array[AssocNode | AssocSplatNode] attr_reader :elements # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :keyword_hash_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :keyword_hash_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(KeywordHashNode) && (flags === other.flags) && (elements.length == other.elements.length) && elements.zip(other.elements).all? { |left, right| left === right } end end # Represents a keyword rest parameter to a method, block, or lambda definition. # # def a(**b) # ^^^ # end class KeywordRestParameterNode < Node # Initialize a new KeywordRestParameterNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*name_loc, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> KeywordRestParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) KeywordRestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol? attr_reader :name # attr_reader name_loc: Location? def name_loc location = @name_loc case location when nil nil when Location location else @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) unless @name_loc.nil? end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :keyword_rest_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :keyword_rest_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(KeywordRestParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents using a lambda literal (not the lambda method call). # # ->(value) { value * 2 } # ^^^^^^^^^^^^^^^^^^^^^^^ class LambdaNode < Node # Initialize a new LambdaNode node. def initialize(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @operator_loc = operator_loc @opening_loc = opening_loc @closing_loc = closing_loc @parameters = parameters @body = body 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << parameters if parameters compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [operator_loc, opening_loc, closing_loc, *parameters, *body] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?operator_loc: Location, ?opening_loc: Location, ?closing_loc: Location, ?parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, ?body: StatementsNode | BeginNode | nil) -> LambdaNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, operator_loc: self.operator_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc, parameters: self.parameters, body: self.body) LambdaNode.new(source, node_id, location, flags, locals, operator_loc, opening_loc, closing_loc, parameters, body) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], operator_loc: Location, opening_loc: Location, closing_loc: Location, parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil, body: StatementsNode | BeginNode | nil } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, operator_loc: operator_loc, opening_loc: opening_loc, closing_loc: closing_loc, parameters: parameters, body: body } end # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader parameters: BlockParametersNode | NumberedParametersNode | ItParametersNode | nil attr_reader :parameters # attr_reader body: StatementsNode | BeginNode | nil attr_reader :body # def operator: () -> String def operator operator_loc.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :lambda_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :lambda_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LambdaNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (operator_loc.nil? == other.operator_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (parameters === other.parameters) && (body === other.body) end end # Represents the use of the `&&=` operator for assignment to a local variable. # # target &&= value # ^^^^^^^^^^^^^^^^ class LocalVariableAndWriteNode < Node # Initialize a new LocalVariableAndWriteNode node. def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) @source = source @node_id = node_id @location = location @flags = flags @name_loc = name_loc @operator_loc = operator_loc @value = value @name = name @depth = depth end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_local_variable_and_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableAndWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth) LocalVariableAndWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, name_loc: name_loc, operator_loc: operator_loc, value: value, name: name, depth: depth } end # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader name: Symbol attr_reader :name # attr_reader depth: Integer attr_reader :depth # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_and_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_and_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableAndWriteNode) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) && (name === other.name) && (depth === other.depth) end end # Represents assigning to a local variable using an operator that isn't `=`. # # target += value # ^^^^^^^^^^^^^^^ class LocalVariableOperatorWriteNode < Node # Initialize a new LocalVariableOperatorWriteNode node. def initialize(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth) @source = source @node_id = node_id @location = location @flags = flags @name_loc = name_loc @binary_operator_loc = binary_operator_loc @value = value @name = name @binary_operator = binary_operator @depth = depth 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, binary_operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?binary_operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?binary_operator: Symbol, ?depth: Integer) -> LocalVariableOperatorWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, binary_operator_loc: self.binary_operator_loc, value: self.value, name: self.name, binary_operator: self.binary_operator, depth: self.depth) LocalVariableOperatorWriteNode.new(source, node_id, location, flags, name_loc, binary_operator_loc, value, name, binary_operator, depth) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, binary_operator_loc: Location, value: Prism::node, name: Symbol, binary_operator: Symbol, depth: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, name_loc: name_loc, binary_operator_loc: binary_operator_loc, value: value, name: name, binary_operator: binary_operator, depth: depth } end # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader binary_operator_loc: Location def binary_operator_loc location = @binary_operator_loc return location if location.is_a?(Location) @binary_operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the binary_operator_loc location using the given saved source so that # it can be retrieved later. def save_binary_operator_loc(repository) repository.enter(node_id, :binary_operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader name: Symbol attr_reader :name # attr_reader binary_operator: Symbol attr_reader :binary_operator # attr_reader depth: Integer attr_reader :depth # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_operator_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_operator_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableOperatorWriteNode) && (name_loc.nil? == other.name_loc.nil?) && (binary_operator_loc.nil? == other.binary_operator_loc.nil?) && (value === other.value) && (name === other.name) && (binary_operator === other.binary_operator) && (depth === other.depth) end end # Represents the use of the `||=` operator for assignment to a local variable. # # target ||= value # ^^^^^^^^^^^^^^^^ class LocalVariableOrWriteNode < Node # Initialize a new LocalVariableOrWriteNode node. def initialize(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) @source = source @node_id = node_id @location = location @flags = flags @name_loc = name_loc @operator_loc = operator_loc @value = value @name = name @depth = depth end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_local_variable_or_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node, ?name: Symbol, ?depth: Integer) -> LocalVariableOrWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value, name: self.name, depth: self.depth) LocalVariableOrWriteNode.new(source, node_id, location, flags, name_loc, operator_loc, value, name, depth) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name_loc: Location, operator_loc: Location, value: Prism::node, name: Symbol, depth: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, name_loc: name_loc, operator_loc: operator_loc, value: value, name: name, depth: depth } end # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # attr_reader name: Symbol attr_reader :name # attr_reader depth: Integer attr_reader :depth # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_or_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_or_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableOrWriteNode) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) && (name === other.name) && (depth === other.depth) 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 # Initialize a new LocalVariableReadNode node. def initialize(source, node_id, location, flags, name, depth) @source = source @node_id = node_id @location = location @flags = flags @name = name @depth = depth 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth) LocalVariableReadNode.new(source, node_id, location, flags, name, depth) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, depth: depth } end # The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # x # name `:x` # # _Test # name `:_Test` # # Note that this can also be an underscore followed by a number for the default block parameters. # # _1 # name `:_1` attr_reader :name # The number of visible scopes that should be searched to find the origin of this local variable. # # foo = 1; foo # depth 0 # # bar = 2; tap { bar } # depth 1 # # The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). attr_reader :depth # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableReadNode) && (name === other.name) && (depth === other.depth) end end # Represents writing to a local variable in a context that doesn't have an explicit value. # # foo, bar = baz # ^^^ ^^^ class LocalVariableTargetNode < Node # Initialize a new LocalVariableTargetNode node. def initialize(source, node_id, location, flags, name, depth) @source = source @node_id = node_id @location = location @flags = flags @name = name @depth = depth end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_local_variable_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer) -> LocalVariableTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth) LocalVariableTargetNode.new(source, node_id, location, flags, name, depth) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, depth: depth } end # attr_reader name: Symbol attr_reader :name # attr_reader depth: Integer attr_reader :depth # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableTargetNode) && (name === other.name) && (depth === other.depth) end end # Represents writing to a local variable. # # foo = 1 # ^^^^^^^ class LocalVariableWriteNode < Node # Initialize a new LocalVariableWriteNode node. def initialize(source, node_id, location, flags, name, depth, name_loc, value, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @depth = depth @name_loc = name_loc @value = value @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?depth: Integer, ?name_loc: Location, ?value: Prism::node, ?operator_loc: Location) -> LocalVariableWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, depth: self.depth, name_loc: self.name_loc, value: self.value, operator_loc: self.operator_loc) LocalVariableWriteNode.new(source, node_id, location, flags, name, depth, name_loc, value, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, depth: Integer, name_loc: Location, value: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, depth: depth, name_loc: name_loc, value: value, operator_loc: operator_loc } end # The name of the local variable, which is an [identifier](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#identifiers). # # foo = :bar # name `:foo` # # abc = 123 # name `:abc` attr_reader :name # The number of semantic scopes we have to traverse to find the declaration of this variable. # # foo = 1 # depth 0 # # tap { foo = 1 } # depth 1 # # The specific rules for calculating the depth may differ from individual Ruby implementations, as they are not specified by the language. For more information, see [the Prism documentation](https://github.com/ruby/prism/blob/main/docs/local_variable_depth.md). attr_reader :depth # The location of the variable name. # # foo = :bar # ^^^ def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # The value to write to the local variable. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # foo = :bar # ^^^^ # # abc = 1234 # ^^^^ # # Note that since the name of a local variable is known before the value is parsed, it is valid for a local variable to appear within the value of its own write. # # foo = foo attr_reader :value # The location of the `=` operator. # # x = :y # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :local_variable_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :local_variable_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(LocalVariableWriteNode) && (name === other.name) && (depth === other.depth) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a regular expression literal used in the predicate of a conditional to implicitly match against the last line read by an IO object. # # if /foo/i then end # ^^^^^^ class MatchLastLineNode < Node # Initialize a new MatchLastLineNode node. def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_match_last_line_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> MatchLastLineNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) MatchLastLineNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } end # def ignore_case?: () -> bool def ignore_case? flags.anybits?(RegularExpressionFlags::IGNORE_CASE) end # def extended?: () -> bool def extended? flags.anybits?(RegularExpressionFlags::EXTENDED) end # def multi_line?: () -> bool def multi_line? flags.anybits?(RegularExpressionFlags::MULTI_LINE) end # def once?: () -> bool def once? flags.anybits?(RegularExpressionFlags::ONCE) end # def euc_jp?: () -> bool def euc_jp? flags.anybits?(RegularExpressionFlags::EUC_JP) end # def ascii_8bit?: () -> bool def ascii_8bit? flags.anybits?(RegularExpressionFlags::ASCII_8BIT) end # def windows_31j?: () -> bool def windows_31j? flags.anybits?(RegularExpressionFlags::WINDOWS_31J) end # def utf_8?: () -> bool def utf_8? flags.anybits?(RegularExpressionFlags::UTF_8) end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) end # def forced_us_ascii_encoding?: () -> bool def forced_us_ascii_encoding? flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader content_loc: Location def content_loc location = @content_loc return location if location.is_a?(Location) @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the content_loc location using the given saved source so that # it can be retrieved later. def save_content_loc(repository) repository.enter(node_id, :content_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader unescaped: String attr_reader :unescaped # def opening: () -> String def opening opening_loc.slice end # def content: () -> String def content content_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :match_last_line_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :match_last_line_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MatchLastLineNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (content_loc.nil? == other.content_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (unescaped === other.unescaped) end end # Represents the use of the modifier `in` operator. # # foo in bar # ^^^^^^^^^^ class MatchPredicateNode < Node # Initialize a new MatchPredicateNode node. def initialize(source, node_id, location, flags, value, pattern, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @value = value @pattern = pattern @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value, pattern] end # def comment_targets: () -> Array[Node | Location] def comment_targets [value, pattern, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchPredicateNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc) MatchPredicateNode.new(source, node_id, location, flags, value, pattern, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value, pattern: pattern, operator_loc: operator_loc } end # attr_reader value: Prism::node attr_reader :value # attr_reader pattern: Prism::node attr_reader :pattern # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :match_predicate_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :match_predicate_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MatchPredicateNode) && (value === other.value) && (pattern === other.pattern) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of the `=>` operator. # # foo => bar # ^^^^^^^^^^ class MatchRequiredNode < Node # Initialize a new MatchRequiredNode node. def initialize(source, node_id, location, flags, value, pattern, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @value = value @pattern = pattern @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value, pattern] end # def comment_targets: () -> Array[Node | Location] def comment_targets [value, pattern, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?value: Prism::node, ?pattern: Prism::node, ?operator_loc: Location) -> MatchRequiredNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, value: self.value, pattern: self.pattern, operator_loc: self.operator_loc) MatchRequiredNode.new(source, node_id, location, flags, value, pattern, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, value: Prism::node, pattern: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, value: value, pattern: pattern, operator_loc: operator_loc } end # attr_reader value: Prism::node attr_reader :value # attr_reader pattern: Prism::node attr_reader :pattern # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :match_required_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :match_required_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MatchRequiredNode) && (value === other.value) && (pattern === other.pattern) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents writing local variables using a regular expression match with named capture groups. # # /(?bar)/ =~ baz # ^^^^^^^^^^^^^^^^^^^^ class MatchWriteNode < Node # Initialize a new MatchWriteNode node. def initialize(source, node_id, location, flags, call, targets) @source = source @node_id = node_id @location = location @flags = flags @call = call @targets = targets end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_match_write_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [call, *targets] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [call, *targets] end # def comment_targets: () -> Array[Node | Location] def comment_targets [call, *targets] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?call: CallNode, ?targets: Array[LocalVariableTargetNode]) -> MatchWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, call: self.call, targets: self.targets) MatchWriteNode.new(source, node_id, location, flags, call, targets) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, call: CallNode, targets: Array[LocalVariableTargetNode] } def deconstruct_keys(keys) { node_id: node_id, location: location, call: call, targets: targets } end # attr_reader call: CallNode attr_reader :call # attr_reader targets: Array[LocalVariableTargetNode] attr_reader :targets # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :match_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :match_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MatchWriteNode) && (call === other.call) && (targets.length == other.targets.length) && targets.zip(other.targets).all? { |left, right| left === right } end end # Represents a node that is missing from the source and results in a syntax error. class MissingNode < Node # Initialize a new MissingNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> MissingNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) MissingNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :missing_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :missing_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MissingNode) end end # Represents a module declaration involving the `module` keyword. # # module Foo end # ^^^^^^^^^^^^^^ class ModuleNode < Node # Initialize a new ModuleNode node. def initialize(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @module_keyword_loc = module_keyword_loc @constant_path = constant_path @body = body @end_keyword_loc = end_keyword_loc @name = name 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << constant_path compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [module_keyword_loc, constant_path, *body, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?module_keyword_loc: Location, ?constant_path: ConstantReadNode | ConstantPathNode | MissingNode, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location, ?name: Symbol) -> ModuleNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, module_keyword_loc: self.module_keyword_loc, constant_path: self.constant_path, body: self.body, end_keyword_loc: self.end_keyword_loc, name: self.name) ModuleNode.new(source, node_id, location, flags, locals, module_keyword_loc, constant_path, body, end_keyword_loc, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], module_keyword_loc: Location, constant_path: ConstantReadNode | ConstantPathNode | MissingNode, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, module_keyword_loc: module_keyword_loc, constant_path: constant_path, body: body, end_keyword_loc: end_keyword_loc, name: name } end # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader module_keyword_loc: Location def module_keyword_loc location = @module_keyword_loc return location if location.is_a?(Location) @module_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the module_keyword_loc location using the given saved source so that # it can be retrieved later. def save_module_keyword_loc(repository) repository.enter(node_id, :module_keyword_loc) end # attr_reader constant_path: ConstantReadNode | ConstantPathNode | MissingNode attr_reader :constant_path # attr_reader body: StatementsNode | BeginNode | nil attr_reader :body # attr_reader end_keyword_loc: Location def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # attr_reader name: Symbol attr_reader :name # def module_keyword: () -> String def module_keyword module_keyword_loc.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :module_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :module_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ModuleNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (module_keyword_loc.nil? == other.module_keyword_loc.nil?) && (constant_path === other.constant_path) && (body === other.body) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) && (name === other.name) end end # Represents a multi-target expression. # # a, (b, c) = 1, 2, 3 # ^^^^^^ # # This can be a part of `MultiWriteNode` as above, or the target of a `for` loop # # for a, b in [[1, 2], [3, 4]] # ^^^^ class MultiTargetNode < Node # Initialize a new MultiTargetNode node. def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc) @source = source @node_id = node_id @location = location @flags = flags @lefts = lefts @rest = rest @rights = rights @lparen_loc = lparen_loc @rparen_loc = rparen_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_multi_target_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [*lefts, rest, *rights] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact.concat(lefts) compact << rest if rest compact.concat(rights) compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*lefts, *rest, *rights, *lparen_loc, *rparen_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?) -> MultiTargetNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc) MultiTargetNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | RequiredParameterNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc } end # Represents the targets expressions before a splat node. # # a, (b, c, *) = 1, 2, 3, 4, 5 # ^^^^ # # The splat node can be absent, in that case all target expressions are in the left field. # # a, (b, c) = 1, 2, 3, 4, 5 # ^^^^ attr_reader :lefts # Represents a splat node in the target expression. # # a, (b, *c) = 1, 2, 3, 4 # ^^ # # The variable can be empty, this results in a `SplatNode` with a `nil` expression field. # # a, (b, *) = 1, 2, 3, 4 # ^ # # If the `*` is omitted, this field will contain an `ImplicitRestNode` # # a, (b,) = 1, 2, 3, 4 # ^ attr_reader :rest # Represents the targets expressions after a splat node. # # a, (*, b, c) = 1, 2, 3, 4, 5 # ^^^^ attr_reader :rights # The location of the opening parenthesis. # # a, (b, c) = 1, 2, 3 # ^ def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # The location of the closing parenthesis. # # a, (b, c) = 1, 2, 3 # ^ def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :multi_target_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :multi_target_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MultiTargetNode) && (lefts.length == other.lefts.length) && lefts.zip(other.lefts).all? { |left, right| left === right } && (rest === other.rest) && (rights.length == other.rights.length) && rights.zip(other.rights).all? { |left, right| left === right } && (lparen_loc.nil? == other.lparen_loc.nil?) && (rparen_loc.nil? == other.rparen_loc.nil?) end end # Represents a write to a multi-target expression. # # a, b, c = 1, 2, 3 # ^^^^^^^^^^^^^^^^^ class MultiWriteNode < Node # Initialize a new MultiWriteNode node. def initialize(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @lefts = lefts @rest = rest @rights = rights @lparen_loc = lparen_loc @rparen_loc = rparen_loc @operator_loc = operator_loc @value = value 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 [*lefts, rest, *rights, value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact.concat(lefts) compact << rest if rest compact.concat(rights) compact << value compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*lefts, *rest, *rights, *lparen_loc, *rparen_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?rest: ImplicitRestNode | SplatNode | nil, ?rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], ?lparen_loc: Location?, ?rparen_loc: Location?, ?operator_loc: Location, ?value: Prism::node) -> MultiWriteNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, lefts: self.lefts, rest: self.rest, rights: self.rights, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc, operator_loc: self.operator_loc, value: self.value) MultiWriteNode.new(source, node_id, location, flags, lefts, rest, rights, lparen_loc, rparen_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, lefts: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], rest: ImplicitRestNode | SplatNode | nil, rights: Array[LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | MultiTargetNode | BackReferenceReadNode | NumberedReferenceReadNode], lparen_loc: Location?, rparen_loc: Location?, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, lefts: lefts, rest: rest, rights: rights, lparen_loc: lparen_loc, rparen_loc: rparen_loc, operator_loc: operator_loc, value: value } end # Represents the targets expressions before a splat node. # # a, b, * = 1, 2, 3, 4, 5 # ^^^^ # # The splat node can be absent, in that case all target expressions are in the left field. # # a, b, c = 1, 2, 3, 4, 5 # ^^^^^^^ attr_reader :lefts # Represents a splat node in the target expression. # # a, b, *c = 1, 2, 3, 4 # ^^ # # The variable can be empty, this results in a `SplatNode` with a `nil` expression field. # # a, b, * = 1, 2, 3, 4 # ^ # # If the `*` is omitted, this field will contain an `ImplicitRestNode` # # a, b, = 1, 2, 3, 4 # ^ attr_reader :rest # Represents the targets expressions after a splat node. # # a, *, b, c = 1, 2, 3, 4, 5 # ^^^^ attr_reader :rights # The location of the opening parenthesis. # # (a, b, c) = 1, 2, 3 # ^ def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # The location of the closing parenthesis. # # (a, b, c) = 1, 2, 3 # ^ def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # The location of the operator. # # a, b, c = 1, 2, 3 # ^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # The value to write to the targets. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # a, b, c = 1, 2, 3 # ^^^^^^^ attr_reader :value # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :multi_write_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :multi_write_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(MultiWriteNode) && (lefts.length == other.lefts.length) && lefts.zip(other.lefts).all? { |left, right| left === right } && (rest === other.rest) && (rights.length == other.rights.length) && rights.zip(other.rights).all? { |left, right| left === right } && (lparen_loc.nil? == other.lparen_loc.nil?) && (rparen_loc.nil? == other.rparen_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents the use of the `next` keyword. # # next 1 # ^^^^^^ class NextNode < Node # Initialize a new NextNode node. def initialize(source, node_id, location, flags, arguments, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @arguments = arguments @keyword_loc = keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << arguments if arguments compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*arguments, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?arguments: ArgumentsNode?, ?keyword_loc: Location) -> NextNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, arguments: self.arguments, keyword_loc: self.keyword_loc) NextNode.new(source, node_id, location, flags, arguments, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, arguments: ArgumentsNode?, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, arguments: arguments, keyword_loc: keyword_loc } end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :next_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :next_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(NextNode) && (arguments === other.arguments) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents the use of the `nil` keyword. # # nil # ^^^ class NilNode < Node # Initialize a new NilNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> NilNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) NilNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :nil_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :nil_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(NilNode) end end # Represents the use of `**nil` inside method arguments. # # def a(**nil) # ^^^^^ # end class NoKeywordsParameterNode < Node # Initialize a new NoKeywordsParameterNode node. def initialize(source, node_id, location, flags, operator_loc, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @operator_loc = operator_loc @keyword_loc = keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [operator_loc, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?keyword_loc: Location) -> NoKeywordsParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, keyword_loc: self.keyword_loc) NoKeywordsParameterNode.new(source, node_id, location, flags, operator_loc, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, operator_loc: operator_loc, keyword_loc: keyword_loc } end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def operator: () -> String def operator operator_loc.slice end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :no_keywords_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :no_keywords_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(NoKeywordsParameterNode) && (operator_loc.nil? == other.operator_loc.nil?) && (keyword_loc.nil? == other.keyword_loc.nil?) end end # Represents an implicit set of parameters through the use of numbered parameters within a block or lambda. # # -> { _1 + _2 } # ^^^^^^^^^^^^^^ class NumberedParametersNode < Node # Initialize a new NumberedParametersNode node. def initialize(source, node_id, location, flags, maximum) @source = source @node_id = node_id @location = location @flags = flags @maximum = maximum end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_numbered_parameters_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?maximum: Integer) -> NumberedParametersNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, maximum: self.maximum) NumberedParametersNode.new(source, node_id, location, flags, maximum) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, maximum: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, maximum: maximum } end # attr_reader maximum: Integer attr_reader :maximum # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :numbered_parameters_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :numbered_parameters_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(NumberedParametersNode) && (maximum === other.maximum) end end # Represents reading a numbered reference to a capture in the previous match. # # $1 # ^^ class NumberedReferenceReadNode < Node # Initialize a new NumberedReferenceReadNode node. def initialize(source, node_id, location, flags, number) @source = source @node_id = node_id @location = location @flags = flags @number = number 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?number: Integer) -> NumberedReferenceReadNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, number: self.number) NumberedReferenceReadNode.new(source, node_id, location, flags, number) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, number: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, number: number } end # The (1-indexed, from the left) number of the capture group. Numbered references that are too large result in this value being `0`. # # $1 # number `1` # # $5432 # number `5432` # # $4294967296 # number `0` attr_reader :number # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :numbered_reference_read_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :numbered_reference_read_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(NumberedReferenceReadNode) && (number === other.number) end end # Represents an optional keyword parameter to a method, block, or lambda definition. # # def a(b: 1) # ^^^^ # end class OptionalKeywordParameterNode < Node # Initialize a new OptionalKeywordParameterNode node. def initialize(source, node_id, location, flags, name, name_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @value = value end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_optional_keyword_parameter_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [value] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?value: Prism::node) -> OptionalKeywordParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, value: self.value) OptionalKeywordParameterNode.new(source, node_id, location, flags, name, name_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, value: value } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader value: Prism::node attr_reader :value # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :optional_keyword_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :optional_keyword_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(OptionalKeywordParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (value === other.value) end end # Represents an optional parameter to a method, block, or lambda definition. # # def a(b = 1) # ^^^^^ # end class OptionalParameterNode < Node # Initialize a new OptionalParameterNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc, value) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc @value = value 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [value] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc, operator_loc, value] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location, ?operator_loc: Location, ?value: Prism::node) -> OptionalParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc, value: self.value) OptionalParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc, value) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location, operator_loc: Location, value: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc, value: value } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader value: Prism::node attr_reader :value # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :optional_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :optional_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(OptionalParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (value === other.value) end end # Represents the use of the `||` operator or the `or` keyword. # # left or right # ^^^^^^^^^^^^^ class OrNode < Node # Initialize a new OrNode node. def initialize(source, node_id, location, flags, left, right, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @left = left @right = right @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [left, right] end # def comment_targets: () -> Array[Node | Location] def comment_targets [left, right, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node, ?right: Prism::node, ?operator_loc: Location) -> OrNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) OrNode.new(source, node_id, location, flags, left, right, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node, right: Prism::node, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } end # Represents the left side of the expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # left or right # ^^^^ # # 1 || 2 # ^ attr_reader :left # Represents the right side of the expression. # # left || right # ^^^^^ # # 1 or 2 # ^ attr_reader :right # The location of the `or` keyword or the `||` operator. # # left or right # ^^ def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :or_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :or_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(OrNode) && (left === other.left) && (right === other.right) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the list of parameters on a method, block, or lambda definition. # # def a(b, c, d) # ^^^^^^^ # end class ParametersNode < Node # Initialize a new ParametersNode node. def initialize(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block) @source = source @node_id = node_id @location = location @flags = flags @requireds = requireds @optionals = optionals @rest = rest @posts = posts @keywords = keywords @keyword_rest = keyword_rest @block = block 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, rest, *posts, *keywords, keyword_rest, block] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact.concat(requireds) compact.concat(optionals) compact << rest if rest compact.concat(posts) compact.concat(keywords) compact << keyword_rest if keyword_rest compact << block if block compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*requireds, *optionals, *rest, *posts, *keywords, *keyword_rest, *block] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?requireds: Array[RequiredParameterNode | MultiTargetNode], ?optionals: Array[OptionalParameterNode], ?rest: RestParameterNode | ImplicitRestNode | nil, ?posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], ?keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], ?keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, ?block: BlockParameterNode?) -> ParametersNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, requireds: self.requireds, optionals: self.optionals, rest: self.rest, posts: self.posts, keywords: self.keywords, keyword_rest: self.keyword_rest, block: self.block) ParametersNode.new(source, node_id, location, flags, requireds, optionals, rest, posts, keywords, keyword_rest, block) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, requireds: Array[RequiredParameterNode | MultiTargetNode], optionals: Array[OptionalParameterNode], rest: RestParameterNode | ImplicitRestNode | nil, posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode], keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode], keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil, block: BlockParameterNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, requireds: requireds, optionals: optionals, rest: rest, posts: posts, keywords: keywords, keyword_rest: keyword_rest, block: block } end # attr_reader requireds: Array[RequiredParameterNode | MultiTargetNode] attr_reader :requireds # attr_reader optionals: Array[OptionalParameterNode] attr_reader :optionals # attr_reader rest: RestParameterNode | ImplicitRestNode | nil attr_reader :rest # attr_reader posts: Array[RequiredParameterNode | MultiTargetNode | KeywordRestParameterNode | NoKeywordsParameterNode | ForwardingParameterNode] attr_reader :posts # attr_reader keywords: Array[RequiredKeywordParameterNode | OptionalKeywordParameterNode] attr_reader :keywords # attr_reader keyword_rest: KeywordRestParameterNode | ForwardingParameterNode | NoKeywordsParameterNode | nil attr_reader :keyword_rest # attr_reader block: BlockParameterNode? attr_reader :block # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :parameters_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :parameters_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ParametersNode) && (requireds.length == other.requireds.length) && requireds.zip(other.requireds).all? { |left, right| left === right } && (optionals.length == other.optionals.length) && optionals.zip(other.optionals).all? { |left, right| left === right } && (rest === other.rest) && (posts.length == other.posts.length) && posts.zip(other.posts).all? { |left, right| left === right } && (keywords.length == other.keywords.length) && keywords.zip(other.keywords).all? { |left, right| left === right } && (keyword_rest === other.keyword_rest) && (block === other.block) end end # Represents a parenthesized expression # # (10 + 34) # ^^^^^^^^^ class ParenthesesNode < Node # Initialize a new ParenthesesNode node. def initialize(source, node_id, location, flags, body, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @body = body @opening_loc = opening_loc @closing_loc = closing_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_parentheses_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*body, opening_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Prism::node?, ?opening_loc: Location, ?closing_loc: Location) -> ParenthesesNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body, opening_loc: self.opening_loc, closing_loc: self.closing_loc) ParenthesesNode.new(source, node_id, location, flags, body, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Prism::node?, opening_loc: Location, closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, body: body, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader body: Prism::node? attr_reader :body # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :parentheses_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :parentheses_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ParenthesesNode) && (body === other.body) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents the use of the `^` operator for pinning an expression in a pattern matching expression. # # foo in ^(bar) # ^^^^^^ class PinnedExpressionNode < Node # Initialize a new PinnedExpressionNode node. def initialize(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc) @source = source @node_id = node_id @location = location @flags = flags @expression = expression @operator_loc = operator_loc @lparen_loc = lparen_loc @rparen_loc = rparen_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [expression] end # def comment_targets: () -> Array[Node | Location] def comment_targets [expression, operator_loc, lparen_loc, rparen_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?operator_loc: Location, ?lparen_loc: Location, ?rparen_loc: Location) -> PinnedExpressionNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, operator_loc: self.operator_loc, lparen_loc: self.lparen_loc, rparen_loc: self.rparen_loc) PinnedExpressionNode.new(source, node_id, location, flags, expression, operator_loc, lparen_loc, rparen_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, expression: expression, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc } end # attr_reader expression: Prism::node attr_reader :expression # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader lparen_loc: Location def lparen_loc location = @lparen_loc return location if location.is_a?(Location) @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) end # attr_reader rparen_loc: Location def rparen_loc location = @rparen_loc return location if location.is_a?(Location) @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) end # def operator: () -> String def operator operator_loc.slice end # def lparen: () -> String def lparen lparen_loc.slice end # def rparen: () -> String def rparen rparen_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :pinned_expression_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :pinned_expression_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(PinnedExpressionNode) && (expression === other.expression) && (operator_loc.nil? == other.operator_loc.nil?) && (lparen_loc.nil? == other.lparen_loc.nil?) && (rparen_loc.nil? == other.rparen_loc.nil?) end end # Represents the use of the `^` operator for pinning a variable in a pattern matching expression. # # foo in ^bar # ^^^^ class PinnedVariableNode < Node # Initialize a new PinnedVariableNode node. def initialize(source, node_id, location, flags, variable, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @variable = variable @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [variable] end # def comment_targets: () -> Array[Node | Location] def comment_targets [variable, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, ?operator_loc: Location) -> PinnedVariableNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, variable: self.variable, operator_loc: self.operator_loc) PinnedVariableNode.new(source, node_id, location, flags, variable, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, variable: variable, operator_loc: operator_loc } end # attr_reader variable: LocalVariableReadNode | InstanceVariableReadNode | ClassVariableReadNode | GlobalVariableReadNode | BackReferenceReadNode | NumberedReferenceReadNode | ItLocalVariableReadNode | MissingNode attr_reader :variable # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :pinned_variable_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :pinned_variable_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(PinnedVariableNode) && (variable === other.variable) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of the `END` keyword. # # END { foo } # ^^^^^^^^^^^ class PostExecutionNode < Node # Initialize a new PostExecutionNode node. def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @statements = statements @keyword_loc = keyword_loc @opening_loc = opening_loc @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*statements, keyword_loc, opening_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PostExecutionNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc) PostExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :post_execution_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :post_execution_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(PostExecutionNode) && (statements === other.statements) && (keyword_loc.nil? == other.keyword_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # Represents the use of the `BEGIN` keyword. # # BEGIN { foo } # ^^^^^^^^^^^^^ class PreExecutionNode < Node # Initialize a new PreExecutionNode node. def initialize(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) @source = source @node_id = node_id @location = location @flags = flags @statements = statements @keyword_loc = keyword_loc @opening_loc = opening_loc @closing_loc = closing_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*statements, keyword_loc, opening_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?statements: StatementsNode?, ?keyword_loc: Location, ?opening_loc: Location, ?closing_loc: Location) -> PreExecutionNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, statements: self.statements, keyword_loc: self.keyword_loc, opening_loc: self.opening_loc, closing_loc: self.closing_loc) PreExecutionNode.new(source, node_id, location, flags, statements, keyword_loc, opening_loc, closing_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, statements: StatementsNode?, keyword_loc: Location, opening_loc: Location, closing_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc } end # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def opening: () -> String def opening opening_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :pre_execution_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :pre_execution_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(PreExecutionNode) && (statements === other.statements) && (keyword_loc.nil? == other.keyword_loc.nil?) && (opening_loc.nil? == other.opening_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) end end # The top level node of any parse tree. class ProgramNode < Node # Initialize a new ProgramNode node. def initialize(source, node_id, location, flags, locals, statements) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @statements = statements 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [statements] end # def comment_targets: () -> Array[Node | Location] def comment_targets [statements] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?statements: StatementsNode) -> ProgramNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, statements: self.statements) ProgramNode.new(source, node_id, location, flags, locals, statements) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], statements: StatementsNode } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, statements: statements } end # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader statements: StatementsNode attr_reader :statements # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :program_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :program_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ProgramNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (statements === other.statements) end end # Represents the use of the `..` or `...` operators. # # 1..2 # ^^^^ # # c if a =~ /left/ ... b =~ /right/ # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ class RangeNode < Node # Initialize a new RangeNode node. def initialize(source, node_id, location, flags, left, right, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @left = left @right = right @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << left if left compact << right if right compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [*left, *right, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?left: Prism::node?, ?right: Prism::node?, ?operator_loc: Location) -> RangeNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, left: self.left, right: self.right, operator_loc: self.operator_loc) RangeNode.new(source, node_id, location, flags, left, right, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, left: Prism::node?, right: Prism::node?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, left: left, right: right, operator_loc: operator_loc } end # def exclude_end?: () -> bool def exclude_end? flags.anybits?(RangeFlags::EXCLUDE_END) end # The left-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # 1... # ^ # # hello...goodbye # ^^^^^ attr_reader :left # The right-hand side of the range, if present. It can be either `nil` or any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # ..5 # ^ # # 1...foo # ^^^ # If neither right-hand or left-hand side was included, this will be a MissingNode. attr_reader :right # The location of the `..` or `...` operator. def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :range_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :range_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RangeNode) && (flags === other.flags) && (left === other.left) && (right === other.right) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents a rational number literal. # # 1.0r # ^^^^ class RationalNode < Node # Initialize a new RationalNode node. def initialize(source, node_id, location, flags, numerator, denominator) @source = source @node_id = node_id @location = location @flags = flags @numerator = numerator @denominator = denominator end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_rational_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?numerator: Integer, ?denominator: Integer) -> RationalNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, numerator: self.numerator, denominator: self.denominator) RationalNode.new(source, node_id, location, flags, numerator, denominator) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, numerator: Integer, denominator: Integer } def deconstruct_keys(keys) { node_id: node_id, location: location, numerator: numerator, denominator: denominator } end # def binary?: () -> bool def binary? flags.anybits?(IntegerBaseFlags::BINARY) end # def decimal?: () -> bool def decimal? flags.anybits?(IntegerBaseFlags::DECIMAL) end # def octal?: () -> bool def octal? flags.anybits?(IntegerBaseFlags::OCTAL) end # def hexadecimal?: () -> bool def hexadecimal? flags.anybits?(IntegerBaseFlags::HEXADECIMAL) end # The numerator of the rational number. # # 1.5r # numerator 3 attr_reader :numerator # The denominator of the rational number. # # 1.5r # denominator 2 attr_reader :denominator # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :rational_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :rational_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RationalNode) && (flags === other.flags) && (numerator === other.numerator) && (denominator === other.denominator) end end # Represents the use of the `redo` keyword. # # redo # ^^^^ class RedoNode < Node # Initialize a new RedoNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RedoNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) RedoNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :redo_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :redo_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RedoNode) end end # Represents a regular expression literal with no interpolation. # # /foo/i # ^^^^^^ class RegularExpressionNode < Node # Initialize a new RegularExpressionNode node. def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> RegularExpressionNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) RegularExpressionNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } end # def ignore_case?: () -> bool def ignore_case? flags.anybits?(RegularExpressionFlags::IGNORE_CASE) end # def extended?: () -> bool def extended? flags.anybits?(RegularExpressionFlags::EXTENDED) end # def multi_line?: () -> bool def multi_line? flags.anybits?(RegularExpressionFlags::MULTI_LINE) end # def once?: () -> bool def once? flags.anybits?(RegularExpressionFlags::ONCE) end # def euc_jp?: () -> bool def euc_jp? flags.anybits?(RegularExpressionFlags::EUC_JP) end # def ascii_8bit?: () -> bool def ascii_8bit? flags.anybits?(RegularExpressionFlags::ASCII_8BIT) end # def windows_31j?: () -> bool def windows_31j? flags.anybits?(RegularExpressionFlags::WINDOWS_31J) end # def utf_8?: () -> bool def utf_8? flags.anybits?(RegularExpressionFlags::UTF_8) end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(RegularExpressionFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(RegularExpressionFlags::FORCED_BINARY_ENCODING) end # def forced_us_ascii_encoding?: () -> bool def forced_us_ascii_encoding? flags.anybits?(RegularExpressionFlags::FORCED_US_ASCII_ENCODING) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader content_loc: Location def content_loc location = @content_loc return location if location.is_a?(Location) @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the content_loc location using the given saved source so that # it can be retrieved later. def save_content_loc(repository) repository.enter(node_id, :content_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader unescaped: String attr_reader :unescaped # def opening: () -> String def opening opening_loc.slice end # def content: () -> String def content content_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :regular_expression_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :regular_expression_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RegularExpressionNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (content_loc.nil? == other.content_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (unescaped === other.unescaped) end end # Represents a required keyword parameter to a method, block, or lambda definition. # # def a(b: ) # ^^ # end class RequiredKeywordParameterNode < Node # Initialize a new RequiredKeywordParameterNode node. def initialize(source, node_id, location, flags, name, name_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_required_keyword_parameter_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [name_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol, ?name_loc: Location) -> RequiredKeywordParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc) RequiredKeywordParameterNode.new(source, node_id, location, flags, name, name_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol, name_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol attr_reader :name # attr_reader name_loc: Location def name_loc location = @name_loc return location if location.is_a?(Location) @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :required_keyword_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :required_keyword_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RequiredKeywordParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) end end # Represents a required parameter to a method, block, or lambda definition. # # def a(b) # ^ # end class RequiredParameterNode < Node # Initialize a new RequiredParameterNode node. def initialize(source, node_id, location, flags, name) @source = source @node_id = node_id @location = location @flags = flags @name = name 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol) -> RequiredParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name) RequiredParameterNode.new(source, node_id, location, flags, name) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol attr_reader :name # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :required_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :required_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RequiredParameterNode) && (flags === other.flags) && (name === other.name) end end # Represents an expression modified with a rescue. # # foo rescue nil # ^^^^^^^^^^^^^^ class RescueModifierNode < Node # Initialize a new RescueModifierNode node. def initialize(source, node_id, location, flags, expression, keyword_loc, rescue_expression) @source = source @node_id = node_id @location = location @flags = flags @expression = expression @keyword_loc = keyword_loc @rescue_expression = rescue_expression 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [expression, rescue_expression] end # def comment_targets: () -> Array[Node | Location] def comment_targets [expression, keyword_loc, rescue_expression] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?expression: Prism::node, ?keyword_loc: Location, ?rescue_expression: Prism::node) -> RescueModifierNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, expression: self.expression, keyword_loc: self.keyword_loc, rescue_expression: self.rescue_expression) RescueModifierNode.new(source, node_id, location, flags, expression, keyword_loc, rescue_expression) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, expression: Prism::node, keyword_loc: Location, rescue_expression: Prism::node } def deconstruct_keys(keys) { node_id: node_id, location: location, expression: expression, keyword_loc: keyword_loc, rescue_expression: rescue_expression } end # attr_reader expression: Prism::node attr_reader :expression # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader rescue_expression: Prism::node attr_reader :rescue_expression # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :rescue_modifier_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :rescue_modifier_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RescueModifierNode) && (expression === other.expression) && (keyword_loc.nil? == other.keyword_loc.nil?) && (rescue_expression === other.rescue_expression) end end # Represents a rescue statement. # # begin # rescue Foo, *splat, Bar => ex # foo # ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ # end # # `Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `reference` field. class RescueNode < Node # Initialize a new RescueNode node. def initialize(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, statements, subsequent) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @exceptions = exceptions @operator_loc = operator_loc @reference = reference @statements = statements @subsequent = subsequent 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, reference, statements, subsequent] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact.concat(exceptions) compact << reference if reference compact << statements if statements compact << subsequent if subsequent compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *exceptions, *operator_loc, *reference, *statements, *subsequent] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?exceptions: Array[Prism::node], ?operator_loc: Location?, ?reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, ?statements: StatementsNode?, ?subsequent: RescueNode?) -> RescueNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, exceptions: self.exceptions, operator_loc: self.operator_loc, reference: self.reference, statements: self.statements, subsequent: self.subsequent) RescueNode.new(source, node_id, location, flags, keyword_loc, exceptions, operator_loc, reference, statements, subsequent) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, exceptions: Array[Prism::node], operator_loc: Location?, reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil, statements: StatementsNode?, subsequent: RescueNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, reference: reference, statements: statements, subsequent: subsequent } end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader exceptions: Array[Prism::node] attr_reader :exceptions # attr_reader operator_loc: Location? def operator_loc location = @operator_loc case location when nil nil when Location location else @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) unless @operator_loc.nil? end # attr_reader reference: LocalVariableTargetNode | InstanceVariableTargetNode | ClassVariableTargetNode | GlobalVariableTargetNode | ConstantTargetNode | ConstantPathTargetNode | CallTargetNode | IndexTargetNode | BackReferenceReadNode | NumberedReferenceReadNode | MissingNode | nil attr_reader :reference # attr_reader statements: StatementsNode? attr_reader :statements # attr_reader subsequent: RescueNode? attr_reader :subsequent # def keyword: () -> String def keyword keyword_loc.slice end # def operator: () -> String? def operator operator_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :rescue_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :rescue_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RescueNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (exceptions.length == other.exceptions.length) && exceptions.zip(other.exceptions).all? { |left, right| left === right } && (operator_loc.nil? == other.operator_loc.nil?) && (reference === other.reference) && (statements === other.statements) && (subsequent === other.subsequent) end end # Represents a rest parameter to a method, block, or lambda definition. # # def a(*b) # ^^ # end class RestParameterNode < Node # Initialize a new RestParameterNode node. def initialize(source, node_id, location, flags, name, name_loc, operator_loc) @source = source @node_id = node_id @location = location @flags = flags @name = name @name_loc = name_loc @operator_loc = operator_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*name_loc, operator_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?name: Symbol?, ?name_loc: Location?, ?operator_loc: Location) -> RestParameterNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, name: self.name, name_loc: self.name_loc, operator_loc: self.operator_loc) RestParameterNode.new(source, node_id, location, flags, name, name_loc, operator_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, name: Symbol?, name_loc: Location?, operator_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, name: name, name_loc: name_loc, operator_loc: operator_loc } end # def repeated_parameter?: () -> bool def repeated_parameter? flags.anybits?(ParameterFlags::REPEATED_PARAMETER) end # attr_reader name: Symbol? attr_reader :name # attr_reader name_loc: Location? def name_loc location = @name_loc case location when nil nil when Location location else @name_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the name_loc location using the given saved source so that # it can be retrieved later. def save_name_loc(repository) repository.enter(node_id, :name_loc) unless @name_loc.nil? end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :rest_parameter_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :rest_parameter_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RestParameterNode) && (flags === other.flags) && (name === other.name) && (name_loc.nil? == other.name_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) end end # Represents the use of the `retry` keyword. # # retry # ^^^^^ class RetryNode < Node # Initialize a new RetryNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> RetryNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) RetryNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :retry_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :retry_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(RetryNode) end end # Represents the use of the `return` keyword. # # return 1 # ^^^^^^^^ class ReturnNode < Node # Initialize a new ReturnNode node. def initialize(source, node_id, location, flags, keyword_loc, arguments) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @arguments = arguments 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << arguments if arguments compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *arguments] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?arguments: ArgumentsNode?) -> ReturnNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, arguments: self.arguments) ReturnNode.new(source, node_id, location, flags, keyword_loc, arguments) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, arguments: ArgumentsNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, arguments: arguments } end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :return_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :return_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ReturnNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (arguments === other.arguments) end end # Represents the `self` keyword. # # self # ^^^^ class SelfNode < Node # Initialize a new SelfNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SelfNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) SelfNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :self_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :self_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SelfNode) end end # This node wraps a constant write to indicate that when the value is written, it should have its shareability state modified. # # # shareable_constant_value: literal # C = { a: 1 } # ^^^^^^^^^^^^ class ShareableConstantNode < Node # Initialize a new ShareableConstantNode node. def initialize(source, node_id, location, flags, write) @source = source @node_id = node_id @location = location @flags = flags @write = write end # def accept: (Visitor visitor) -> void def accept(visitor) visitor.visit_shareable_constant_node(self) end # def child_nodes: () -> Array[nil | Node] def child_nodes [write] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes [write] end # def comment_targets: () -> Array[Node | Location] def comment_targets [write] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode) -> ShareableConstantNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, write: self.write) ShareableConstantNode.new(source, node_id, location, flags, write) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, write: ConstantWriteNode | ConstantAndWriteNode | ConstantOrWriteNode | ConstantOperatorWriteNode | ConstantPathWriteNode | ConstantPathAndWriteNode | ConstantPathOrWriteNode | ConstantPathOperatorWriteNode } def deconstruct_keys(keys) { node_id: node_id, location: location, write: write } end # def literal?: () -> bool def literal? flags.anybits?(ShareableConstantNodeFlags::LITERAL) end # def experimental_everything?: () -> bool def experimental_everything? flags.anybits?(ShareableConstantNodeFlags::EXPERIMENTAL_EVERYTHING) end # def experimental_copy?: () -> bool def experimental_copy? flags.anybits?(ShareableConstantNodeFlags::EXPERIMENTAL_COPY) end # The constant write that should be modified with the shareability state. attr_reader :write # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :shareable_constant_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :shareable_constant_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(ShareableConstantNode) && (flags === other.flags) && (write === other.write) end end # Represents a singleton class declaration involving the `class` keyword. # # class << self end # ^^^^^^^^^^^^^^^^^ class SingletonClassNode < Node # Initialize a new SingletonClassNode node. def initialize(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @locals = locals @class_keyword_loc = class_keyword_loc @operator_loc = operator_loc @expression = expression @body = body @end_keyword_loc = end_keyword_loc 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, body] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << expression compact << body if body compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [class_keyword_loc, operator_loc, expression, *body, end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?locals: Array[Symbol], ?class_keyword_loc: Location, ?operator_loc: Location, ?expression: Prism::node, ?body: StatementsNode | BeginNode | nil, ?end_keyword_loc: Location) -> SingletonClassNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, locals: self.locals, class_keyword_loc: self.class_keyword_loc, operator_loc: self.operator_loc, expression: self.expression, body: self.body, end_keyword_loc: self.end_keyword_loc) SingletonClassNode.new(source, node_id, location, flags, locals, class_keyword_loc, operator_loc, expression, body, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Prism::node, body: StatementsNode | BeginNode | nil, end_keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, locals: locals, class_keyword_loc: class_keyword_loc, operator_loc: operator_loc, expression: expression, body: body, end_keyword_loc: end_keyword_loc } end # attr_reader locals: Array[Symbol] attr_reader :locals # attr_reader class_keyword_loc: Location def class_keyword_loc location = @class_keyword_loc return location if location.is_a?(Location) @class_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the class_keyword_loc location using the given saved source so that # it can be retrieved later. def save_class_keyword_loc(repository) repository.enter(node_id, :class_keyword_loc) end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader expression: Prism::node attr_reader :expression # attr_reader body: StatementsNode | BeginNode | nil attr_reader :body # attr_reader end_keyword_loc: Location def end_keyword_loc location = @end_keyword_loc return location if location.is_a?(Location) @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) end # def class_keyword: () -> String def class_keyword class_keyword_loc.slice end # def operator: () -> String def operator operator_loc.slice end # def end_keyword: () -> String def end_keyword end_keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :singleton_class_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :singleton_class_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SingletonClassNode) && (locals.length == other.locals.length) && locals.zip(other.locals).all? { |left, right| left === right } && (class_keyword_loc.nil? == other.class_keyword_loc.nil?) && (operator_loc.nil? == other.operator_loc.nil?) && (expression === other.expression) && (body === other.body) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) end end # Represents the use of the `__ENCODING__` keyword. # # __ENCODING__ # ^^^^^^^^^^^^ class SourceEncodingNode < Node # Initialize a new SourceEncodingNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceEncodingNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) SourceEncodingNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :source_encoding_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :source_encoding_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SourceEncodingNode) end end # Represents the use of the `__FILE__` keyword. # # __FILE__ # ^^^^^^^^ class SourceFileNode < Node # Initialize a new SourceFileNode node. def initialize(source, node_id, location, flags, filepath) @source = source @node_id = node_id @location = location @flags = flags @filepath = filepath 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?filepath: String) -> SourceFileNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, filepath: self.filepath) SourceFileNode.new(source, node_id, location, flags, filepath) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, filepath: String } def deconstruct_keys(keys) { node_id: node_id, location: location, filepath: filepath } end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(StringFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(StringFlags::FORCED_BINARY_ENCODING) end # def frozen?: () -> bool def frozen? flags.anybits?(StringFlags::FROZEN) end # def mutable?: () -> bool def mutable? flags.anybits?(StringFlags::MUTABLE) end # Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs. attr_reader :filepath # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :source_file_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :source_file_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SourceFileNode) && (flags === other.flags) && (filepath === other.filepath) end end # Represents the use of the `__LINE__` keyword. # # __LINE__ # ^^^^^^^^ class SourceLineNode < Node # Initialize a new SourceLineNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> SourceLineNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) SourceLineNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :source_line_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :source_line_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SourceLineNode) end end # Represents the use of the splat operator. # # [*a] # ^^ class SplatNode < Node # Initialize a new SplatNode node. def initialize(source, node_id, location, flags, operator_loc, expression) @source = source @node_id = node_id @location = location @flags = flags @operator_loc = operator_loc @expression = expression 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << expression if expression compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [operator_loc, *expression] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?operator_loc: Location, ?expression: Prism::node?) -> SplatNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, operator_loc: self.operator_loc, expression: self.expression) SplatNode.new(source, node_id, location, flags, operator_loc, expression) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, operator_loc: Location, expression: Prism::node? } def deconstruct_keys(keys) { node_id: node_id, location: location, operator_loc: operator_loc, expression: expression } end # attr_reader operator_loc: Location def operator_loc location = @operator_loc return location if location.is_a?(Location) @operator_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the operator_loc location using the given saved source so that # it can be retrieved later. def save_operator_loc(repository) repository.enter(node_id, :operator_loc) end # attr_reader expression: Prism::node? attr_reader :expression # def operator: () -> String def operator operator_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :splat_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :splat_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SplatNode) && (operator_loc.nil? == other.operator_loc.nil?) && (expression === other.expression) end end # Represents a set of statements contained within some scope. # # foo; bar; baz # ^^^^^^^^^^^^^ class StatementsNode < Node # Initialize a new StatementsNode node. def initialize(source, node_id, location, flags, body) @source = source @node_id = node_id @location = location @flags = flags @body = body 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*body] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*body] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?body: Array[Prism::node]) -> StatementsNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, body: self.body) StatementsNode.new(source, node_id, location, flags, body) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, body: Array[Prism::node] } def deconstruct_keys(keys) { node_id: node_id, location: location, body: body } end # attr_reader body: Array[Prism::node] attr_reader :body # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :statements_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :statements_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(StatementsNode) && (body.length == other.body.length) && body.zip(other.body).all? { |left, right| left === right } 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 # Initialize a new StringNode node. def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*opening_loc, content_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?content_loc: Location, ?closing_loc: Location?, ?unescaped: String) -> StringNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) StringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(StringFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(StringFlags::FORCED_BINARY_ENCODING) end # def frozen?: () -> bool def frozen? flags.anybits?(StringFlags::FROZEN) end # def mutable?: () -> bool def mutable? flags.anybits?(StringFlags::MUTABLE) end # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader content_loc: Location def content_loc location = @content_loc return location if location.is_a?(Location) @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the content_loc location using the given saved source so that # it can be retrieved later. def save_content_loc(repository) repository.enter(node_id, :content_loc) end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # attr_reader unescaped: String attr_reader :unescaped # def opening: () -> String? def opening opening_loc&.slice end # def content: () -> String def content content_loc.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :string_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :string_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(StringNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (content_loc.nil? == other.content_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (unescaped === other.unescaped) end end # Represents the use of the `super` keyword with parentheses or arguments. # # super() # ^^^^^^^ # # super foo, bar # ^^^^^^^^^^^^^^ class SuperNode < Node # Initialize a new SuperNode node. def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @lparen_loc = lparen_loc @arguments = arguments @rparen_loc = rparen_loc @block = block 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << arguments if arguments compact << block if block compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *lparen_loc, *arguments, *rparen_loc, *block] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?, ?block: BlockNode | BlockArgumentNode | nil) -> SuperNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc, block: self.block) SuperNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc, block) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location?, block: BlockNode | BlockArgumentNode | nil } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, block: block } end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader lparen_loc: Location? def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader rparen_loc: Location? def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # attr_reader block: BlockNode | BlockArgumentNode | nil attr_reader :block # def keyword: () -> String def keyword keyword_loc.slice end # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :super_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :super_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SuperNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (lparen_loc.nil? == other.lparen_loc.nil?) && (arguments === other.arguments) && (rparen_loc.nil? == other.rparen_loc.nil?) && (block === other.block) end end # Represents a symbol literal or a symbol contained within a `%i` list. # # :foo # ^^^^ # # %i[foo] # ^^^ class SymbolNode < Node # Initialize a new SymbolNode node. def initialize(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @value_loc = value_loc @closing_loc = closing_loc @unescaped = unescaped 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*opening_loc, *value_loc, *closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location?, ?value_loc: Location?, ?closing_loc: Location?, ?unescaped: String) -> SymbolNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, value_loc: self.value_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) SymbolNode.new(source, node_id, location, flags, opening_loc, value_loc, closing_loc, unescaped) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location?, value_loc: Location?, closing_loc: Location?, unescaped: String } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped } end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(SymbolFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(SymbolFlags::FORCED_BINARY_ENCODING) end # def forced_us_ascii_encoding?: () -> bool def forced_us_ascii_encoding? flags.anybits?(SymbolFlags::FORCED_US_ASCII_ENCODING) end # attr_reader opening_loc: Location? def opening_loc location = @opening_loc case location when nil nil when Location location else @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) unless @opening_loc.nil? end # attr_reader value_loc: Location? def value_loc location = @value_loc case location when nil nil when Location location else @value_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the value_loc location using the given saved source so that # it can be retrieved later. def save_value_loc(repository) repository.enter(node_id, :value_loc) unless @value_loc.nil? end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # attr_reader unescaped: String attr_reader :unescaped # def opening: () -> String? def opening opening_loc&.slice end # def value: () -> String? def value value_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :symbol_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :symbol_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(SymbolNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (value_loc.nil? == other.value_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (unescaped === other.unescaped) end end # Represents the use of the literal `true` keyword. # # true # ^^^^ class TrueNode < Node # Initialize a new TrueNode node. def initialize(source, node_id, location, flags) @source = source @node_id = node_id @location = location @flags = flags 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer) -> TrueNode def copy(node_id: self.node_id, location: self.location, flags: self.flags) TrueNode.new(source, node_id, location, flags) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location } def deconstruct_keys(keys) { node_id: node_id, location: location } end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :true_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :true_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(TrueNode) end end # Represents the use of the `undef` keyword. # # undef :foo, :bar, :baz # ^^^^^^^^^^^^^^^^^^^^^^ class UndefNode < Node # Initialize a new UndefNode node. def initialize(source, node_id, location, flags, names, keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @names = names @keyword_loc = keyword_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [*names] end # def comment_targets: () -> Array[Node | Location] def comment_targets [*names, keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?names: Array[SymbolNode | InterpolatedSymbolNode], ?keyword_loc: Location) -> UndefNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, names: self.names, keyword_loc: self.keyword_loc) UndefNode.new(source, node_id, location, flags, names, keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, names: Array[SymbolNode | InterpolatedSymbolNode], keyword_loc: Location } def deconstruct_keys(keys) { node_id: node_id, location: location, names: names, keyword_loc: keyword_loc } end # attr_reader names: Array[SymbolNode | InterpolatedSymbolNode] attr_reader :names # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # def keyword: () -> String def keyword keyword_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :undef_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :undef_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(UndefNode) && (names.length == other.names.length) && names.zip(other.names).all? { |left, right| left === right } && (keyword_loc.nil? == other.keyword_loc.nil?) 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 # Initialize a new UnlessNode node. def initialize(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @predicate = predicate @then_keyword_loc = then_keyword_loc @statements = statements @else_clause = else_clause @end_keyword_loc = end_keyword_loc 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, else_clause] end # def compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate compact << statements if statements compact << else_clause if else_clause compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, predicate, *then_keyword_loc, *statements, *else_clause, *end_keyword_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?predicate: Prism::node, ?then_keyword_loc: Location?, ?statements: StatementsNode?, ?else_clause: ElseNode?, ?end_keyword_loc: Location?) -> UnlessNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, predicate: self.predicate, then_keyword_loc: self.then_keyword_loc, statements: self.statements, else_clause: self.else_clause, end_keyword_loc: self.end_keyword_loc) UnlessNode.new(source, node_id, location, flags, keyword_loc, predicate, then_keyword_loc, statements, else_clause, end_keyword_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, predicate: Prism::node, then_keyword_loc: Location?, statements: StatementsNode?, else_clause: ElseNode?, end_keyword_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, predicate: predicate, then_keyword_loc: then_keyword_loc, statements: statements, else_clause: else_clause, end_keyword_loc: end_keyword_loc } end # The location of the `unless` keyword. # # unless cond then bar end # ^^^^^^ # # bar unless cond # ^^^^^^ def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # The condition to be evaluated for the unless expression. It can be any [non-void expression](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression). # # unless cond then bar end # ^^^^ # # bar unless cond # ^^^^ attr_reader :predicate # The location of the `then` keyword, if present. # # unless cond then bar end # ^^^^ def then_keyword_loc location = @then_keyword_loc case location when nil nil when Location location else @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the then_keyword_loc location using the given saved source so that # it can be retrieved later. def save_then_keyword_loc(repository) repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? end # The body of statements that will executed if the unless condition is # falsey. Will be `nil` if no body is provided. # # unless cond then bar end # ^^^ attr_reader :statements # The else clause of the unless expression, if present. # # unless cond then bar else baz end # ^^^^^^^^ attr_reader :else_clause # The location of the `end` keyword, if present. # # unless cond then bar end # ^^^ def end_keyword_loc location = @end_keyword_loc case location when nil nil when Location location else @end_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the end_keyword_loc location using the given saved source so that # it can be retrieved later. def save_end_keyword_loc(repository) repository.enter(node_id, :end_keyword_loc) unless @end_keyword_loc.nil? end # def keyword: () -> String def keyword keyword_loc.slice end # def then_keyword: () -> String? def then_keyword then_keyword_loc&.slice end # def end_keyword: () -> String? def end_keyword end_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :unless_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :unless_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(UnlessNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (predicate === other.predicate) && (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && (statements === other.statements) && (else_clause === other.else_clause) && (end_keyword_loc.nil? == other.end_keyword_loc.nil?) 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 # Initialize a new UntilNode node. def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @do_keyword_loc = do_keyword_loc @closing_loc = closing_loc @predicate = predicate @statements = statements 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *do_keyword_loc, *closing_loc, predicate, *statements] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> UntilNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements) UntilNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, do_keyword_loc: do_keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements } end # def begin_modifier?: () -> bool def begin_modifier? flags.anybits?(LoopFlags::BEGIN_MODIFIER) end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader do_keyword_loc: Location? def do_keyword_loc location = @do_keyword_loc case location when nil nil when Location location else @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the do_keyword_loc location using the given saved source so that # it can be retrieved later. def save_do_keyword_loc(repository) repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # attr_reader predicate: Prism::node attr_reader :predicate # attr_reader statements: StatementsNode? attr_reader :statements # def keyword: () -> String def keyword keyword_loc.slice end # def do_keyword: () -> String? def do_keyword do_keyword_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :until_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :until_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(UntilNode) && (flags === other.flags) && (keyword_loc.nil? == other.keyword_loc.nil?) && (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (predicate === other.predicate) && (statements === other.statements) end end # Represents the use of the `when` keyword within a case statement. # # case true # when true # ^^^^^^^^^ # end class WhenNode < Node # Initialize a new WhenNode node. def initialize(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @conditions = conditions @then_keyword_loc = then_keyword_loc @statements = statements 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact.concat(conditions) compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *conditions, *then_keyword_loc, *statements] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?conditions: Array[Prism::node], ?then_keyword_loc: Location?, ?statements: StatementsNode?) -> WhenNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, conditions: self.conditions, then_keyword_loc: self.then_keyword_loc, statements: self.statements) WhenNode.new(source, node_id, location, flags, keyword_loc, conditions, then_keyword_loc, statements) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, conditions: Array[Prism::node], then_keyword_loc: Location?, statements: StatementsNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, conditions: conditions, then_keyword_loc: then_keyword_loc, statements: statements } end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader conditions: Array[Prism::node] attr_reader :conditions # attr_reader then_keyword_loc: Location? def then_keyword_loc location = @then_keyword_loc case location when nil nil when Location location else @then_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the then_keyword_loc location using the given saved source so that # it can be retrieved later. def save_then_keyword_loc(repository) repository.enter(node_id, :then_keyword_loc) unless @then_keyword_loc.nil? end # attr_reader statements: StatementsNode? attr_reader :statements # def keyword: () -> String def keyword keyword_loc.slice end # def then_keyword: () -> String? def then_keyword then_keyword_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :when_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :when_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(WhenNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (conditions.length == other.conditions.length) && conditions.zip(other.conditions).all? { |left, right| left === right } && (then_keyword_loc.nil? == other.then_keyword_loc.nil?) && (statements === other.statements) 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 # Initialize a new WhileNode node. def initialize(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @do_keyword_loc = do_keyword_loc @closing_loc = closing_loc @predicate = predicate @statements = statements 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << predicate compact << statements if statements compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *do_keyword_loc, *closing_loc, predicate, *statements] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?do_keyword_loc: Location?, ?closing_loc: Location?, ?predicate: Prism::node, ?statements: StatementsNode?) -> WhileNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, do_keyword_loc: self.do_keyword_loc, closing_loc: self.closing_loc, predicate: self.predicate, statements: self.statements) WhileNode.new(source, node_id, location, flags, keyword_loc, do_keyword_loc, closing_loc, predicate, statements) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, do_keyword_loc: Location?, closing_loc: Location?, predicate: Prism::node, statements: StatementsNode? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, do_keyword_loc: do_keyword_loc, closing_loc: closing_loc, predicate: predicate, statements: statements } end # def begin_modifier?: () -> bool def begin_modifier? flags.anybits?(LoopFlags::BEGIN_MODIFIER) end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader do_keyword_loc: Location? def do_keyword_loc location = @do_keyword_loc case location when nil nil when Location location else @do_keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the do_keyword_loc location using the given saved source so that # it can be retrieved later. def save_do_keyword_loc(repository) repository.enter(node_id, :do_keyword_loc) unless @do_keyword_loc.nil? end # attr_reader closing_loc: Location? def closing_loc location = @closing_loc case location when nil nil when Location location else @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) unless @closing_loc.nil? end # attr_reader predicate: Prism::node attr_reader :predicate # attr_reader statements: StatementsNode? attr_reader :statements # def keyword: () -> String def keyword keyword_loc.slice end # def do_keyword: () -> String? def do_keyword do_keyword_loc&.slice end # def closing: () -> String? def closing closing_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :while_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :while_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(WhileNode) && (flags === other.flags) && (keyword_loc.nil? == other.keyword_loc.nil?) && (do_keyword_loc.nil? == other.do_keyword_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (predicate === other.predicate) && (statements === other.statements) end end # Represents an xstring literal with no interpolation. # # `foo` # ^^^^^ class XStringNode < Node # Initialize a new XStringNode node. def initialize(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) @source = source @node_id = node_id @location = location @flags = flags @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes [] end # def comment_targets: () -> Array[Node | Location] def comment_targets [opening_loc, content_loc, closing_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?opening_loc: Location, ?content_loc: Location, ?closing_loc: Location, ?unescaped: String) -> XStringNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, opening_loc: self.opening_loc, content_loc: self.content_loc, closing_loc: self.closing_loc, unescaped: self.unescaped) XStringNode.new(source, node_id, location, flags, opening_loc, content_loc, closing_loc, unescaped) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String } def deconstruct_keys(keys) { node_id: node_id, location: location, opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped } end # def forced_utf8_encoding?: () -> bool def forced_utf8_encoding? flags.anybits?(EncodingFlags::FORCED_UTF8_ENCODING) end # def forced_binary_encoding?: () -> bool def forced_binary_encoding? flags.anybits?(EncodingFlags::FORCED_BINARY_ENCODING) end # attr_reader opening_loc: Location def opening_loc location = @opening_loc return location if location.is_a?(Location) @opening_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the opening_loc location using the given saved source so that # it can be retrieved later. def save_opening_loc(repository) repository.enter(node_id, :opening_loc) end # attr_reader content_loc: Location def content_loc location = @content_loc return location if location.is_a?(Location) @content_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the content_loc location using the given saved source so that # it can be retrieved later. def save_content_loc(repository) repository.enter(node_id, :content_loc) end # attr_reader closing_loc: Location def closing_loc location = @closing_loc return location if location.is_a?(Location) @closing_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the closing_loc location using the given saved source so that # it can be retrieved later. def save_closing_loc(repository) repository.enter(node_id, :closing_loc) end # attr_reader unescaped: String attr_reader :unescaped # def opening: () -> String def opening opening_loc.slice end # def content: () -> String def content content_loc.slice end # def closing: () -> String def closing closing_loc.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :x_string_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :x_string_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(XStringNode) && (flags === other.flags) && (opening_loc.nil? == other.opening_loc.nil?) && (content_loc.nil? == other.content_loc.nil?) && (closing_loc.nil? == other.closing_loc.nil?) && (unescaped === other.unescaped) end end # Represents the use of the `yield` keyword. # # yield 1 # ^^^^^^^ class YieldNode < Node # Initialize a new YieldNode node. def initialize(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc) @source = source @node_id = node_id @location = location @flags = flags @keyword_loc = keyword_loc @lparen_loc = lparen_loc @arguments = arguments @rparen_loc = rparen_loc 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 compact_child_nodes: () -> Array[Node] def compact_child_nodes compact = [] #: Array[Prism::node] compact << arguments if arguments compact end # def comment_targets: () -> Array[Node | Location] def comment_targets [keyword_loc, *lparen_loc, *arguments, *rparen_loc] #: Array[Prism::node | Location] end # def copy: (?node_id: Integer, ?location: Location, ?flags: Integer, ?keyword_loc: Location, ?lparen_loc: Location?, ?arguments: ArgumentsNode?, ?rparen_loc: Location?) -> YieldNode def copy(node_id: self.node_id, location: self.location, flags: self.flags, keyword_loc: self.keyword_loc, lparen_loc: self.lparen_loc, arguments: self.arguments, rparen_loc: self.rparen_loc) YieldNode.new(source, node_id, location, flags, keyword_loc, lparen_loc, arguments, rparen_loc) end # def deconstruct: () -> Array[nil | Node] alias deconstruct child_nodes # def deconstruct_keys: (Array[Symbol] keys) -> { node_id: Integer, location: Location, keyword_loc: Location, lparen_loc: Location?, arguments: ArgumentsNode?, rparen_loc: Location? } def deconstruct_keys(keys) { node_id: node_id, location: location, keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc } end # attr_reader keyword_loc: Location def keyword_loc location = @keyword_loc return location if location.is_a?(Location) @keyword_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end # Save the keyword_loc location using the given saved source so that # it can be retrieved later. def save_keyword_loc(repository) repository.enter(node_id, :keyword_loc) end # attr_reader lparen_loc: Location? def lparen_loc location = @lparen_loc case location when nil nil when Location location else @lparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the lparen_loc location using the given saved source so that # it can be retrieved later. def save_lparen_loc(repository) repository.enter(node_id, :lparen_loc) unless @lparen_loc.nil? end # attr_reader arguments: ArgumentsNode? attr_reader :arguments # attr_reader rparen_loc: Location? def rparen_loc location = @rparen_loc case location when nil nil when Location location else @rparen_loc = Location.new(source, location >> 32, location & 0xFFFFFFFF) end end # Save the rparen_loc location using the given saved source so that # it can be retrieved later. def save_rparen_loc(repository) repository.enter(node_id, :rparen_loc) unless @rparen_loc.nil? end # def keyword: () -> String def keyword keyword_loc.slice end # def lparen: () -> String? def lparen lparen_loc&.slice end # def rparen: () -> String? def rparen rparen_loc&.slice end # def inspect -> String def inspect InspectVisitor.compose(self) end # Return a symbol representation of this node type. See `Node#type`. def type :yield_node end # Return a symbol representation of this node type. See `Node::type`. def self.type :yield_node end # Implements case-equality for the node. This is effectively == but without # comparing the value of locations. Locations are checked only for presence. def ===(other) other.is_a?(YieldNode) && (keyword_loc.nil? == other.keyword_loc.nil?) && (lparen_loc.nil? == other.lparen_loc.nil?) && (arguments === other.arguments) && (rparen_loc.nil? == other.rparen_loc.nil?) end end # Flags for arguments nodes. module ArgumentsNodeFlags # if the arguments contain forwarding CONTAINS_FORWARDING = 1 << 2 # if the arguments contain keywords CONTAINS_KEYWORDS = 1 << 3 # if the arguments contain a keyword splat CONTAINS_KEYWORD_SPLAT = 1 << 4 # if the arguments contain a splat CONTAINS_SPLAT = 1 << 5 # if the arguments contain multiple splats CONTAINS_MULTIPLE_SPLATS = 1 << 6 end # Flags for array nodes. module ArrayNodeFlags # if array contains splat nodes CONTAINS_SPLAT = 1 << 2 end # Flags for call nodes. module CallNodeFlags # &. operator SAFE_NAVIGATION = 1 << 2 # a call that could have been a local variable VARIABLE_CALL = 1 << 3 # a call that is an attribute write, so the value being written should be returned ATTRIBUTE_WRITE = 1 << 4 # a call that ignores method visibility IGNORE_VISIBILITY = 1 << 5 end # Flags for nodes that have unescaped content. module EncodingFlags # internal bytes forced the encoding to UTF-8 FORCED_UTF8_ENCODING = 1 << 2 # internal bytes forced the encoding to binary FORCED_BINARY_ENCODING = 1 << 3 end # Flags for integer nodes that correspond to the base of the integer. module IntegerBaseFlags # 0b prefix BINARY = 1 << 2 # 0d or no prefix DECIMAL = 1 << 3 # 0o or 0 prefix OCTAL = 1 << 4 # 0x prefix HEXADECIMAL = 1 << 5 end # Flags for interpolated string nodes that indicated mutability if they are also marked as literals. module InterpolatedStringNodeFlags # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` FROZEN = 1 << 2 # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal`; only for adjacent string literals like `'a' 'b'` MUTABLE = 1 << 3 end # Flags for keyword hash nodes. module KeywordHashNodeFlags # a keyword hash which only has `AssocNode` elements all with symbol keys, which means the elements can be treated as keyword arguments SYMBOL_KEYS = 1 << 2 end # Flags for while and until loop nodes. module LoopFlags # a loop after a begin statement, so the body is executed first before the condition BEGIN_MODIFIER = 1 << 2 end # Flags for parameter nodes. module ParameterFlags # a parameter name that has been repeated in the method signature REPEATED_PARAMETER = 1 << 2 end # Flags for range and flip-flop nodes. module RangeFlags # ... operator EXCLUDE_END = 1 << 2 end # Flags for regular expression and match last line nodes. module RegularExpressionFlags # i - ignores the case of characters when matching IGNORE_CASE = 1 << 2 # x - ignores whitespace and allows comments in regular expressions EXTENDED = 1 << 3 # m - allows $ to match the end of lines within strings MULTI_LINE = 1 << 4 # o - only interpolates values into the regular expression once ONCE = 1 << 5 # e - forces the EUC-JP encoding EUC_JP = 1 << 6 # n - forces the ASCII-8BIT encoding ASCII_8BIT = 1 << 7 # s - forces the Windows-31J encoding WINDOWS_31J = 1 << 8 # u - forces the UTF-8 encoding UTF_8 = 1 << 9 # internal bytes forced the encoding to UTF-8 FORCED_UTF8_ENCODING = 1 << 10 # internal bytes forced the encoding to binary FORCED_BINARY_ENCODING = 1 << 11 # internal bytes forced the encoding to US-ASCII FORCED_US_ASCII_ENCODING = 1 << 12 end # Flags for shareable constant nodes. module ShareableConstantNodeFlags # constant writes that should be modified with shareable constant value literal LITERAL = 1 << 2 # constant writes that should be modified with shareable constant value experimental everything EXPERIMENTAL_EVERYTHING = 1 << 3 # constant writes that should be modified with shareable constant value experimental copy EXPERIMENTAL_COPY = 1 << 4 end # Flags for string nodes. module StringFlags # internal bytes forced the encoding to UTF-8 FORCED_UTF8_ENCODING = 1 << 2 # internal bytes forced the encoding to binary FORCED_BINARY_ENCODING = 1 << 3 # frozen by virtue of a `frozen_string_literal: true` comment or `--enable-frozen-string-literal` FROZEN = 1 << 4 # mutable by virtue of a `frozen_string_literal: false` comment or `--disable-frozen-string-literal` MUTABLE = 1 << 5 end # Flags for symbol nodes. module SymbolFlags # internal bytes forced the encoding to UTF-8 FORCED_UTF8_ENCODING = 1 << 2 # internal bytes forced the encoding to binary FORCED_BINARY_ENCODING = 1 << 3 # internal bytes forced the encoding to US-ASCII FORCED_US_ASCII_ENCODING = 1 << 4 end # The flags that are common to all nodes. module NodeFlags # A flag to indicate that the node is a candidate to emit a :line event # through tracepoint when compiled. NEWLINE = 1 # A flag to indicate that the value that the node represents is a value that # can be determined at parse-time. STATIC_LITERAL = 2 end end