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.
Constant Summary collapse
- THINLY_REMAPPED_METHODS =
These are methods defined in TreeStand::Node but map to something in TreeSitter::Node, because we want a more idiomatic API.
{ '[]': :[], fetch: :fetch, field: :child_by_field_name, next: :next_sibling, prev: :prev_sibling, next_named: :next_named_sibling, prev_named: :prev_named_sibling, field_names: :fields, }.freeze
- THINLY_WRAPPED_METHODS =
These are methods from TreeSitter that are thinly wrapped to create TreeStand::Node instead.
( %i[ child named_child parent ] + THINLY_REMAPPED_METHODS.keys ).freeze
Instance Attribute Summary collapse
-
#tree ⇒ Object
readonly
Returns the value of attribute tree.
-
#ts_node ⇒ Object
readonly
Returns the value of attribute ts_node.
Instance Method Summary collapse
- #==(other) ⇒ Object
-
#changed? ⇒ Boolean
True if a syntax node has been edited.
-
#child_count ⇒ Integer
The number of child nodes.
- #children ⇒ Object
- #each(&block) ⇒ Object
- #each_field(&block) ⇒ Object (also: #fields)
- #each_named(&block) ⇒ Object (also: #named)
-
#error? ⇒ bool
True if the node is an error node.
-
#extra? ⇒ Boolean
True if the node is extra (e.g. comments).
- #find_node(query_string) ⇒ Object
- #find_node!(query_string) ⇒ Object
-
#has_error? ⇒ Boolean
True if the node is a syntax error or contains any syntax errors.
-
#initialize(tree, ts_node) ⇒ Node
constructor
A new instance of Node.
-
#method_missing(method, *args, **kwargs, &block) ⇒ Object
This class overrides the ‘method_missing` method to delegate to the node’s named children.
-
#missing? ⇒ Boolean
True if the parser inserted that node to recover from error.
-
#named? ⇒ Boolean
True if the node is not a literal in the grammar.
-
#named_child_count ⇒ Integer
The number of named children.
- #pretty_print(pp) ⇒ Object
- #query(query_string) ⇒ Object
- #range ⇒ Object
-
#sexpr ⇒ String
A pretty-printed sexpr.
- #text ⇒ Object
-
#type ⇒ Symbol
The type of the node in the tree-sitter grammar.
- #walk(&block) ⇒ Object
Constructor Details
#initialize(tree, ts_node) ⇒ Node
Returns a new instance of Node.
79 80 81 82 |
# File 'lib/tree_stand/node.rb', line 79 def initialize(tree, ts_node) @tree = tree @ts_node = ts_node 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.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
# File 'lib/tree_stand/node.rb', line 293 def method_missing(method, *args, **kwargs, &block) if thinly_wrapped?(method) from( T.unsafe(@ts_node) .public_send( THINLY_REMAPPED_METHODS[method] || method, *args, **kwargs, &block ), ) else super end end |
Instance Attribute Details
#tree ⇒ Object (readonly)
Returns the value of attribute tree.
72 73 74 |
# File 'lib/tree_stand/node.rb', line 72 def tree @tree end |
#ts_node ⇒ Object (readonly)
Returns the value of attribute ts_node.
75 76 77 |
# File 'lib/tree_stand/node.rb', line 75 def ts_node @ts_node end |
Instance Method Details
#==(other) ⇒ Object
310 311 312 313 314 |
# File 'lib/tree_stand/node.rb', line 310 def ==(other) return false unless other.is_a?(TreeStand::Node) T.must(range == other.range && type == other.type && text == other.text) end |
#changed? ⇒ Boolean
Returns true if a syntax node has been edited.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#child_count ⇒ Integer
Returns the number of child nodes.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#children ⇒ Object
268 |
# File 'lib/tree_stand/node.rb', line 268 def children = to_a |
#each(&block) ⇒ Object
162 163 164 165 166 167 168 169 170 |
# File 'lib/tree_stand/node.rb', line 162 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 |
#each_field(&block) ⇒ Object Also known as: fields
222 223 224 225 226 227 228 229 230 |
# File 'lib/tree_stand/node.rb', line 222 def each_field(&block) enumerator = Enumerator.new do |yielder| @ts_node.each_field do |field, child| yielder << [field.to_sym, TreeStand::Node.new(@tree, child)] end end enumerator.each(&block) if block_given? enumerator end |
#each_named(&block) ⇒ Object Also known as: named
190 191 192 193 194 195 196 197 198 |
# File 'lib/tree_stand/node.rb', line 190 def each_named(&block) enumerator = Enumerator.new do |yielder| @ts_node.each_named 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.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#extra? ⇒ Boolean
Returns true if the node is extra (e.g. comments).
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#find_node(query_string) ⇒ Object
119 120 121 |
# File 'lib/tree_stand/node.rb', line 119 def find_node(query_string) query(query_string).first&.values&.first end |
#find_node!(query_string) ⇒ Object
129 130 131 |
# File 'lib/tree_stand/node.rb', line 129 def find_node!(query_string) find_node(query_string) || raise(TreeStand::NodeNotFound) end |
#has_error? ⇒ Boolean
Returns true if the node is a syntax error or contains any syntax errors.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#missing? ⇒ Boolean
Returns true if the parser inserted that node to recover from error.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#named? ⇒ Boolean
Returns true if the node is not a literal in the grammar.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#named_child_count ⇒ Integer
Returns the number of named children.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#pretty_print(pp) ⇒ Object
318 319 320 |
# File 'lib/tree_stand/node.rb', line 318 def pretty_print(pp) pp.output << sexpr(source: text) end |
#query(query_string) ⇒ Object
101 102 103 104 105 106 107 108 |
# File 'lib/tree_stand/node.rb', line 101 def query(query_string) ts_query = TreeSitter::Query.new(@tree.parser.ts_language, query_string) TreeSitter::QueryCursor .new .matches(ts_query, @tree.ts_tree.root_node, @tree.document) .each_capture_hash .map { |h| h.transform_values! { |n| TreeStand::Node.new(@tree, n) } } end |
#range ⇒ Object
134 135 136 137 138 139 140 141 |
# File 'lib/tree_stand/node.rb', line 134 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 |
#sexpr ⇒ String
Returns a pretty-printed sexpr.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#text ⇒ Object
273 274 275 |
# File 'lib/tree_stand/node.rb', line 273 def text T.must(@tree.document.byteslice(@ts_node.start_byte...@ts_node.end_byte)) end |
#type ⇒ Symbol
Returns the type of the node in the tree-sitter grammar.
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/tree_stand/node.rb', line 34 def_delegators( :@ts_node, :changed?, :child_count, :error?, :extra?, :has_error?, :missing?, :named?, :named_child_count, :sexpr, :type, ) |
#walk(&block) ⇒ Object
253 254 255 256 257 258 259 260 261 |
# File 'lib/tree_stand/node.rb', line 253 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 |