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.
Defined Under Namespace
Classes: CommentAugmenter
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
-
#comment_attachment_for(owner, line_num: nil, **options) ⇒ Ast::Merge::Comment::Attachment
Build a shared comment attachment for an owner.
-
#comment_augmenter(owners: nil, **options) ⇒ CommentAugmenter
Build a shared comment augmenter for this analysis.
-
#comment_capability ⇒ Ast::Merge::Comment::Capability
Get shared comment capability information for this analysis.
-
#comment_node_at(line_num) ⇒ Ast::Merge::Comment::Line?
Get a shared Ast::Merge comment node at a specific line.
-
#comment_nodes ⇒ Array<Ast::Merge::Comment::Line>
Get all comments converted to shared Ast::Merge comment nodes.
-
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Ast::Merge::Comment::Region
Get comments in a line range converted to a shared comment region.
-
#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
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/toml/merge/file_analysis.rb', line 72 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.
45 46 47 |
# File 'lib/toml/merge/file_analysis.rb', line 45 def ast @ast end |
#backend ⇒ Symbol (readonly)
Returns The backend used for parsing (:tree_sitter or :citrus).
51 52 53 |
# File 'lib/toml/merge/file_analysis.rb', line 51 def backend @backend end |
#errors ⇒ Array (readonly)
Returns Parse errors if any.
48 49 50 |
# File 'lib/toml/merge/file_analysis.rb', line 48 def errors @errors end |
Class Method Details
.find_parser_path ⇒ String?
Find the parser library path using TreeHaver::GrammarFinder
57 58 59 |
# File 'lib/toml/merge/file_analysis.rb', line 57 def find_parser_path TreeHaver::GrammarFinder.new(:toml).find_library_path end |
Instance Method Details
#comment_attachment_for(owner, line_num: nil, **options) ⇒ Ast::Merge::Comment::Attachment
Build a shared comment attachment for an owner.
137 138 139 |
# File 'lib/toml/merge/file_analysis.rb', line 137 def (owner, line_num: nil, **) comment_tracker.(owner, line_num: line_num, **) end |
#comment_augmenter(owners: nil, **options) ⇒ CommentAugmenter
Build a shared comment augmenter for this analysis.
146 147 148 |
# File 'lib/toml/merge/file_analysis.rb', line 146 def comment_augmenter(owners: nil, **) CommentAugmenter.new(self, owners: owners || comment_augmenter_default_owners, **) end |
#comment_capability ⇒ Ast::Merge::Comment::Capability
Get shared comment capability information for this analysis.
102 103 104 |
# File 'lib/toml/merge/file_analysis.rb', line 102 def comment_capability @comment_capability ||= build_comment_capability(owner_count: 0) end |
#comment_node_at(line_num) ⇒ Ast::Merge::Comment::Line?
Get a shared Ast::Merge comment node at a specific line.
117 118 119 |
# File 'lib/toml/merge/file_analysis.rb', line 117 def comment_node_at(line_num) comment_tracker.comment_node_at(line_num) end |
#comment_nodes ⇒ Array<Ast::Merge::Comment::Line>
Get all comments converted to shared Ast::Merge comment nodes.
109 110 111 |
# File 'lib/toml/merge/file_analysis.rb', line 109 def comment_nodes comment_tracker.comment_nodes end |
#comment_region_for_range(range, kind:, full_line_only: false) ⇒ Ast::Merge::Comment::Region
Get comments in a line range converted to a shared comment region.
127 128 129 |
# File 'lib/toml/merge/file_analysis.rb', line 127 def comment_region_for_range(range, kind:, full_line_only: false) comment_tracker.comment_region_for_range(range, kind: kind, full_line_only: full_line_only) end |
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough
153 154 155 |
# File 'lib/toml/merge/file_analysis.rb', line 153 def fallthrough_node?(value) value.is_a?(NodeWrapper) || super end |
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree
159 160 161 162 163 164 |
# File 'lib/toml/merge/file_analysis.rb', line 159 def root_node return unless valid? root = @ast.root_node wrap_node(root, 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.
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
# File 'lib/toml/merge/file_analysis.rb', line 199 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 << wrap_node(child, document_root: root) end result end |
#signature_map ⇒ Hash<Array, NodeWrapper>
Get a hash mapping signatures to nodes
168 169 170 |
# File 'lib/toml/merge/file_analysis.rb', line 168 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).
176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/toml/merge/file_analysis.rb', line 176 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 << wrap_node(child, document_root: root) end result end |
#valid? ⇒ Boolean
Check if parse was successful
95 96 97 |
# File 'lib/toml/merge/file_analysis.rb', line 95 def valid? @errors.empty? && !@ast.nil? end |