Module: RemLint::Joiner

Defined in:
lib/remlint/logical_line.rb

Overview

Joins backslash-continued physical lines into logical ones.

This is where a whole bug class lives. Remind continues a line only on a backslash that is the very last character; a backslash followed by a space is just a backslash, and the long IIF(...) chains in defs.rem and astro are held together by nothing else. Joining here -- rather than letting each rule guess -- means every rule sees the command Remind sees, and "backslash that does not continue" becomes something DanglingContinuation can report rather than something that silently splits a command in half.

Class Method Summary collapse

Class Method Details

.call(source) ⇒ Object



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
# File 'lib/remlint/logical_line.rb', line 69

def call(source)
  buffer = nil

  [].tap do |logical|
    source.lines.each_with_index do |raw, index|
      line_no = index + 1 + source.line_offset
      body = raw.chomp

      if buffer
        buffer.text << body
        buffer.physical_lines << line_no
        buffer.raw << raw
      else
        buffer = LogicalLine.new(
          text:           +body,
          line:           line_no,
          physical_lines: [line_no],
          raw:            +raw,
        )
      end

      if buffer.text.end_with?("\\")
        # Remind overwrites the backslash with the newline it just consumed.
        buffer.text[-1] = "\n"
      else
        logical << buffer
        buffer = nil
      end
    end

    # A file whose last line ends in a backslash leaves a command open.
    # Emit it anyway, so the rules can see -- and complain about -- it.
    if buffer
      logical << buffer
    end
  end
end