Class: Prism::IndexAndWriteNode

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 the `[]` method.

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) ⇒ IndexAndWriteNode

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



8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
# File 'lib/prism/node.rb', line 8282

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?



8267
8268
8269
# File 'lib/prism/node.rb', line 8267

def arguments
  @arguments
end

#blockObject (readonly)

attr_reader block: Node?



8273
8274
8275
# File 'lib/prism/node.rb', line 8273

def block
  @block
end

#call_operator_locObject (readonly)

attr_reader call_operator_loc: Location?



8261
8262
8263
# File 'lib/prism/node.rb', line 8261

def call_operator_loc
  @call_operator_loc
end

#closing_locObject (readonly)

attr_reader closing_loc: Location



8270
8271
8272
# File 'lib/prism/node.rb', line 8270

def closing_loc
  @closing_loc
end

#flagsObject (readonly)

Returns the value of attribute flags.



8255
8256
8257
# File 'lib/prism/node.rb', line 8255

def flags
  @flags
end

#opening_locObject (readonly)

attr_reader opening_loc: Location



8264
8265
8266
# File 'lib/prism/node.rb', line 8264

def opening_loc
  @opening_loc
end

#operator_locObject (readonly)

attr_reader operator_loc: Location



8276
8277
8278
# File 'lib/prism/node.rb', line 8276

def operator_loc
  @operator_loc
end

#receiverObject (readonly)

attr_reader receiver: Node?



8258
8259
8260
# File 'lib/prism/node.rb', line 8258

def receiver
  @receiver
end

#valueObject (readonly)

attr_reader value: Node



8279
8280
8281
# File 'lib/prism/node.rb', line 8279

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



8435
8436
8437
# File 'lib/prism/node.rb', line 8435

def self.type
  :index_and_write_node
end

Instance Method Details

#accept(visitor) ⇒ Object

def accept: (visitor: Visitor) -> void



8296
8297
8298
# File 'lib/prism/node.rb', line 8296

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

#attribute_write?Boolean

def attribute_write?: () -> bool

Returns:

  • (Boolean)


8355
8356
8357
# File 'lib/prism/node.rb', line 8355

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

#call_operatorObject

def call_operator: () -> String?



8360
8361
8362
# File 'lib/prism/node.rb', line 8360

def call_operator
  call_operator_loc&.slice
end

#child_nodesObject Also known as: deconstruct

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



8301
8302
8303
# File 'lib/prism/node.rb', line 8301

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

#closingObject

def closing: () -> String



8370
8371
8372
# File 'lib/prism/node.rb', line 8370

def closing
  closing_loc.slice
end

#comment_targetsObject

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



8316
8317
8318
# File 'lib/prism/node.rb', line 8316

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



8306
8307
8308
8309
8310
8311
8312
8313
# File 'lib/prism/node.rb', line 8306

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



8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
# File 'lib/prism/node.rb', line 8321

def copy(**params)
  IndexAndWriteNode.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]



8340
8341
8342
# File 'lib/prism/node.rb', line 8340

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



8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
# File 'lib/prism/node.rb', line 8380

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



8365
8366
8367
# File 'lib/prism/node.rb', line 8365

def opening
  opening_loc.slice
end

#operatorObject

def operator: () -> String



8375
8376
8377
# File 'lib/prism/node.rb', line 8375

def operator
  operator_loc.slice
end

#safe_navigation?Boolean

def safe_navigation?: () -> bool

Returns:

  • (Boolean)


8345
8346
8347
# File 'lib/prism/node.rb', line 8345

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



8425
8426
8427
# File 'lib/prism/node.rb', line 8425

def type
  :index_and_write_node
end

#variable_call?Boolean

def variable_call?: () -> bool

Returns:

  • (Boolean)


8350
8351
8352
# File 'lib/prism/node.rb', line 8350

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