Class: TreeHaver::Backends::FFI::Node Private
- Inherits:
-
Object
- Object
- TreeHaver::Backends::FFI::Node
- Includes:
- Enumerable
- Defined in:
- lib/tree_haver/backends/ffi.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.
FFI-based tree-sitter node (raw backend node)
This is a raw backend node that wraps a TSNode by-value struct from the
tree-sitter C API. It provides the minimal interface needed for tree-sitter
operations but is NOT intended for direct use by application code.
== Architecture Note
Unlike pure-Ruby backends (Citrus, Parslet, Prism, Psych) which define Node
classes that inherit from TreeHaver::Base::Node, tree-sitter backends (MRI,
Rust, FFI, Java) define raw wrapper classes that get wrapped by TreeHaver::Node.
The wrapping hierarchy is:
FFI::Node (this class) → TreeHaver::Node → Base::Node
When you use TreeHaver::Parser#parse, the returned tree’s nodes are already
wrapped in TreeHaver::Node, which provides the full unified API including:
#children- Array of child nodes#text- Extract text from source#first_child,#last_child- Convenience accessors#start_line,#end_line- 1-based line numbers#source_position- Hash with position info#each,#map, etc. - Enumerable methods#to_s,#inspect- String representations
This raw class only implements methods that require direct FFI calls to the
tree-sitter C library. The wrapper adds Ruby-level conveniences.
Instance Method Summary collapse
-
#<=>(other) ⇒ Integer?
private
Compare nodes for ordering (used by Comparable module).
-
#child(index) ⇒ Node?
private
Get a child by index.
-
#child_by_field_name(field_name) ⇒ Node?
private
Get a child node by field name.
-
#child_count ⇒ Integer
private
Get the number of children.
-
#descendant_for_byte_range(start_byte, end_byte) ⇒ Node?
private
Find the smallest descendant that spans the given byte range.
-
#descendant_for_point_range(start_point, end_point) ⇒ Node?
private
Find the smallest descendant that spans the given point range.
-
#each {|child| ... } ⇒ Enumerator?
private
Iterate over child nodes.
-
#end_byte ⇒ Integer
private
Get end byte offset.
-
#end_point ⇒ TreeHaver::Point
private
Get end point.
-
#has_error? ⇒ Boolean
private
Check if node has error.
-
#initialize(ts_node_value) ⇒ Node
constructor
private
A new instance of Node.
-
#missing? ⇒ Boolean
private
Check if this is a MISSING node.
-
#named? ⇒ Boolean
private
Check if this is a named node.
-
#named_child(index) ⇒ Node?
private
Get a named child by index.
-
#named_child_count ⇒ Integer
private
Get the count of named children.
-
#named_descendant_for_byte_range(start_byte, end_byte) ⇒ Node?
private
Find the smallest named descendant that spans the given byte range.
-
#named_descendant_for_point_range(start_point, end_point) ⇒ Node?
private
Find the smallest named descendant that spans the given point range.
-
#next_named_sibling ⇒ Node?
private
Get the next named sibling node.
-
#next_sibling ⇒ Node?
private
Get the next sibling node.
-
#parent ⇒ Node?
private
Get the parent node.
-
#prev_named_sibling ⇒ Node?
private
Get the previous named sibling node.
-
#prev_sibling ⇒ Node?
private
Get the previous sibling node.
-
#start_byte ⇒ Integer
private
Get start byte offset.
-
#start_point ⇒ TreeHaver::Point
private
Get start point.
-
#type ⇒ String
private
Get the type name of this node.
Constructor Details
#initialize(ts_node_value) ⇒ 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.
717 718 719 720 |
# File 'lib/tree_haver/backends/ffi.rb', line 717 def initialize(ts_node_value) # Store by-value struct (FFI will copy); methods pass it back by value @val = ts_node_value end |
Instance Method Details
#<=>(other) ⇒ 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.
Compare nodes for ordering (used by Comparable module)
Nodes are ordered by their position in the source:
- First by start_byte (earlier nodes come first)
- Then by end_byte for tie-breaking (shorter spans come first)
- Then by type for deterministic ordering
990 991 992 993 994 995 996 997 998 999 1000 |
# File 'lib/tree_haver/backends/ffi.rb', line 990 def <=>(other) return unless other.is_a?(Node) cmp = start_byte <=> other.start_byte return cmp if cmp.nonzero? cmp = end_byte <=> other.end_byte return cmp if cmp.nonzero? type <=> other.type end |
#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 by index
740 741 742 743 744 |
# File 'lib/tree_haver/backends/ffi.rb', line 740 def child(index) return if index >= child_count || index < 0 child_node = Native.ts_node_child(@val, index) Node.new(child_node) end |
#child_by_field_name(field_name) ⇒ 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 field name
Tree-sitter grammars define named fields for certain child positions.
For example, in JSON, a “pair” node has “key” and “value” fields.
756 757 758 759 760 761 762 763 |
# File 'lib/tree_haver/backends/ffi.rb', line 756 def child_by_field_name(field_name) name = String(field_name) child_node = Native.ts_node_child_by_field_name(@val, name, name.bytesize) # ts_node_child_by_field_name returns a null node if field not found return if Native.ts_node_is_null(child_node) Node.new(child_node) end |
#child_count ⇒ 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 number of children
732 733 734 |
# File 'lib/tree_haver/backends/ffi.rb', line 732 def child_count Native.ts_node_child_count(@val) end |
#descendant_for_byte_range(start_byte, end_byte) ⇒ 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.
Find the smallest descendant that spans the given byte range
905 906 907 908 909 910 |
# File 'lib/tree_haver/backends/ffi.rb', line 905 def descendant_for_byte_range(start_byte, end_byte) node = Native.ts_node_descendant_for_byte_range(@val, start_byte, end_byte) return if Native.ts_node_is_null(node) Node.new(node) end |
#descendant_for_point_range(start_point, end_point) ⇒ 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.
Find the smallest descendant that spans the given point range
929 930 931 932 933 934 935 936 937 938 939 940 941 942 |
# File 'lib/tree_haver/backends/ffi.rb', line 929 def descendant_for_point_range(start_point, end_point) start_pt = Native::TSPoint.new start_pt[:row] = start_point.respond_to?(:row) ? start_point.row : start_point[:row] start_pt[:column] = start_point.respond_to?(:column) ? start_point.column : start_point[:column] end_pt = Native::TSPoint.new end_pt[:row] = end_point.respond_to?(:row) ? end_point.row : end_point[:row] end_pt[:column] = end_point.respond_to?(:column) ? end_point.column : end_point[:column] node = Native.ts_node_descendant_for_point_range(@val, start_pt, end_pt) return if Native.ts_node_is_null(node) Node.new(node) end |
#each {|child| ... } ⇒ 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
968 969 970 971 972 973 974 975 976 977 978 979 |
# File 'lib/tree_haver/backends/ffi.rb', line 968 def each return enum_for(:each) unless block_given? count = child_count i = 0 while i < count child = Native.ts_node_child(@val, i) yield Node.new(child) i += 1 end nil end |
#end_byte ⇒ 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 end byte offset
775 776 777 |
# File 'lib/tree_haver/backends/ffi.rb', line 775 def end_byte Native.ts_node_end_byte(@val) end |
#end_point ⇒ TreeHaver::Point
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 end point
791 792 793 794 795 |
# File 'lib/tree_haver/backends/ffi.rb', line 791 def end_point point = Native.ts_node_end_point(@val) # TSPoint is returned by value as an FFI::Struct with :row and :column fields TreeHaver::Point.new(point[:row], point[:column]) 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 node has error
Returns true if this node or any of its descendants have a syntax error.
This is the FFI equivalent of tree-sitter’s ts_node_has_error.
803 804 805 806 807 |
# File 'lib/tree_haver/backends/ffi.rb', line 803 def has_error? # Explicit boolean conversion ensures consistent behavior across Ruby versions # FFI :bool return type may behave differently on some platforms !!Native.ts_node_has_error(@val) 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 is a MISSING node
A MISSING node represents a token that was expected by the grammar
but was not found in the source. Tree-sitter inserts MISSING nodes
to allow parsing to continue despite syntax errors.
816 817 818 |
# File 'lib/tree_haver/backends/ffi.rb', line 816 def missing? !!Native.ts_node_is_missing(@val) 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
Named nodes represent syntactic constructs (e.g., “pair”, “object”).
Anonymous nodes represent syntax/punctuation (e.g., “{“, “,”).
826 827 828 |
# File 'lib/tree_haver/backends/ffi.rb', line 826 def named? !!Native.ts_node_is_named(@val) end |
#named_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 named child by index
884 885 886 887 888 889 890 891 |
# File 'lib/tree_haver/backends/ffi.rb', line 884 def named_child(index) return if index < 0 || index >= named_child_count child_node = Native.ts_node_named_child(@val, index) return if Native.ts_node_is_null(child_node) Node.new(child_node) end |
#named_child_count ⇒ 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 count of named children
896 897 898 |
# File 'lib/tree_haver/backends/ffi.rb', line 896 def named_child_count Native.ts_node_named_child_count(@val) end |
#named_descendant_for_byte_range(start_byte, end_byte) ⇒ 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.
Find the smallest named descendant that spans the given byte range
917 918 919 920 921 922 |
# File 'lib/tree_haver/backends/ffi.rb', line 917 def named_descendant_for_byte_range(start_byte, end_byte) node = Native.ts_node_named_descendant_for_byte_range(@val, start_byte, end_byte) return if Native.ts_node_is_null(node) Node.new(node) end |
#named_descendant_for_point_range(start_point, end_point) ⇒ 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.
Find the smallest named descendant that spans the given point range
949 950 951 952 953 954 955 956 957 958 959 960 961 962 |
# File 'lib/tree_haver/backends/ffi.rb', line 949 def named_descendant_for_point_range(start_point, end_point) start_pt = Native::TSPoint.new start_pt[:row] = start_point.respond_to?(:row) ? start_point.row : start_point[:row] start_pt[:column] = start_point.respond_to?(:column) ? start_point.column : start_point[:column] end_pt = Native::TSPoint.new end_pt[:row] = end_point.respond_to?(:row) ? end_point.row : end_point[:row] end_pt[:column] = end_point.respond_to?(:column) ? end_point.column : end_point[:column] node = Native.ts_node_named_descendant_for_point_range(@val, start_pt, end_pt) return if Native.ts_node_is_null(node) Node.new(node) end |
#next_named_sibling ⇒ 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 the next named sibling node
863 864 865 866 867 868 |
# File 'lib/tree_haver/backends/ffi.rb', line 863 def next_named_sibling sibling = Native.ts_node_next_named_sibling(@val) return if Native.ts_node_is_null(sibling) Node.new(sibling) end |
#next_sibling ⇒ 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 the next sibling node
843 844 845 846 847 848 |
# File 'lib/tree_haver/backends/ffi.rb', line 843 def next_sibling sibling = Native.ts_node_next_sibling(@val) return if Native.ts_node_is_null(sibling) Node.new(sibling) end |
#parent ⇒ 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 the parent node
833 834 835 836 837 838 |
# File 'lib/tree_haver/backends/ffi.rb', line 833 def parent parent_node = Native.ts_node_parent(@val) return if Native.ts_node_is_null(parent_node) Node.new(parent_node) end |
#prev_named_sibling ⇒ 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 the previous named sibling node
873 874 875 876 877 878 |
# File 'lib/tree_haver/backends/ffi.rb', line 873 def prev_named_sibling sibling = Native.ts_node_prev_named_sibling(@val) return if Native.ts_node_is_null(sibling) Node.new(sibling) end |
#prev_sibling ⇒ 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 the previous sibling node
853 854 855 856 857 858 |
# File 'lib/tree_haver/backends/ffi.rb', line 853 def prev_sibling sibling = Native.ts_node_prev_sibling(@val) return if Native.ts_node_is_null(sibling) Node.new(sibling) end |
#start_byte ⇒ 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 start byte offset
768 769 770 |
# File 'lib/tree_haver/backends/ffi.rb', line 768 def start_byte Native.ts_node_start_byte(@val) end |
#start_point ⇒ TreeHaver::Point
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 start point
782 783 784 785 786 |
# File 'lib/tree_haver/backends/ffi.rb', line 782 def start_point point = Native.ts_node_start_point(@val) # TSPoint is returned by value as an FFI::Struct with :row and :column fields TreeHaver::Point.new(point[:row], point[:column]) end |
#type ⇒ String
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 type name of this node
725 726 727 |
# File 'lib/tree_haver/backends/ffi.rb', line 725 def type Native.ts_node_type(@val) end |