Class: Psych::Merge::FileAnalysis
- Inherits:
-
Object
- Object
- Psych::Merge::FileAnalysis
- Includes:
- Ast::Merge::FileAnalyzable
- Defined in:
- lib/psych/merge/file_analysis.rb
Overview
Analyzes YAML file structure, extracting statements, comments, and freeze blocks. This is the main analysis class that prepares YAML content for merging.
Constant Summary collapse
- DEFAULT_FREEZE_TOKEN =
Default freeze token for identifying freeze blocks
'psych-merge'
Instance Attribute Summary collapse
-
#ast ⇒ Psych::Nodes::Stream?
readonly
Parsed AST.
-
#comment_tracker ⇒ CommentTracker
readonly
Comment tracker for this file.
-
#errors ⇒ Array
readonly
Parse errors if any.
-
#tree ⇒ TreeHaver::Backends::Psych::Tree?
readonly
TreeHaver tree (for future use).
Instance Method Summary collapse
-
#comment_attachment_for(owner, line_num: nil, **options) ⇒ Ast::Merge::Comment::Attachment
Build a passive shared comment attachment for an owner.
- #comment_attachment_strategy ⇒ Symbol
-
#comment_augmenter(owners: nil, **options) ⇒ Ast::Merge::Comment::Augmenter
Build a passive 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.
-
#comment_support_style ⇒ Ast::Merge::Comment::SupportStyle
Describe how Psych merges currently own and emit comments.
-
#fallthrough_node?(value) ⇒ Boolean
Override to detect Psych nodes for signature generator fallthrough.
-
#freeze_block_at(line_num) ⇒ FreezeNode?
Get the freeze block containing the given line.
-
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block.
-
#initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, **_options) ⇒ FileAnalysis
constructor
Initialize file analysis.
-
#root_mapping_entries ⇒ Array<Array(NodeWrapper, NodeWrapper)>
Get mapping entries from the root document.
-
#root_node ⇒ NodeWrapper?
Get the root node of the first document.
- #ruleset_match_key ⇒ Object
- #ruleset_owner_selector ⇒ Object
- #ruleset_render_family ⇒ Object
-
#valid? ⇒ Boolean
Check if parse was successful.
Constructor Details
#initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, **_options) ⇒ FileAnalysis
Initialize file analysis
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/psych/merge/file_analysis.rb', line 37 def initialize(source, freeze_token: DEFAULT_FREEZE_TOKEN, signature_generator: nil, **) @source = source @lines = source.lines.map(&:chomp) @freeze_token = freeze_token @signature_generator = signature_generator @errors = [] # **options captures any additional parameters (e.g., node_typing) for forward compatibility # Initialize comment tracking @comment_tracker = CommentTracker.new(source) # Parse the YAML DebugLogger.time('FileAnalysis#parse_yaml') { parse_yaml } # Extract freeze blocks and integrate with nodes @freeze_blocks = extract_freeze_blocks @statements = integrate_nodes_and_freeze_blocks DebugLogger.debug('FileAnalysis initialized', { signature_generator: signature_generator ? 'custom' : 'default', statements_count: @statements.size, freeze_blocks: @freeze_blocks.size, valid: valid? }) end |
Instance Attribute Details
#ast ⇒ Psych::Nodes::Stream? (readonly)
Returns Parsed AST.
23 24 25 |
# File 'lib/psych/merge/file_analysis.rb', line 23 def ast @ast end |
#comment_tracker ⇒ CommentTracker (readonly)
Returns Comment tracker for this file.
20 21 22 |
# File 'lib/psych/merge/file_analysis.rb', line 20 def comment_tracker @comment_tracker end |
#errors ⇒ Array (readonly)
Returns Parse errors if any.
29 30 31 |
# File 'lib/psych/merge/file_analysis.rb', line 29 def errors @errors end |
#tree ⇒ TreeHaver::Backends::Psych::Tree? (readonly)
Returns TreeHaver tree (for future use).
26 27 28 |
# File 'lib/psych/merge/file_analysis.rb', line 26 def tree @tree end |
Instance Method Details
#comment_attachment_for(owner, line_num: nil, **options) ⇒ Ast::Merge::Comment::Attachment
Build a passive shared comment attachment for an owner.
203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/psych/merge/file_analysis.rb', line 203 def (owner, line_num: nil, **) = if owner.is_a?(MappingEntry) && .empty? (owner) else @comment_tracker.(owner, line_num: line_num, **) end ( owner, tracker_attachment: , line_num: line_num, ** ) end |
#comment_attachment_strategy ⇒ Symbol
219 220 221 |
# File 'lib/psych/merge/file_analysis.rb', line 219 def :tracker_layout_merge end |
#comment_augmenter(owners: nil, **options) ⇒ Ast::Merge::Comment::Augmenter
Build a passive shared comment augmenter for this analysis.
124 125 126 127 128 129 |
# File 'lib/psych/merge/file_analysis.rb', line 124 def comment_augmenter(owners: nil, **) comment_tracker.augment( owners: owners || comment_augmenter_default_owners, ** ) end |
#comment_capability ⇒ Ast::Merge::Comment::Capability
Get shared comment capability information for this analysis.
72 73 74 |
# File 'lib/psych/merge/file_analysis.rb', line 72 def comment_capability @comment_capability ||= comment_tracker.augment(owners: []).capability end |
#comment_node_at(line_num) ⇒ Ast::Merge::Comment::Line?
Get a shared Ast::Merge comment node at a specific line.
101 102 103 |
# File 'lib/psych/merge/file_analysis.rb', line 101 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.
93 94 95 |
# File 'lib/psych/merge/file_analysis.rb', line 93 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.
111 112 113 114 115 116 117 |
# File 'lib/psych/merge/file_analysis.rb', line 111 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 Psych merges currently own and emit comments.
YAML comment handling is source-augmented and emitted through the synthetic merge layer rather than native AST mutation.
82 83 84 85 86 87 88 |
# File 'lib/psych/merge/file_analysis.rb', line 82 def comment_support_style @comment_support_style ||= shared_comment_support_style( source: :psych_source, style: :hash_comment, read_strategy: :source_augmented_portable_write ) end |
#fallthrough_node?(value) ⇒ Boolean
Override to detect Psych nodes for signature generator fallthrough
164 165 166 |
# File 'lib/psych/merge/file_analysis.rb', line 164 def fallthrough_node?(value) value.is_a?(NodeWrapper) || value.is_a?(Ast::Merge::FreezeNodeBase) || value.is_a?(MappingEntry) || super end |
#freeze_block_at(line_num) ⇒ FreezeNode?
Get the freeze block containing the given line.
NOTE: This method intentionally does NOT call super or use the base
freeze_blocks method. The base implementation derives freeze blocks from
statements.select { |n| n.is_a?(Freezable) }, but during initialization
@freeze_blocks is extracted BEFORE @statements is populated (see
integrate_nodes_and_freeze_blocks). This method is called during that
integration process, so we must use @freeze_blocks directly.
157 158 159 |
# File 'lib/psych/merge/file_analysis.rb', line 157 def freeze_block_at(line_num) @freeze_blocks.find { |fb| fb.location.cover?(line_num) } end |
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block.
NOTE: This method intentionally does NOT call super or use the base
freeze_blocks method. The base implementation derives freeze blocks from
statements.select { |n| n.is_a?(Freezable) }, but during initialization
@freeze_blocks is extracted BEFORE @statements is populated (see
integrate_nodes_and_freeze_blocks). This method is called during that
integration process, so we must use @freeze_blocks directly.
142 143 144 |
# File 'lib/psych/merge/file_analysis.rb', line 142 def in_freeze_block?(line_num) @freeze_blocks.any? { |fb| fb.location.cover?(line_num) } end |
#root_mapping_entries ⇒ Array<Array(NodeWrapper, NodeWrapper)>
Get mapping entries from the root document
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/psych/merge/file_analysis.rb', line 170 def root_mapping_entries return [] unless valid? && @ast.children&.any? doc = @ast.children.first return [] unless doc.is_a?(::Psych::Nodes::Document) root = doc.children&.first return [] unless root.is_a?(::Psych::Nodes::Mapping) root_wrapper = wrap_root_node(root) root_wrapper.mapping_entries(comment_tracker: @comment_tracker) end |
#root_node ⇒ NodeWrapper?
Get the root node of the first document
185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/psych/merge/file_analysis.rb', line 185 def root_node return unless valid? && @ast.children&.any? doc = @ast.children.first return unless doc.is_a?(::Psych::Nodes::Document) root = doc.children&.first return unless root wrap_root_node(root) end |
#ruleset_match_key ⇒ Object
227 228 229 |
# File 'lib/psych/merge/file_analysis.rb', line 227 def ruleset_match_key :key_name end |
#ruleset_owner_selector ⇒ Object
223 224 225 |
# File 'lib/psych/merge/file_analysis.rb', line 223 def ruleset_owner_selector :mapping_entries end |
#ruleset_render_family ⇒ Object
231 232 233 |
# File 'lib/psych/merge/file_analysis.rb', line 231 def ruleset_render_family :key_value_colon end |
#valid? ⇒ Boolean
Check if parse was successful
65 66 67 |
# File 'lib/psych/merge/file_analysis.rb', line 65 def valid? @errors.empty? && !@ast.nil? end |