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_attachment_strategy ⇒ Symbol
- #comment_augmenter(owners: nil, **options) ⇒ Object
-
#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.
-
#comment_support_style ⇒ Ast::Merge::Comment::SupportStyle
Describe how TOML merges currently own and emit comments.
-
#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).
- #ruleset_owner_selector ⇒ Object
- #ruleset_render_family ⇒ Object
-
#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 @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.
152 153 154 155 156 157 158 159 |
# File 'lib/toml/merge/file_analysis.rb', line 152 def (owner, line_num: nil, **) ( owner, tracker_attachment: comment_tracker.(owner, line_num: line_num, **), line_num: line_num, ** ) end |
#comment_attachment_strategy ⇒ Symbol
162 163 164 |
# File 'lib/toml/merge/file_analysis.rb', line 162 def :normalize_tracked_layout_merge end |
#comment_augmenter(owners: nil, **options) ⇒ Object
174 175 176 |
# File 'lib/toml/merge/file_analysis.rb', line 174 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.
132 133 134 |
# File 'lib/toml/merge/file_analysis.rb', line 132 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.
124 125 126 |
# File 'lib/toml/merge/file_analysis.rb', line 124 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.
142 143 144 |
# File 'lib/toml/merge/file_analysis.rb', line 142 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 |
#comment_support_style ⇒ Ast::Merge::Comment::SupportStyle
Describe how TOML merges currently own and emit comments.
Native backends expose comment nodes, but TOML still emits comments through its synthetic merge layer. Source-only backends use the same synthetic ownership model with a source-augmented read path.
113 114 115 116 117 118 119 |
# File 'lib/toml/merge/file_analysis.rb', line 113 def comment_support_style @comment_support_style ||= shared_comment_support_style( source: native_comment_backend? ? @backend : :toml_source, style: :hash_comment, read_strategy: native_comment_backend? ? :native_read_portable_write : :source_augmented_portable_write ) end |
#fallthrough_node?(value) ⇒ Boolean
Override to detect tree-sitter nodes for signature generator fallthrough
181 182 183 |
# File 'lib/toml/merge/file_analysis.rb', line 181 def fallthrough_node?(value) value.is_a?(NodeWrapper) || super end |
#root_node ⇒ NodeWrapper?
Get the root node of the parse tree
187 188 189 190 191 192 |
# File 'lib/toml/merge/file_analysis.rb', line 187 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.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/toml/merge/file_analysis.rb', line 228 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| wrapper = wrap_node(child, document_root: root) next unless wrapper if wrapper.table? || wrapper.array_of_tables? child_line = wrapper.start_line first_table_line = child_line if child_line && (first_table_line.nil? || child_line < first_table_line) next end next unless wrapper.pair? # For Citrus backend, only include pairs before the first table if first_table_line child_line = wrapper.start_line next if child_line && child_line >= first_table_line end result << wrapper end result end |
#ruleset_owner_selector ⇒ Object
166 167 168 |
# File 'lib/toml/merge/file_analysis.rb', line 166 def ruleset_owner_selector :line_bound_statements end |
#ruleset_render_family ⇒ Object
170 171 172 |
# File 'lib/toml/merge/file_analysis.rb', line 170 def ruleset_render_family :toml_pairs_and_tables end |
#signature_map ⇒ Hash<Array, NodeWrapper>
Get a hash mapping signatures to nodes
196 197 198 |
# File 'lib/toml/merge/file_analysis.rb', line 196 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).
204 205 206 207 208 209 210 211 212 213 214 215 216 217 |
# File 'lib/toml/merge/file_analysis.rb', line 204 def tables return [] unless valid? result = [] root = @ast.root_node root.each do |child| wrapper = wrap_node(child, document_root: root) next unless wrapper next unless wrapper.table? || wrapper.array_of_tables? result << wrapper 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 |