Class: TreeHaver::Backends::Prism::Node Private

Inherits:
Object
  • Object
show all
Defined in:
lib/tree_haver/backends/prism.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Prism node wrapper

Wraps Prism::Node objects to provide tree-sitter-compatible node API.

Prism nodes provide:

  • type: class name without “Node” suffix (e.g., ProgramNode → “program”)

  • location: ::Prism::Location with start/end offsets and line/column

  • child_nodes: array of child nodes

  • Various node-specific accessors

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, source) ⇒ Node

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Node.



328
329
330
331
# File 'lib/tree_haver/backends/prism.rb', line 328

def initialize(node, source)
  @inner_node = node
  @source = source
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, **kwargs, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Delegate unknown methods to the underlying Prism node

This provides passthrough access for Prism-specific node methods like ‘receiver`, `message`, `arguments`, etc.

Parameters:

  • method_name (Symbol)

    method to call

  • args (Array)

    arguments to pass

  • kwargs (Hash)

    keyword arguments

  • block (Proc)

    block to pass

Returns:

  • (Object)

    result from the underlying node



613
614
615
616
617
618
619
# File 'lib/tree_haver/backends/prism.rb', line 613

def method_missing(method_name, *args, **kwargs, &block)
  if @inner_node&.respond_to?(method_name)
    @inner_node.public_send(method_name, *args, **kwargs, &block)
  else
    super
  end
end

Instance Attribute Details

#inner_node::Prism::Node (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the underlying Prism node.

Returns:

  • (::Prism::Node)

    the underlying Prism node



323
324
325
# File 'lib/tree_haver/backends/prism.rb', line 323

def inner_node
  @inner_node
end

#sourceString (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the source code.

Returns:

  • (String)

    the source code



326
327
328
# File 'lib/tree_haver/backends/prism.rb', line 326

def source
  @source
end

Instance Method Details

#child(index) ⇒ Node?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get a child node by index

Parameters:

  • index (Integer)

    child index

Returns:

  • (Node, nil)

    wrapped child node



464
465
466
467
468
469
470
471
472
# File 'lib/tree_haver/backends/prism.rb', line 464

def child(index)
  return if @inner_node.nil?
  return unless @inner_node.respond_to?(:child_nodes)

  children_array = @inner_node.child_nodes.compact
  return if index >= children_array.size

  Node.new(children_array[index], @source)
end

#child_by_field_name(name) ⇒ Node? Also known as: field

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get a child by field name (Prism node accessor)

Prism nodes have specific accessors for their children. This method tries to call that accessor.

Parameters:

  • name (String, Symbol)

    field/accessor name

Returns:

  • (Node, nil)

    wrapped child node



539
540
541
542
543
544
545
546
547
548
549
550
# File 'lib/tree_haver/backends/prism.rb', line 539

def child_by_field_name(name)
  return if @inner_node.nil?
  return unless @inner_node.respond_to?(name)

  result = @inner_node.public_send(name)
  return if result.nil?

  # Wrap if it's a node, otherwise return nil
  if result.is_a?(::Prism::Node)
    Node.new(result, @source)
  end
end

#child_countInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the number of child nodes

Returns:

  • (Integer)


454
455
456
457
458
# File 'lib/tree_haver/backends/prism.rb', line 454

def child_count
  return 0 if @inner_node.nil?
  return 0 unless @inner_node.respond_to?(:child_nodes)
  @inner_node.child_nodes.compact.size
end

#childrenArray<Node>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get all child nodes

Returns:

  • (Array<Node>)

    array of wrapped child nodes



477
478
479
480
481
482
# File 'lib/tree_haver/backends/prism.rb', line 477

def children
  return [] if @inner_node.nil?
  return [] unless @inner_node.respond_to?(:child_nodes)

  @inner_node.child_nodes.compact.map { |n| Node.new(n, @source) }
end

#each {|Node| ... } ⇒ Enumerator?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Iterate over child nodes

Yields:

  • (Node)

    each child node

Returns:

  • (Enumerator, nil)


488
489
490
491
# File 'lib/tree_haver/backends/prism.rb', line 488

def each(&block)
  return to_enum(__method__) unless block_given?
  children.each(&block)
end

#end_byteInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get byte offset where the node ends

Returns:

  • (Integer)


363
364
365
366
367
# File 'lib/tree_haver/backends/prism.rb', line 363

def end_byte
  return 0 if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  loc&.end_offset || 0
end

#end_lineInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the 1-based line number where this node ends

Returns:

  • (Integer)

    1-based line number



405
406
407
408
409
# File 'lib/tree_haver/backends/prism.rb', line 405

def end_line
  return 1 if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  loc&.end_line || 1
end

#end_pointHash{Symbol => Integer}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the end position as row/column

Returns:

  • (Hash{Symbol => Integer})

    with :row and :column keys



384
385
386
387
388
389
390
391
# File 'lib/tree_haver/backends/prism.rb', line 384

def end_point
  return {row: 0, column: 0} if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  return {row: 0, column: 0} unless loc

  # Prism uses 1-based lines internally but we need 0-based for tree-sitter compat
  {row: (loc.end_line - 1), column: loc.end_column}
end

#first_childNode?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the first child node

Returns:

  • (Node, nil)

    First child or nil



429
430
431
# File 'lib/tree_haver/backends/prism.rb', line 429

def first_child
  child(0)
end

#has_error?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this node has errors

Returns:

  • (Boolean)


496
497
498
499
500
501
502
503
504
505
# File 'lib/tree_haver/backends/prism.rb', line 496

def has_error?
  return false if @inner_node.nil?

  # Check if this is an error node type
  return true if type.include?("missing") || type.include?("error")

  # Check children recursively (Prism error nodes are usually children)
  return false unless @inner_node.respond_to?(:child_nodes)
  @inner_node.child_nodes.compact.any? { |n| n.class.name.to_s.include?("Missing") }
end

#inspectString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

String representation for debugging

Returns:

  • (String)


582
583
584
# File 'lib/tree_haver/backends/prism.rb', line 582

def inspect
  "#<#{self.class} type=#{type} bytes=#{start_byte}..#{end_byte}>"
end

#missing?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this node is a “missing” node (error recovery)

Returns:

  • (Boolean)


510
511
512
513
# File 'lib/tree_haver/backends/prism.rb', line 510

def missing?
  return false if @inner_node.nil?
  type.include?("missing")
end

#named?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this is a “named” node (structural vs punctuation)

In Prism, all nodes are “named” in tree-sitter terminology (there’s no distinction between named and anonymous nodes).

Returns:

  • (Boolean)


521
522
523
# File 'lib/tree_haver/backends/prism.rb', line 521

def named?
  true
end

#next_siblingnil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Prism nodes don’t have sibling references.

Get next sibling

Returns:

  • (nil)


567
568
569
# File 'lib/tree_haver/backends/prism.rb', line 567

def next_sibling
  nil
end

#parentnil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Prism nodes don’t have built-in parent references. This always returns nil. Use tree traversal instead.

Get the parent node

Returns:

  • (nil)


559
560
561
# File 'lib/tree_haver/backends/prism.rb', line 559

def parent
  nil  # Prism doesn't track parent references
end

#prev_siblingnil

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Note:

Prism nodes don’t have sibling references.

Get previous sibling

Returns:

  • (nil)


575
576
577
# File 'lib/tree_haver/backends/prism.rb', line 575

def prev_sibling
  nil
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if node responds to a method (includes delegation to inner_node)

Parameters:

  • method_name (Symbol)

    method to check

  • include_private (Boolean) (defaults to: false)

    include private methods

Returns:

  • (Boolean)


598
599
600
601
# File 'lib/tree_haver/backends/prism.rb', line 598

def respond_to_missing?(method_name, include_private = false)
  return false if @inner_node.nil?
  @inner_node.respond_to?(method_name, include_private) || super
end

#source_positionHash{Symbol => Integer}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get position information as a hash

Returns a hash with 1-based line numbers and 0-based columns. Compatible with *-merge gems’ FileAnalysisBase.

Returns:

  • (Hash{Symbol => Integer})

    Position hash



417
418
419
420
421
422
423
424
# File 'lib/tree_haver/backends/prism.rb', line 417

def source_position
  {
    start_line: start_line,
    end_line: end_line,
    start_column: start_point[:column],
    end_column: end_point[:column],
  }
end

#start_byteInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get byte offset where the node starts

Returns:

  • (Integer)


354
355
356
357
358
# File 'lib/tree_haver/backends/prism.rb', line 354

def start_byte
  return 0 if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  loc&.start_offset || 0
end

#start_lineInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the 1-based line number where this node starts

Returns:

  • (Integer)

    1-based line number



396
397
398
399
400
# File 'lib/tree_haver/backends/prism.rb', line 396

def start_line
  return 1 if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  loc&.start_line || 1
end

#start_pointHash{Symbol => Integer}

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the start position as row/column

Returns:

  • (Hash{Symbol => Integer})

    with :row and :column keys



372
373
374
375
376
377
378
379
# File 'lib/tree_haver/backends/prism.rb', line 372

def start_point
  return {row: 0, column: 0} if @inner_node.nil? || !@inner_node.respond_to?(:location)
  loc = @inner_node.location
  return {row: 0, column: 0} unless loc

  # Prism uses 1-based lines internally but we need 0-based for tree-sitter compat
  {row: (loc.start_line - 1), column: loc.start_column}
end

#structural?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Check if this is a structural node

Returns:

  • (Boolean)


528
529
530
# File 'lib/tree_haver/backends/prism.rb', line 528

def structural?
  true
end

#textString Also known as: slice

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get the text content of this node

Returns:

  • (String)


436
437
438
439
440
441
442
443
444
445
446
# File 'lib/tree_haver/backends/prism.rb', line 436

def text
  return "" if @inner_node.nil?

  if @inner_node.respond_to?(:slice)
    @inner_node.slice
  elsif @source
    @source[start_byte...end_byte] || ""
  else
    ""
  end
end

#to_sString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

String representation

Returns:

  • (String)


589
590
591
# File 'lib/tree_haver/backends/prism.rb', line 589

def to_s
  text
end

#typeString Also known as: kind

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Get node type from Prism class name

Converts PrismClassName to tree-sitter-style type string. Example: CallNode → “call_node”, ProgramNode → “program_node”

Returns:

  • (String)

    node type in snake_case



339
340
341
342
343
344
345
346
# File 'lib/tree_haver/backends/prism.rb', line 339

def type
  return "nil" if @inner_node.nil?

  # Convert class name to snake_case type
  # ProgramNode → program_node, CallNode → call_node
  class_name = @inner_node.class.name.split("::").last
  class_name.gsub(/([A-Z])/, '_\1').downcase.sub(/^_/, "")
end