Class: Rbs::Merge::FileAligner

Inherits:
Object
  • Object
show all
Defined in:
lib/rbs/merge/file_aligner.rb

Overview

Aligns declarations between template and destination files by matching signatures. Produces alignment information used by SmartMerger to combine files.

Examples:

Basic usage

aligner = FileAligner.new(template_analysis, dest_analysis)
alignment = aligner.align
alignment.each do |entry|
  case entry[:type]
  when :match
    # Both files have this declaration
  when :template_only
    # Only in template
  when :dest_only
    # Only in destination
  end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(template_analysis, dest_analysis) ⇒ FileAligner

Initialize a file aligner

Parameters:

  • template_analysis (FileAnalysis)

    Analysis of the template file

  • dest_analysis (FileAnalysis)

    Analysis of the destination file



32
33
34
35
# File 'lib/rbs/merge/file_aligner.rb', line 32

def initialize(template_analysis, dest_analysis)
  @template_analysis = template_analysis
  @dest_analysis = dest_analysis
end

Instance Attribute Details

#dest_analysisFileAnalysis (readonly)

Returns Destination file analysis.

Returns:



26
27
28
# File 'lib/rbs/merge/file_aligner.rb', line 26

def dest_analysis
  @dest_analysis
end

#template_analysisFileAnalysis (readonly)

Returns Template file analysis.

Returns:



23
24
25
# File 'lib/rbs/merge/file_aligner.rb', line 23

def template_analysis
  @template_analysis
end

Instance Method Details

#alignArray<Hash>

Perform alignment between template and destination statements

Returns:

  • (Array<Hash>)

    Alignment entries with type, indices, and declarations



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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
# File 'lib/rbs/merge/file_aligner.rb', line 40

def align
  template_statements = @template_analysis.statements
  dest_statements = @dest_analysis.statements

  # Build signature maps
  template_by_sig = build_signature_map(template_statements, @template_analysis)
  dest_by_sig = build_signature_map(dest_statements, @dest_analysis)

  # Track which indices have been matched
  matched_template = Set.new
  matched_dest = Set.new
  alignment = []

  # First pass: find matches by signature
  template_by_sig.each do |sig, template_indices|
    next unless dest_by_sig.key?(sig)

    dest_indices = dest_by_sig[sig]

    # Match indices pairwise (first template with first dest, etc.)
    template_indices.zip(dest_indices).each do |t_idx, d_idx|
      next unless t_idx && d_idx

      alignment << {
        type: :match,
        template_index: t_idx,
        dest_index: d_idx,
        signature: sig,
        template_decl: template_statements[t_idx],
        dest_decl: dest_statements[d_idx],
      }

      matched_template << t_idx
      matched_dest << d_idx
    end
  end

  # Second pass: add template-only entries
  template_statements.each_with_index do |stmt, idx|
    next if matched_template.include?(idx)

    alignment << {
      type: :template_only,
      template_index: idx,
      dest_index: nil,
      signature: @template_analysis.signature_at(idx),
      template_decl: stmt,
      dest_decl: nil,
    }
  end

  # Third pass: add dest-only entries
  dest_statements.each_with_index do |stmt, idx|
    next if matched_dest.include?(idx)

    alignment << {
      type: :dest_only,
      template_index: nil,
      dest_index: idx,
      signature: @dest_analysis.signature_at(idx),
      template_decl: nil,
      dest_decl: stmt,
    }
  end

  # Sort by appearance order (prefer destination order, then template)
  sort_alignment(alignment)
end