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.
319 320 321 322 |
# File 'lib/tree_haver/backends/citrus.rb', line 319 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.
317 318 319 |
# File 'lib/tree_haver/backends/citrus.rb', line 317 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
381 382 383 384 385 386 387 |
# File 'lib/tree_haver/backends/citrus.rb', line 381 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)
376 377 378 |
# File 'lib/tree_haver/backends/citrus.rb', line 376 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.
353 354 355 356 |
# File 'lib/tree_haver/backends/citrus.rb', line 353 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.
349 350 351 |
# File 'lib/tree_haver/backends/citrus.rb', line 349 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
366 367 368 |
# File 'lib/tree_haver/backends/citrus.rb', line 366 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.
345 346 347 |
# File 'lib/tree_haver/backends/citrus.rb', line 345 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
361 362 363 |
# File 'lib/tree_haver/backends/citrus.rb', line 361 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).
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 |
# File 'lib/tree_haver/backends/citrus.rb', line 396 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
371 372 373 |
# File 'lib/tree_haver/backends/citrus.rb', line 371 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
337 338 339 340 341 342 343 |
# File 'lib/tree_haver/backends/citrus.rb', line 337 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 |