Class: Ast::Merge::DiffMapperBase Abstract
- Inherits:
-
Object
- Object
- Ast::Merge::DiffMapperBase
- Defined in:
- lib/ast/merge/diff_mapper_base.rb
Overview
Subclass and implement #map_hunk_to_paths
Base class for mapping unified git diffs to AST node paths.
DiffMapperBase provides a format-agnostic foundation for parsing unified
git diffs and mapping changed lines to AST node paths. Subclasses implement
format-specific logic to determine which AST nodes are affected by each change.
Defined Under Namespace
Classes: DiffHunk, DiffLine, DiffMapping, DiffParseResult
Instance Method Summary collapse
-
#create_analysis(content) ⇒ Object
abstract
Create a file analysis for the original content.
-
#determine_operation(hunk) ⇒ Symbol
Determine the operation type for a hunk.
-
#map(diff_text, original_content) ⇒ Array<DiffMapping>
Parse a unified diff and map changes to AST paths.
-
#map_hunk_to_paths(hunk, original_analysis) ⇒ Array<DiffMapping>
abstract
Map a single hunk to AST paths.
-
#parse_diff(diff_text) ⇒ DiffParseResult
Parse a unified diff into structured hunks.
Instance Method Details
#create_analysis(content) ⇒ Object
Create a file analysis for the original content.
Subclasses must implement this to return their format-specific analysis.
190 191 192 |
# File 'lib/ast/merge/diff_mapper_base.rb', line 190 def create_analysis(content) raise NotImplementedError, "Subclasses must implement #create_analysis" end |
#determine_operation(hunk) ⇒ Symbol
Determine the operation type for a hunk.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/ast/merge/diff_mapper_base.rb', line 169 def determine_operation(hunk) has_additions = hunk.lines.any? { |l| l.type == :addition } has_removals = hunk.lines.any? { |l| l.type == :removal } if has_additions && has_removals :modify elsif has_additions :add elsif has_removals :remove else :modify # Context-only hunk (unusual) end end |
#map(diff_text, original_content) ⇒ Array<DiffMapping>
Parse a unified diff and map changes to AST paths.
65 66 67 68 69 70 71 72 73 74 |
# File 'lib/ast/merge/diff_mapper_base.rb', line 65 def map(diff_text, original_content) parse_result = parse_diff(diff_text) return [] if parse_result.hunks.empty? original_analysis = create_analysis(original_content) parse_result.hunks.flat_map do |hunk| map_hunk_to_paths(hunk, original_analysis) end end |
#map_hunk_to_paths(hunk, original_analysis) ⇒ Array<DiffMapping>
Map a single hunk to AST paths.
Subclasses must implement this with format-specific logic.
201 202 203 |
# File 'lib/ast/merge/diff_mapper_base.rb', line 201 def map_hunk_to_paths(hunk, original_analysis) raise NotImplementedError, "Subclasses must implement #map_hunk_to_paths" end |
#parse_diff(diff_text) ⇒ DiffParseResult
Parse a unified diff into structured hunks.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 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 |
# File 'lib/ast/merge/diff_mapper_base.rb', line 80 def parse_diff(diff_text) lines = diff_text.lines.map(&:chomp) old_file = nil new_file = nil hunks = [] current_hunk = nil old_line_num = nil new_line_num = nil lines.each do |line| case line when /^---\s+(.+)$/ # Original file path old_file = extract_file_path($1) when /^\+\+\+\s+(.+)$/ # New file path new_file = extract_file_path($1) when /^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@/ # Hunk header # Finalize previous hunk hunks << current_hunk if current_hunk old_start = $1.to_i old_count = ($2 || "1").to_i new_start = $3.to_i new_count = ($4 || "1").to_i current_hunk = DiffHunk.new( old_start: old_start, old_count: old_count, new_start: new_start, new_count: new_count, lines: [], header: line, ) old_line_num = old_start new_line_num = new_start when /^\+(.*)$/ # Addition (not +++ header line, already handled) next unless current_hunk current_hunk.lines << DiffLine.new( type: :addition, content: $1, old_line_num: nil, new_line_num: new_line_num, ) new_line_num += 1 when /^-(.*)$/ # Removal (not --- header line, already handled) next unless current_hunk current_hunk.lines << DiffLine.new( type: :removal, content: $1, old_line_num: old_line_num, new_line_num: nil, ) old_line_num += 1 when /^ (.*)$/ # Context line next unless current_hunk current_hunk.lines << DiffLine.new( type: :context, content: $1, old_line_num: old_line_num, new_line_num: new_line_num, ) old_line_num += 1 new_line_num += 1 end end # Finalize last hunk hunks << current_hunk if current_hunk DiffParseResult.new( old_file: old_file, new_file: new_file, hunks: hunks, ) end |