Class: Canon::Diff::DiffLine

Inherits:
Object
  • Object
show all
Defined in:
lib/canon/diff/diff_line.rb

Overview

Represents a single line in the diff output Links textual representation to semantic DiffNode and DiffCharRanges

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(line_number:, content:, type:, diff_node: nil, formatting: false, new_position: nil, old_content: nil, char_ranges: nil, new_char_ranges: nil, new_content: nil) ⇒ DiffLine

Returns a new instance of DiffLine.

Parameters:

  • line_number (Integer)

    The 0-based line number in text1 (old text)

  • new_position (Integer, nil) (defaults to: nil)

    The 0-based line number in text2 (new text), used for :changed lines where old and new positions differ

  • content (String)

    The text content of the line (from text1)

  • type (Symbol)

    The type of line (:unchanged, :added, :removed, :changed)

  • diff_node (DiffNode, nil) (defaults to: nil)

    The semantic diff node this line belongs to

  • formatting (Boolean) (defaults to: false)

    Whether this is a formatting-only difference

  • char_ranges (Array<DiffCharRange>) (defaults to: nil)

    Character ranges for text1 side

  • new_char_ranges (Array<DiffCharRange>) (defaults to: nil)

    Character ranges for text2 side

  • new_content (String, nil) (defaults to: nil)

    The text2 line content (for :changed lines)

  • old_content (String, nil) (defaults to: nil)

    Deprecated: multi-line old content



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/canon/diff/diff_line.rb', line 24

def initialize(line_number:, content:, type:, diff_node: nil,
               formatting: false, new_position: nil, old_content: nil,
               char_ranges: nil, new_char_ranges: nil, new_content: nil)
  @line_number = line_number
  @new_position = new_position
  @content = content
  @type = type
  @diff_node = diff_node
  @formatting = formatting
  @old_content = old_content
  @char_ranges = char_ranges || []
  @new_char_ranges = new_char_ranges || []
  @new_content = new_content
end

Instance Attribute Details

#char_rangesObject (readonly)

Returns the value of attribute char_ranges.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def char_ranges
  @char_ranges
end

#contentObject (readonly)

Returns the value of attribute content.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def content
  @content
end

#diff_nodeObject (readonly)

Returns the value of attribute diff_node.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def diff_node
  @diff_node
end

#formatting=(value) ⇒ Object (writeonly)

Sets the attribute formatting

Parameters:

  • value

    the value to set the attribute formatting to.



11
12
13
# File 'lib/canon/diff/diff_line.rb', line 11

def formatting=(value)
  @formatting = value
end

#line_numberObject (readonly)

Returns the value of attribute line_number.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def line_number
  @line_number
end

#new_char_rangesObject (readonly)

Returns the value of attribute new_char_ranges.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def new_char_ranges
  @new_char_ranges
end

#new_contentObject (readonly)

Returns the value of attribute new_content.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def new_content
  @new_content
end

#new_positionObject (readonly)

Returns the value of attribute new_position.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def new_position
  @new_position
end

#old_contentObject

Returns the value of attribute old_content.



10
11
12
# File 'lib/canon/diff/diff_line.rb', line 10

def old_content
  @old_content
end

#typeObject (readonly)

Returns the value of attribute type.



8
9
10
# File 'lib/canon/diff/diff_line.rb', line 8

def type
  @type
end

Instance Method Details

#==(other) ⇒ Object



126
127
128
129
130
131
132
133
134
# File 'lib/canon/diff/diff_line.rb', line 126

def ==(other)
  other.is_a?(DiffLine) &&
    line_number == other.line_number &&
    new_position == other.new_position &&
    content == other.content &&
    type == other.type &&
    diff_node == other.diff_node &&
    @formatting == other.instance_variable_get(:@formatting)
end

#add_char_range(char_range) ⇒ Object

Add a character range for the text1 (old) side

Parameters:



41
42
43
# File 'lib/canon/diff/diff_line.rb', line 41

def add_char_range(char_range)
  @char_ranges << char_range
end

#add_new_char_range(char_range) ⇒ Object

Add a character range for the text2 (new) side

Parameters:



47
48
49
# File 'lib/canon/diff/diff_line.rb', line 47

def add_new_char_range(char_range)
  @new_char_ranges << char_range
end

#added?Boolean

Returns true if this line was added.

Returns:

  • (Boolean)

    true if this line was added



96
97
98
# File 'lib/canon/diff/diff_line.rb', line 96

def added?
  type == :added
end

#changed?Boolean

Returns true if this line was changed.

Returns:

  • (Boolean)

    true if this line was changed



106
107
108
# File 'lib/canon/diff/diff_line.rb', line 106

def changed?
  type == :changed
end

#char_ranges_for_side(side) ⇒ Array<DiffCharRange>

Get character ranges for a specific side

Parameters:

  • side (Symbol)

    :old or :new

Returns:



59
60
61
# File 'lib/canon/diff/diff_line.rb', line 59

def char_ranges_for_side(side)
  side == :old ? @char_ranges : @new_char_ranges
end

#formatting?Boolean

Formatting diffs are purely cosmetic (whitespace, line breaks) with no semantic meaning

Returns:

  • (Boolean)

    true if this line represents a formatting-only difference



86
87
88
# File 'lib/canon/diff/diff_line.rb', line 86

def formatting?
  @formatting == true
end

#has_char_ranges?Boolean

Returns true if this line has any character ranges.

Returns:

  • (Boolean)

    true if this line has any character ranges



52
53
54
# File 'lib/canon/diff/diff_line.rb', line 52

def has_char_ranges?
  !@char_ranges.empty? || !@new_char_ranges.empty?
end

#informative?Boolean

If diff_node is nil (not linked), it’s not informative either (it’s unchanged/cosmetic) Formatting-only diffs are never informative

Returns:

  • (Boolean)

    true if this line represents an informative-only difference



77
78
79
80
81
82
# File 'lib/canon/diff/diff_line.rb', line 77

def informative?
  return false if formatting?
  return false if diff_node.nil?

  diff_node.informative?
end

#normative?Boolean

If diff_node is nil (not linked to any semantic difference), the line is considered informative (cosmetic/unchanged) Formatting-only diffs are never normative

Returns:

  • (Boolean)

    true if this line represents a normative difference



67
68
69
70
71
72
# File 'lib/canon/diff/diff_line.rb', line 67

def normative?
  return false if formatting?
  return false if diff_node.nil?

  diff_node.normative?
end

#removed?Boolean

Returns true if this line was removed.

Returns:

  • (Boolean)

    true if this line was removed



101
102
103
# File 'lib/canon/diff/diff_line.rb', line 101

def removed?
  type == :removed
end

#to_hObject



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/canon/diff/diff_line.rb', line 110

def to_h
  {
    line_number: line_number,
    new_position: new_position,
    content: content,
    new_content: new_content,
    type: type,
    diff_node: diff_node&.to_h,
    normative: normative?,
    informative: informative?,
    formatting: formatting?,
    char_ranges: @char_ranges.map(&:to_h),
    new_char_ranges: @new_char_ranges.map(&:to_h),
  }
end

#unchanged?Boolean

Returns true if this line is unchanged.

Returns:

  • (Boolean)

    true if this line is unchanged



91
92
93
# File 'lib/canon/diff/diff_line.rb', line 91

def unchanged?
  type == :unchanged
end