Class: TreeHaver::Backends::Citrus::Node Private
- Inherits:
-
TreeHaver::Base::Node
- Object
- TreeHaver::Base::Node
- TreeHaver::Backends::Citrus::Node
- Defined in:
- lib/tree_haver/backends/citrus.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.
Citrus node wrapper
Wraps Citrus::Match objects to provide tree-sitter-compatible node API.
Citrus::Match provides:
- events[0]: rule name (Symbol) - used as type
- offset: byte position
- length: byte length
- string: matched text
- matches: child matches
- captures: named groups
Inherits from Base::Node to get shared methods like #first_child, #last_child,
#to_s, #inspect, #==, #<=>, #source_position, #start_line, #end_line, etc.
Language-specific helpers can be mixed in for convenience:
require “tree_haver/backends/citrus/toml_helpers”
TreeHaver::Backends::Citrus::Node.include(TreeHaver::Backends::Citrus::TomlHelpers)
Instance Attribute Summary collapse
-
#match ⇒ Object
readonly
private
Attributes inherited from TreeHaver::Base::Node
Instance Method Summary collapse
-
#child(index) ⇒ Object
private
Override child to handle negative indices properly.
-
#child_count ⇒ Object
private
Override child_count for efficiency (avoid building full children array).
-
#children ⇒ Object
private
-
#end_byte ⇒ Object
private
-
#end_point ⇒ Object
private
Override end_point to calculate from source.
-
#initialize(match, source) ⇒ Node
constructor
private
A new instance of Node.
-
#start_byte ⇒ Object
private
-
#start_point ⇒ Object
private
Override start_point to calculate from source.
-
#structural? ⇒ Boolean
private
Check if this node represents a structural element vs a terminal/token.
-
#text ⇒ Object
private
Override text to use Citrus match string.
-
#type ⇒ String
private
Get node type from Citrus rule name.
Methods inherited from TreeHaver::Base::Node
#<=>, #==, #child_by_field_name, #each, #end_line, #first_child, #has_error?, #inspect, #last_child, #missing?, #named?, #next_sibling, #parent, #prev_sibling, #source_position, #start_line, #to_s
Constructor Details
#initialize(match, 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.
318 319 320 321 |
# File 'lib/tree_haver/backends/citrus.rb', line 318 def initialize(match, source) @match = match super(match, source: source) end |
Instance Attribute Details
#match ⇒ Object (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.
316 317 318 |
# File 'lib/tree_haver/backends/citrus.rb', line 316 def match @match end |
Instance Method Details
#child(index) ⇒ 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.
Override child to handle negative indices properly
380 381 382 383 384 385 386 |
# File 'lib/tree_haver/backends/citrus.rb', line 380 def child(index) return if index.negative? return unless @match.respond_to?(:matches) return if index >= @match.matches.size Node.new(@match.matches[index], @source) end |
#child_count ⇒ 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.
Override child_count for efficiency (avoid building full children array)
375 376 377 |
# File 'lib/tree_haver/backends/citrus.rb', line 375 def child_count @match.respond_to?(:matches) ? @match.matches.size : 0 end |
#children ⇒ 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.
352 353 354 355 |
# File 'lib/tree_haver/backends/citrus.rb', line 352 def children return [] unless @match.respond_to?(:matches) @match.matches.map { |m| Node.new(m, @source) } end |
#end_byte ⇒ 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.
348 349 350 |
# File 'lib/tree_haver/backends/citrus.rb', line 348 def end_byte @match.offset + @match.length end |
#end_point ⇒ 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.
Override end_point to calculate from source
365 366 367 |
# File 'lib/tree_haver/backends/citrus.rb', line 365 def end_point calculate_point(@match.offset + @match.length) end |
#start_byte ⇒ 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.
344 345 346 |
# File 'lib/tree_haver/backends/citrus.rb', line 344 def start_byte @match.offset end |
#start_point ⇒ 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.
Override start_point to calculate from source
360 361 362 |
# File 'lib/tree_haver/backends/citrus.rb', line 360 def start_point calculate_point(@match.offset) 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 node represents a structural element vs a terminal/token
Uses Citrus grammar’s terminal? method to determine if this is
a structural rule (like “table”, “keyvalue”) vs a terminal token
(like “[”, “=”, whitespace).
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
# File 'lib/tree_haver/backends/citrus.rb', line 395 def structural? return false unless @match.respond_to?(:events) return false if @match.events.empty? first_event = @match.events.first # Check if event has terminal? method (Citrus rule object) if first_event.respond_to?(:terminal?) return !first_event.terminal? end # For Symbol events, try to look up in grammar if first_event.is_a?(Symbol) && @match.respond_to?(:grammar) grammar = @match.grammar if grammar.respond_to?(:rules) && grammar.rules.key?(first_event) rule = grammar.rules[first_event] return !rule.terminal? if rule.respond_to?(:terminal?) end end # Default: assume structural if not a simple string/regex terminal true end |
#text ⇒ 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.
Override text to use Citrus match string
370 371 372 |
# File 'lib/tree_haver/backends/citrus.rb', line 370 def text @match.string 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 node type from Citrus rule name
Uses Citrus grammar introspection to dynamically determine node types.
Works with any Citrus grammar without language-specific knowledge.
Strategy:
- Check if first event has a .name method (returns Symbol) - use that
- If first event is a Symbol directly - use that
- For compound rules (Repeat, Choice), recurse into first match
336 337 338 339 340 341 342 |
# File 'lib/tree_haver/backends/citrus.rb', line 336 def type return "unknown" unless @match.respond_to?(:events) return "unknown" unless @match.events.is_a?(Array) return "unknown" if @match.events.empty? extract_type_from_event(@match.events.first) end |