Class: Prism::IndexOrWriteNode

Inherits:
PrismNode
  • Object
show all
Defined in:
lib/prism/node.rb,
ext/prism/api_node.c

Overview

Represents the use of the ‘||=` operator on a call to `[]`.

foo.bar[baz] ||= value
^^^^^^^^^^^^^^^^^^^^^^

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, location) ⇒ IndexOrWriteNode

def initialize: (flags: Integer, receiver: Node?, call_operator_loc: Location?, opening_loc: Location, arguments: ArgumentsNode?, closing_loc: Location, block: Node?, operator_loc: Location, value: Node, location: Location) -> void



8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
# File 'lib/prism/node.rb', line 8665

def initialize(flags, receiver, call_operator_loc, opening_loc, arguments, closing_loc, block, operator_loc, value, 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
  @location = location
end

Instance Attribute Details

#argumentsObject (readonly)

attr_reader arguments: ArgumentsNode?



8650
8651
8652
# File 'lib/prism/node.rb', line 8650

def arguments
  @arguments
end

#blockObject (readonly)

attr_reader block: Node?



8656
8657
8658
# File 'lib/prism/node.rb', line 8656

def block
  @block
end

#call_operator_locObject (readonly)

attr_reader call_operator_loc: Location?



8644
8645
8646
# File 'lib/prism/node.rb', line 8644

def call_operator_loc
  @call_operator_loc
end

#closing_locObject (readonly)

attr_reader closing_loc: Location



8653
8654
8655
# File 'lib/prism/node.rb', line 8653

def closing_loc
  @closing_loc
end

#flagsObject (readonly)

Returns the value of attribute flags.



8638
8639
8640
# File 'lib/prism/node.rb', line 8638

def flags
  @flags
end

#opening_locObject (readonly)

attr_reader opening_loc: Location



8647
8648
8649
# File 'lib/prism/node.rb', line 8647

def opening_loc
  @opening_loc
end

#operator_locObject (readonly)

attr_reader operator_loc: Location



8659
8660
8661
# File 'lib/prism/node.rb', line 8659

def operator_loc
  @operator_loc
end

#receiverObject (readonly)

attr_reader receiver: Node?



8641
8642
8643
# File 'lib/prism/node.rb', line 8641

def receiver
  @receiver
end

#valueObject (readonly)

attr_reader value: Node



8662
8663
8664
# File 'lib/prism/node.rb', line 8662

def value
  @value
end

Class Method Details

.typeObject

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: () -> Symbol



8818
8819
8820
# File 'lib/prism/node.rb', line 8818

def self.type
  :index_or_write_node
end

Instance Method Details

#accept(visitor) ⇒ Object

def accept: (visitor: Visitor) -> void



8679
8680
8681
# File 'lib/prism/node.rb', line 8679

def accept(visitor)
  visitor.visit_index_or_write_node(self)
end

#attribute_write?Boolean

def attribute_write?: () -> bool

Returns:

  • (Boolean)


8738
8739
8740
# File 'lib/prism/node.rb', line 8738

def attribute_write?
  flags.anybits?(CallNodeFlags::ATTRIBUTE_WRITE)
end

#call_operatorObject

def call_operator: () -> String?



8743
8744
8745
# File 'lib/prism/node.rb', line 8743

def call_operator
  call_operator_loc&.slice
end

#child_nodesObject Also known as: deconstruct

def child_nodes: () -> Array[nil | Node]



8684
8685
8686
# File 'lib/prism/node.rb', line 8684

def child_nodes
  [receiver, arguments, block, value]
end

#closingObject

def closing: () -> String



8753
8754
8755
# File 'lib/prism/node.rb', line 8753

def closing
  closing_loc.slice
end

#comment_targetsObject

def comment_targets: () -> Array[Node | Location]



8699
8700
8701
# File 'lib/prism/node.rb', line 8699

def comment_targets
  [*receiver, *call_operator_loc, opening_loc, *arguments, closing_loc, *block, operator_loc, value]
end

#compact_child_nodesObject

def compact_child_nodes: () -> Array



8689
8690
8691
8692
8693
8694
8695
8696
# File 'lib/prism/node.rb', line 8689

def compact_child_nodes
  compact = []
  compact << receiver if receiver
  compact << arguments if arguments
  compact << block if block
  compact << value
  compact
end

#copy(**params) ⇒ Object

def copy: (**params) -> IndexOrWriteNode



8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
# File 'lib/prism/node.rb', line 8704

def copy(**params)
  IndexOrWriteNode.new(
    params.fetch(:flags) { flags },
    params.fetch(:receiver) { receiver },
    params.fetch(:call_operator_loc) { call_operator_loc },
    params.fetch(:opening_loc) { opening_loc },
    params.fetch(:arguments) { arguments },
    params.fetch(:closing_loc) { closing_loc },
    params.fetch(:block) { block },
    params.fetch(:operator_loc) { operator_loc },
    params.fetch(:value) { value },
    params.fetch(:location) { location },
  )
end

#deconstruct_keys(keys) ⇒ Object

def deconstruct_keys: (keys: Array) -> Hash[Symbol, nil | Node | Array | String | Token | Array | Location]



8723
8724
8725
# File 'lib/prism/node.rb', line 8723

def deconstruct_keys(keys)
  { 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, location: location }
end

#inspect(inspector = NodeInspector.new) ⇒ Object

def inspect(inspector: NodeInspector) -> String



8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
# File 'lib/prism/node.rb', line 8763

def inspect(inspector = NodeInspector.new)
  inspector << inspector.header(self)
  flags = [("safe_navigation" if safe_navigation?), ("variable_call" if variable_call?), ("attribute_write" if attribute_write?)].compact
  inspector << "├── flags: #{flags.empty? ? "" : flags.join(", ")}\n"
  if (receiver = self.receiver).nil?
    inspector << "├── receiver: ∅\n"
  else
    inspector << "├── receiver:\n"
    inspector << receiver.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
  end
  inspector << "├── call_operator_loc: #{inspector.location(call_operator_loc)}\n"
  inspector << "├── opening_loc: #{inspector.location(opening_loc)}\n"
  if (arguments = self.arguments).nil?
    inspector << "├── arguments: ∅\n"
  else
    inspector << "├── arguments:\n"
    inspector << arguments.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
  end
  inspector << "├── closing_loc: #{inspector.location(closing_loc)}\n"
  if (block = self.block).nil?
    inspector << "├── block: ∅\n"
  else
    inspector << "├── block:\n"
    inspector << block.inspect(inspector.child_inspector("")).delete_prefix(inspector.prefix)
  end
  inspector << "├── operator_loc: #{inspector.location(operator_loc)}\n"
  inspector << "└── value:\n"
  inspector << inspector.child_node(value, "    ")
  inspector.to_str
end

#openingObject

def opening: () -> String



8748
8749
8750
# File 'lib/prism/node.rb', line 8748

def opening
  opening_loc.slice
end

#operatorObject

def operator: () -> String



8758
8759
8760
# File 'lib/prism/node.rb', line 8758

def operator
  operator_loc.slice
end

#safe_navigation?Boolean

def safe_navigation?: () -> bool

Returns:

  • (Boolean)


8728
8729
8730
# File 'lib/prism/node.rb', line 8728

def safe_navigation?
  flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
end

#typeObject

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: () -> Symbol



8808
8809
8810
# File 'lib/prism/node.rb', line 8808

def type
  :index_or_write_node
end

#variable_call?Boolean

def variable_call?: () -> bool

Returns:

  • (Boolean)


8733
8734
8735
# File 'lib/prism/node.rb', line 8733

def variable_call?
  flags.anybits?(CallNodeFlags::VARIABLE_CALL)
end