Class: Ast::Merge::StructuralEdit::SplicePlan

Inherits:
Object
  • Object
show all
Defined in:
lib/ast/merge/structural_edit/splice_plan.rb

Overview

Passive plan for a contiguous structural splice.

The first shared primitive models exact line-range replacement: keep the original source untouched outside the replaced window and substitute only the requested structural range. This avoids separator surgery in callers such as PartialTemplateMergerBase and gives future remove/rehome work a stable place to grow richer ownership-transfer rules.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source:, replacement:, replace_start_line:, replace_end_line:, leading_boundary: nil, trailing_boundary: nil, preserve_removed_trailing_blank_lines: true, metadata: {}, **options) ⇒ SplicePlan

Build a plan for exact line-range replacement.

Parameters:

  • source (String)

    original source text

  • replacement (String)

    replacement text for the removed range

  • replace_start_line (Integer)

    first replaced line, 1-based

  • replace_end_line (Integer)

    last replaced line, 1-based

  • leading_boundary (Boundary, nil) (defaults to: nil)

    surviving boundary before the replaced range

  • trailing_boundary (Boundary, nil) (defaults to: nil)

    surviving boundary after the replaced range

  • preserve_removed_trailing_blank_lines (Boolean) (defaults to: true)

    whether to preserve trailing blank lines from removed content

  • metadata (Hash) (defaults to: {})

    base metadata

  • options (Hash)

    extra metadata merged into metadata



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 42

def initialize(source:, replacement:, replace_start_line:, replace_end_line:, leading_boundary: nil,
               trailing_boundary: nil, preserve_removed_trailing_blank_lines: true, metadata: {}, **options)
  @source = source.to_s
  @replacement = replacement.to_s
  @replace_start_line = Integer(replace_start_line)
  @replace_end_line = Integer(replace_end_line)
  @leading_boundary = leading_boundary
  @trailing_boundary = trailing_boundary
  @preserve_removed_trailing_blank_lines = preserve_removed_trailing_blank_lines
  @metadata = .merge(options).freeze

  validate_range!
end

Instance Attribute Details

#leading_boundaryString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def leading_boundary
  @leading_boundary
end

#metadataString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def 
  @metadata
end

#preserve_removed_trailing_blank_linesString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def preserve_removed_trailing_blank_lines
  @preserve_removed_trailing_blank_lines
end

#replace_end_lineString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def replace_end_line
  @replace_end_line
end

#replace_start_lineString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def replace_start_line
  @replace_start_line
end

#replacementString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def replacement
  @replacement
end

#sourceString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def source
  @source
end

#trailing_boundaryString, ... (readonly)

Returns:

  • (String)

    original source content

  • (String)

    replacement text inserted for the removed line range

  • (Integer)

    first replaced line number

  • (Integer)

    last replaced line number

  • (Boundary, nil)

    surviving boundary before the replaced range

  • (Boundary, nil)

    surviving boundary after the replaced range

  • (Boolean)

    whether trailing blank lines removed with the range may be preserved

  • (Hash)

    producer metadata



22
23
24
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 22

def trailing_boundary
  @trailing_boundary
end

Instance Method Details

#after_contentString

Return content after the replaced range.

Returns:

  • (String)


87
88
89
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 87

def after_content
  line_chunks[replace_end_line..].to_a.join
end

#apply_to(alternate_source = source) ⇒ String

Apply the splice to the original source or a compatible alternate source.

Parameters:

  • alternate_source (String) (defaults to: source)

    alternate source text

Returns:

  • (String)


113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 113

def apply_to(alternate_source = source)
  alternate_text = alternate_source.to_s
  return merged_content if alternate_text == source

  self.class.new(
    source: alternate_text,
    replacement: replacement,
    replace_start_line: replace_start_line,
    replace_end_line: replace_end_line,
    leading_boundary: leading_boundary,
    trailing_boundary: trailing_boundary,
    metadata: 
  ).merged_content
end

#before_contentString

Return content before the replaced range.

Returns:

  • (String)


66
67
68
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 66

def before_content
  line_chunks[0...(replace_start_line - 1)].to_a.join
end

#changed?Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 98

def changed?
  merged_content != source
end

#inspectString

Return a concise debug representation of the splice plan.

Returns:

  • (String)


131
132
133
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 131

def inspect
  "#<#{self.class.name} lines=#{replace_start_line}..#{replace_end_line} changed=#{changed?}>"
end

#line_chunksArray<String>

Return the source split into line chunks.

Returns:

  • (Array<String>)


59
60
61
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 59

def line_chunks
  @line_chunks ||= source.lines
end

#line_rangeRange

Return the replaced line range.

Returns:

  • (Range)


73
74
75
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 73

def line_range
  replace_start_line..replace_end_line
end

#merged_contentString

Return merged content after applying the splice.

Returns:

  • (String)


94
95
96
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 94

def merged_content
  +before_content + replacement_with_preserved_boundary_layout + after_content
end

#removed_contentString

Return the content removed by the splice.

Returns:

  • (String)


80
81
82
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 80

def removed_content
  line_chunks[(replace_start_line - 1)..(replace_end_line - 1)].to_a.join
end

#to_splice_planSplicePlan

Return self so splice-compatible plans share a common adapter surface.

Returns:



105
106
107
# File 'lib/ast/merge/structural_edit/splice_plan.rb', line 105

def to_splice_plan
  self
end