Class: Prism::Merge::FileAnalysis
- Inherits:
-
Object
- Object
- Prism::Merge::FileAnalysis
- Defined in:
- lib/prism/merge/file_analysis.rb
Overview
Comprehensive metadata capture for a Ruby file being merged. Tracks Prism parse result, line-to-node mapping, comment associations, structural signatures, and sequential anchor lines for merge alignment.
Constant Summary collapse
- FREEZE_START =
Regex pattern for freeze block start marker. Matches comments like: # kettle-dev:freeze Case-insensitive to allow variations like FREEZE or Freeze
/#\s*kettle-dev:freeze/i- FREEZE_END =
Regex pattern for freeze block end marker. Matches comments like: # kettle-dev:unfreeze Case-insensitive to allow variations like UNFREEZE or Unfreeze
/#\s*kettle-dev:unfreeze/i- FREEZE_BLOCK =
Combined regex pattern for matching complete freeze blocks. Captures content between freeze/unfreeze markers (inclusive). Used to identify sections that should always be preserved from destination.
Regexp.new("(#{FREEZE_START.source}).*?(#{FREEZE_END.source})", Regexp::IGNORECASE | Regexp::MULTILINE)
Instance Attribute Summary collapse
-
#content ⇒ Object
readonly
Returns the value of attribute content.
-
#freeze_blocks ⇒ Object
readonly
Returns the value of attribute freeze_blocks.
-
#lines ⇒ Object
readonly
Returns the value of attribute lines.
-
#parse_result ⇒ Object
readonly
Returns the value of attribute parse_result.
-
#statements ⇒ Object
readonly
Returns the value of attribute statements.
Instance Method Summary collapse
-
#comment_map ⇒ Hash<Integer, Array<Prism::Comment>>
Get comment map by line number.
-
#extract_freeze_blocks ⇒ Array<Hash>
Extract freeze block information.
-
#extract_statements ⇒ Array<Prism::Node>
Get all top-level statement nodes.
-
#freeze_block_at(line_num) ⇒ Hash?
Get the freeze block containing the given line, if any.
-
#generate_signature(node) ⇒ Array?
Generate signature for a node.
-
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block.
-
#initialize(content, signature_generator: nil) ⇒ FileAnalysis
constructor
A new instance of FileAnalysis.
-
#line_at(line_num) ⇒ String?
Get raw line content.
-
#line_to_node_map ⇒ Hash<Integer, Array<Prism::Node>>
Build mapping from line numbers to AST nodes.
-
#node_to_line_map ⇒ Hash<Prism::Node, Range>
Build mapping from nodes to line ranges.
-
#nodes_with_comments ⇒ Array<Hash>
Get nodes with their associated comments and metadata.
-
#normalized_line(line_num) ⇒ String?
Get normalized line content (stripped).
-
#signature_at(index) ⇒ Array?
Get structural signature for a statement at given index.
-
#valid? ⇒ Boolean
Check if parsing was successful.
Constructor Details
#initialize(content, signature_generator: nil) ⇒ FileAnalysis
Returns a new instance of FileAnalysis.
35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/prism/merge/file_analysis.rb', line 35 def initialize(content, signature_generator: nil) @content = content @lines = content.lines @parse_result = Prism.parse(content) @statements = extract_statements @freeze_blocks = extract_freeze_blocks @signature_generator = signature_generator @line_to_node_map = nil @node_to_line_map = nil @comment_map = nil end |
Instance Attribute Details
#content ⇒ Object (readonly)
Returns the value of attribute content.
31 32 33 |
# File 'lib/prism/merge/file_analysis.rb', line 31 def content @content end |
#freeze_blocks ⇒ Object (readonly)
Returns the value of attribute freeze_blocks.
31 32 33 |
# File 'lib/prism/merge/file_analysis.rb', line 31 def freeze_blocks @freeze_blocks end |
#lines ⇒ Object (readonly)
Returns the value of attribute lines.
31 32 33 |
# File 'lib/prism/merge/file_analysis.rb', line 31 def lines @lines end |
#parse_result ⇒ Object (readonly)
Returns the value of attribute parse_result.
31 32 33 |
# File 'lib/prism/merge/file_analysis.rb', line 31 def parse_result @parse_result end |
#statements ⇒ Object (readonly)
Returns the value of attribute statements.
31 32 33 |
# File 'lib/prism/merge/file_analysis.rb', line 31 def statements @statements end |
Instance Method Details
#comment_map ⇒ Hash<Integer, Array<Prism::Comment>>
Get comment map by line number
114 115 116 |
# File 'lib/prism/merge/file_analysis.rb', line 114 def comment_map @comment_map ||= build_comment_map end |
#extract_freeze_blocks ⇒ Array<Hash>
Extract freeze block information
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/prism/merge/file_analysis.rb', line 69 def extract_freeze_blocks return [] unless content.match?(FREEZE_START) blocks = [] content.to_enum(:scan, FREEZE_BLOCK).each do match = Regexp.last_match next unless match start_idx = match.begin(0) end_idx = match.end(0) segment = match[0] start_line = content[0...start_idx].count("\n") + 1 end_line = content[0...end_idx].count("\n") + 1 blocks << { range: start_idx...end_idx, line_range: start_line..end_line, text: segment, start_marker: segment&.lines&.first&.strip, } end blocks end |
#extract_statements ⇒ Array<Prism::Node>
Get all top-level statement nodes
55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/prism/merge/file_analysis.rb', line 55 def extract_statements return [] unless valid? body = @parse_result.value.statements return [] unless body if body.is_a?(Prism::StatementsNode) body.body.compact else [body].compact end end |
#freeze_block_at(line_num) ⇒ Hash?
Get the freeze block containing the given line, if any
147 148 149 |
# File 'lib/prism/merge/file_analysis.rb', line 147 def freeze_block_at(line_num) freeze_blocks.find { |block| block[:line_range].cover?(line_num) } end |
#generate_signature(node) ⇒ Array?
Generate signature for a node
129 130 131 132 133 134 135 |
# File 'lib/prism/merge/file_analysis.rb', line 129 def generate_signature(node) if @signature_generator @signature_generator.call(node) else default_signature(node) end end |
#in_freeze_block?(line_num) ⇒ Boolean
Check if a line is within a freeze block
140 141 142 |
# File 'lib/prism/merge/file_analysis.rb', line 140 def in_freeze_block?(line_num) freeze_blocks.any? { |block| block[:line_range].cover?(line_num) } end |
#line_at(line_num) ⇒ String?
Get raw line content
162 163 164 165 |
# File 'lib/prism/merge/file_analysis.rb', line 162 def line_at(line_num) return if line_num < 1 || line_num > lines.length lines[line_num - 1] end |
#line_to_node_map ⇒ Hash<Integer, Array<Prism::Node>>
Build mapping from line numbers to AST nodes
96 97 98 |
# File 'lib/prism/merge/file_analysis.rb', line 96 def line_to_node_map @line_to_node_map ||= build_line_to_node_map end |
#node_to_line_map ⇒ Hash<Prism::Node, Range>
Build mapping from nodes to line ranges
102 103 104 |
# File 'lib/prism/merge/file_analysis.rb', line 102 def node_to_line_map @node_to_line_map ||= build_node_to_line_map end |
#nodes_with_comments ⇒ Array<Hash>
Get nodes with their associated comments and metadata
108 109 110 |
# File 'lib/prism/merge/file_analysis.rb', line 108 def nodes_with_comments @nodes_with_comments ||= extract_nodes_with_comments end |
#normalized_line(line_num) ⇒ String?
Get normalized line content (stripped)
154 155 156 157 |
# File 'lib/prism/merge/file_analysis.rb', line 154 def normalized_line(line_num) return if line_num < 1 || line_num > lines.length lines[line_num - 1].strip end |
#signature_at(index) ⇒ Array?
Get structural signature for a statement at given index
121 122 123 124 |
# File 'lib/prism/merge/file_analysis.rb', line 121 def signature_at(index) return if index < 0 || index >= statements.length generate_signature(statements[index]) end |
#valid? ⇒ Boolean
Check if parsing was successful
49 50 51 |
# File 'lib/prism/merge/file_analysis.rb', line 49 def valid? @parse_result.success? end |