Class: Toml::Merge::FileAnalysis
- Inherits:
-
Object
- Object
- Toml::Merge::FileAnalysis
- Includes:
- Ast::Merge::FileAnalyzable
- Defined in:
- lib/toml/merge/file_analysis.rb
Overview
Analyzes TOML file structure, extracting statements for merging.
This is the main analysis class that prepares TOML content for merging.
Instance Attribute Summary collapse
-
#ast ⇒ TreeHaver::Tree?
readonly
Parsed AST.
-
#backend ⇒ Symbol
readonly
The backend used for parsing (:tree_sitter or :citrus).
-
#errors ⇒ Array
readonly
Parse errors if any.
Class Method Summary collapse
-
.find_parser_path ⇒ String?
Find the parser library path using TreeHaver::GrammarFinder.
Instance Method Summary collapse
-
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough.
-
#initialize(source, signature_generator: nil, parser_path: nil, **options) ⇒ FileAnalysis
constructor
Initialize file analysis.
-
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree.
-
#root_pairs ⇒ Array<NodeWrapper>
Get all top-level key-value pairs (not in tables).
-
#signature_map ⇒ Hash<Array, NodeWrapper>
Get a hash mapping signatures to nodes.
-
#tables ⇒ Array<NodeWrapper>
Get all top-level tables (sections) in the TOML document Uses NodeTypeNormalizer for backend-agnostic type checking.
-
#valid? ⇒ Boolean
Check if parse was successful.
Constructor Details
#initialize(source, signature_generator: nil, parser_path: nil, **options) ⇒ FileAnalysis
To force a specific backend, use TreeHaver.with_backend or TREE_HAVER_BACKEND env var.
TreeHaver handles backend selection, auto-detection, and fallback.
Initialize file analysis
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/toml/merge/file_analysis.rb', line 43 def initialize(source, signature_generator: nil, parser_path: nil, **) @source = source @lines = source.lines.map(&:chomp) @signature_generator = signature_generator @parser_path = parser_path || self.class.find_parser_path @errors = [] @backend = :tree_sitter # Default, will be updated during parsing # **options captures any additional parameters (e.g., freeze_token, node_typing) for forward compatibility # Parse the TOML DebugLogger.time("FileAnalysis#parse_toml") { parse_toml } @statements = integrate_nodes DebugLogger.debug("FileAnalysis initialized", { signature_generator: signature_generator ? "custom" : "default", statements_count: @statements.size, valid: valid?, }) end |
Instance Attribute Details
#ast ⇒ TreeHaver::Tree? (readonly)
Returns Parsed AST.
16 17 18 |
# File 'lib/toml/merge/file_analysis.rb', line 16 def ast @ast end |
#backend ⇒ Symbol (readonly)
Returns The backend used for parsing (:tree_sitter or :citrus).
22 23 24 |
# File 'lib/toml/merge/file_analysis.rb', line 22 def backend @backend end |
#errors ⇒ Array (readonly)
Returns Parse errors if any.
19 20 21 |
# File 'lib/toml/merge/file_analysis.rb', line 19 def errors @errors end |
Class Method Details
.find_parser_path ⇒ String?
Find the parser library path using TreeHaver::GrammarFinder
28 29 30 |
# File 'lib/toml/merge/file_analysis.rb', line 28 def find_parser_path TreeHaver::GrammarFinder.new(:toml).find_library_path end |
Instance Method Details
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough
73 74 75 |
# File 'lib/toml/merge/file_analysis.rb', line 73 def fallthrough_node?(value) value.is_a?(NodeWrapper) || super end |
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/toml/merge/file_analysis.rb', line 79 def root_node return unless valid? root = @ast.root_node NodeWrapper.new( root, lines: @lines, source: @source, backend: @backend, document_root: root, ) end |
#root_pairs ⇒ Array<NodeWrapper>
Get all top-level key-value pairs (not in tables)
For tree-sitter backend: pairs are nested under tables, so root-level
pairs are direct children of the document.
For Citrus backend: ALL pairs are siblings at document level (flat structure).
We must filter to only include pairs that appear BEFORE the first table header.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/toml/merge/file_analysis.rb', line 131 def root_pairs return [] unless valid? result = [] root = @ast.root_node # Find the line number of the first table (if any) first_table_line = nil root.each do |child| canonical_type = NodeTypeNormalizer.canonical_type(child.type, @backend) if NodeTypeNormalizer.table_type?(canonical_type) child_line = child.respond_to?(:start_point) ? child.start_point.row + 1 : nil if child_line && (first_table_line.nil? || child_line < first_table_line) first_table_line = child_line end end end root.each do |child| canonical_type = NodeTypeNormalizer.canonical_type(child.type, @backend) next unless canonical_type == :pair # For Citrus backend, only include pairs before the first table if first_table_line child_line = child.respond_to?(:start_point) ? child.start_point.row + 1 : nil next if child_line && child_line >= first_table_line end result << NodeWrapper.new( child, lines: @lines, source: @source, backend: @backend, document_root: root, ) end result end |
#signature_map ⇒ Hash<Array, NodeWrapper>
Get a hash mapping signatures to nodes
94 95 96 |
# File 'lib/toml/merge/file_analysis.rb', line 94 def signature_map @signature_map ||= build_signature_map end |
#tables ⇒ Array<NodeWrapper>
Get all top-level tables (sections) in the TOML document
Uses NodeTypeNormalizer for backend-agnostic type checking.
Passes document_root to enable Citrus backend normalization (pairs as siblings).
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/toml/merge/file_analysis.rb', line 102 def tables return [] unless valid? result = [] root = @ast.root_node root.each do |child| canonical_type = NodeTypeNormalizer.canonical_type(child.type, @backend) next unless NodeTypeNormalizer.table_type?(canonical_type) result << NodeWrapper.new( child, lines: @lines, source: @source, backend: @backend, document_root: root, ) end result end |
#valid? ⇒ Boolean
Check if parse was successful
66 67 68 |
# File 'lib/toml/merge/file_analysis.rb', line 66 def valid? @errors.empty? && !@ast.nil? end |