Class: RuboCop::Cop::Corrector

Inherits:
Object
  • Object
show all
Defined in:
lib/rubocop/cop/corrector.rb

Overview

This class takes a source buffer and rewrite its source based on the different correction rules supplied.

Important! The nodes modified by the corrections should be part of the AST of the source_buffer.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_buffer, corrections = []) ⇒ Corrector

Returns a new instance of Corrector

Examples:


class AndOrCorrector
  def initialize(node)
    @node = node
  end

  def call(corrector)
    replacement = (@node.type == :and ? '&&' : '||')
    corrector.replace(@node.loc.operator, replacement)
  end
end

corrections = [AndOrCorrector.new(node)]
corrector = Corrector.new(source_buffer, corrections)


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/rubocop/cop/corrector.rb', line 33

def initialize(source_buffer, corrections = [])
  @source_buffer = source_buffer
  raise 'source_buffer should be a Parser::Source::Buffer' unless \
    source_buffer.is_a? Parser::Source::Buffer

  @corrections = corrections
  @source_rewriter = Parser::Source::TreeRewriter.new(
    source_buffer,
    different_replacements: :raise,
    swallowed_insertions: :raise,
    crossing_deletions: :accept
  )

  @diagnostics = []
  # Don't print warnings to stderr if corrections conflict with each other
  @source_rewriter.diagnostics.consumer = lambda do |diagnostic|
    @diagnostics << diagnostic
  end
end

Instance Attribute Details

#correctionsObject (readonly)

Returns the value of attribute corrections



53
54
55
# File 'lib/rubocop/cop/corrector.rb', line 53

def corrections
  @corrections
end

#diagnosticsObject (readonly)

Returns the value of attribute diagnostics



53
54
55
# File 'lib/rubocop/cop/corrector.rb', line 53

def diagnostics
  @diagnostics
end

Instance Method Details

#insert_after(range, content) ⇒ Object

Inserts new code after the given source range.



100
101
102
103
# File 'lib/rubocop/cop/corrector.rb', line 100

def insert_after(range, content)
  validate_range range
  @source_rewriter.insert_after(range, content)
end

#insert_before(range, content) ⇒ Object

Inserts new code before the given source range.



86
87
88
89
90
91
92
93
94
# File 'lib/rubocop/cop/corrector.rb', line 86

def insert_before(range, content)
  validate_range range
  # TODO: Fix Cops using bad ranges instead
  if range.end_pos > @source_buffer.source.size
    range = range.with(end_pos: @source_buffer.source.size)
  end

  @source_rewriter.insert_before(range, content)
end

#remove(range) ⇒ Object

Removes the source range.



77
78
79
80
# File 'lib/rubocop/cop/corrector.rb', line 77

def remove(range)
  validate_range range
  @source_rewriter.remove(range)
end

#remove_leading(range, size) ⇒ Object

Removes `size` characters from the beginning of the given range. If `size` is greater than the size of `range`, the removed region can overrun the end of `range`.



132
133
134
135
136
137
138
# File 'lib/rubocop/cop/corrector.rb', line 132

def remove_leading(range, size)
  validate_range range
  to_remove = Parser::Source::Range.new(range.source_buffer,
                                        range.begin_pos,
                                        range.begin_pos + size)
  @source_rewriter.remove(to_remove)
end

#remove_preceding(range, size) ⇒ Object

Removes `size` characters prior to the source range.



118
119
120
121
122
123
124
# File 'lib/rubocop/cop/corrector.rb', line 118

def remove_preceding(range, size)
  validate_range range
  to_remove = Parser::Source::Range.new(range.source_buffer,
                                        range.begin_pos - size,
                                        range.begin_pos)
  @source_rewriter.remove(to_remove)
end

#remove_trailing(range, size) ⇒ Object

Removes `size` characters from the end of the given range. If `size` is greater than the size of `range`, the removed region can overrun the beginning of `range`.



146
147
148
149
150
151
152
# File 'lib/rubocop/cop/corrector.rb', line 146

def remove_trailing(range, size)
  validate_range range
  to_remove = Parser::Source::Range.new(range.source_buffer,
                                        range.end_pos - size,
                                        range.end_pos)
  @source_rewriter.remove(to_remove)
end

#replace(range, content) ⇒ Object

Replaces the code of the source range `range` with `content`.



109
110
111
112
# File 'lib/rubocop/cop/corrector.rb', line 109

def replace(range, content)
  validate_range range
  @source_rewriter.replace(range, content)
end

#rewriteString

Does the actual rewrite and returns string corresponding to the rewritten source.



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/rubocop/cop/corrector.rb', line 59

def rewrite
  # rubocop:disable Lint/HandleExceptions
  @corrections.each do |correction|
    begin
      @source_rewriter.transaction do
        correction.call(self)
      end
    rescue ::Parser::ClobberingError
    end
  end
  # rubocop:enable Lint/HandleExceptions

  @source_rewriter.process
end