Class: TreeStand::Node
- Inherits:
-
Object
- Object
- TreeStand::Node
- Extended by:
- Forwardable, T::Sig
- Includes:
- Enumerable
- Defined in:
- lib/tree_stand/node.rb
Overview
Wrapper around a TreeSitter node and provides convient methods that are missing on the original node. This class overrides the ‘method_missing` method to delegate to a nodes named children.
Instance Attribute Summary collapse
- #tree ⇒ TreeStand::Tree readonly
- #ts_node ⇒ TreeSitter::Node readonly
Instance Method Summary collapse
- #==(other) ⇒ Boolean
- #children ⇒ Array<TreeStand::Node>
-
#each(&block) {|child| ... } ⇒ T::Enumerator[TreeStand::Node]
Node includes enumerable so that you can iterate over the child nodes.
-
#error? ⇒ bool
True if the node is an error node.
-
#find_node(query_string) ⇒ TreeStand::Node?
Returns the first captured node that matches the query string or nil if there was no captured node.
-
#find_node!(query_string) ⇒ TreeStand::Node
Like #find_node, except that if no node is found, raises an NodeNotFound error.
- #initialize(tree, ts_node) ⇒ void constructor private
-
#method_missing(method, *args, &block) ⇒ Object
This class overrides the ‘method_missing` method to delegate to the node’s named children.
- #parent ⇒ TreeStand::Node
-
#pretty_print(pp) ⇒ void
Backed by Utils::Printer.
-
#query(query_string) ⇒ Array<Hash{String => TreeStand::Node}>
TreeSitter uses a ‘TreeSitter::Cursor` to iterate over matches by calling `curser#next_match` repeatedly until it returns `nil`.
- #range ⇒ TreeStand::Range
-
#text ⇒ String
A convenience method for getting the text of the node.
-
#type ⇒ Symbol
The type of the node in the tree-sitter grammar.
-
#walk(&block) {|node| ... } ⇒ T::Enumerator[TreeStand::Node]
Backed by Visitors::TreeWalker.
Constructor Details
#initialize(tree, ts_node) ⇒ void
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.
31 32 33 34 35 |
# File 'lib/tree_stand/node.rb', line 31 def initialize(tree, ts_node) @tree = tree @ts_node = ts_node @fields = @ts_node.each_field.to_a.map(&:first) end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(field_name) ⇒ TreeStand::Node #method_missing(method_name, *args, &block) ⇒ Object
This class overrides the ‘method_missing` method to delegate to the node’s named children.
195 196 197 198 |
# File 'lib/tree_stand/node.rb', line 195 def method_missing(method, *args, &block) return super unless @fields.include?(method.to_s) TreeStand::Node.new(@tree, T.unsafe(@ts_node).public_send(method, *args, &block)) end |
Instance Attribute Details
#tree ⇒ TreeStand::Tree (readonly)
25 26 27 |
# File 'lib/tree_stand/node.rb', line 25 def tree @tree end |
#ts_node ⇒ TreeSitter::Node (readonly)
27 28 29 |
# File 'lib/tree_stand/node.rb', line 27 def ts_node @ts_node end |
Instance Method Details
#==(other) ⇒ Boolean
201 202 203 204 205 |
# File 'lib/tree_stand/node.rb', line 201 def ==(other) return false unless other.is_a?(TreeStand::Node) T.must(range == other.range && type == other.type && text == other.text) end |
#children ⇒ Array<TreeStand::Node>
170 |
# File 'lib/tree_stand/node.rb', line 170 def children = to_a |
#each(&block) {|child| ... } ⇒ T::Enumerator[TreeStand::Node]
Node includes enumerable so that you can iterate over the child nodes.
123 124 125 126 127 128 129 130 131 |
# File 'lib/tree_stand/node.rb', line 123 def each(&block) enumerator = Enumerator.new do |yielder| @ts_node.each do |child| yielder << TreeStand::Node.new(@tree, child) end end enumerator.each(&block) if block_given? enumerator end |
#error? ⇒ bool
Returns true if the node is an error node.
18 19 20 21 22 |
# File 'lib/tree_stand/node.rb', line 18 def_delegators( :@ts_node, :type, :error?, ) |
#find_node(query_string) ⇒ TreeStand::Node?
Returns the first captured node that matches the query string or nil if there was no captured node.
80 81 82 |
# File 'lib/tree_stand/node.rb', line 80 def find_node(query_string) query(query_string).first&.values&.first end |
#find_node!(query_string) ⇒ TreeStand::Node
Like #find_node, except that if no node is found, raises an TreeStand::NodeNotFound error.
90 91 92 |
# File 'lib/tree_stand/node.rb', line 90 def find_node!(query_string) find_node(query_string) || raise(TreeStand::NodeNotFound) end |
#parent ⇒ TreeStand::Node
161 162 163 |
# File 'lib/tree_stand/node.rb', line 161 def parent TreeStand::Node.new(@tree, @ts_node.parent) end |
#pretty_print(pp) ⇒ void
This method returns an undefined value.
Backed by Utils::Printer.
212 213 214 |
# File 'lib/tree_stand/node.rb', line 212 def pretty_print(pp) Utils::Printer.new(ralign: 80).print(self, io: pp.output) end |
#query(query_string) ⇒ Array<Hash{String => TreeStand::Node}>
TreeSitter uses a ‘TreeSitter::Cursor` to iterate over matches by calling `curser#next_match` repeatedly until it returns `nil`.
This method does all of that for you and collects all of the matches into an array and each corresponding capture into a hash.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/tree_stand/node.rb', line 54 def query(query_string) ts_query = TreeSitter::Query.new(@tree.parser.ts_language, query_string) ts_cursor = TreeSitter::QueryCursor.exec(ts_query, ts_node) matches = [] while ts_match = ts_cursor.next_match captures = {} ts_match.captures.each do |ts_capture| capture_name = ts_query.capture_name_for_id(ts_capture.index) captures[capture_name] = TreeStand::Node.new(@tree, ts_capture.node) end matches << captures end matches end |
#range ⇒ TreeStand::Range
95 96 97 98 99 100 101 102 |
# File 'lib/tree_stand/node.rb', line 95 def range TreeStand::Range.new( start_byte: @ts_node.start_byte, end_byte: @ts_node.end_byte, start_point: @ts_node.start_point, end_point: @ts_node.end_point, ) end |
#text ⇒ String
A convenience method for getting the text of the node. Each TreeStand::Node wraps the parent #tree and has access to the source document.
175 176 177 |
# File 'lib/tree_stand/node.rb', line 175 def text T.must(@tree.document[@ts_node.start_byte...@ts_node.end_byte]) end |
#type ⇒ Symbol
Returns the type of the node in the tree-sitter grammar.
18 19 20 21 22 |
# File 'lib/tree_stand/node.rb', line 18 def_delegators( :@ts_node, :type, :error?, ) |
#walk(&block) {|node| ... } ⇒ T::Enumerator[TreeStand::Node]
Backed by Visitors::TreeWalker.
146 147 148 149 150 151 152 153 154 |
# File 'lib/tree_stand/node.rb', line 146 def walk(&block) enumerator = Enumerator.new do |yielder| Visitors::TreeWalker.new(self) do |child| yielder << child end.visit end enumerator.each(&block) if block_given? enumerator end |