module RuboCop::Cop::AutocorrectLogic
This module encapsulates the logic for autocorrect behavior for a cop.
Public Instance Methods
autocorrect?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 7 def autocorrect? autocorrect_requested? && correctable? && autocorrect_enabled? end
autocorrect_enabled?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 31 def autocorrect_enabled? # allow turning off autocorrect on a cop by cop basis return true unless cop_config # `false` is the same as `disabled` for backward compatibility. return false if ['disabled', false].include?(cop_config['AutoCorrect']) # When LSP is enabled, it is considered as editing source code, # and autocorrection with `AutoCorrect: contextual` will not be performed. return false if contextual_autocorrect? && LSP.enabled? # :safe_autocorrect is a derived option based on several command-line # arguments - see RuboCop::Options#add_autocorrection_options return safe_autocorrect? if @options.fetch(:safe_autocorrect, false) true end
autocorrect_requested?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 15 def autocorrect_requested? @options.fetch(:autocorrect, false) end
autocorrect_with_disable_uncorrectable?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 11 def autocorrect_with_disable_uncorrectable? autocorrect_requested? && disable_uncorrectable? && autocorrect_enabled? end
correctable?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 19 def correctable? self.class.support_autocorrect? || disable_uncorrectable? end
disable_uncorrectable?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 23 def disable_uncorrectable? @options[:disable_uncorrectable] == true end
safe_autocorrect?()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 27 def safe_autocorrect? cop_config.fetch('Safe', true) && cop_config.fetch('SafeAutoCorrect', true) end
Private Instance Methods
disable_offense(offense_range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 51 def disable_offense(offense_range) range = surrounding_heredoc(offense_range) || surrounding_percent_array(offense_range) || string_continuation(offense_range) if range disable_offense_before_and_after(range_by_lines(range)) else disable_offense_with_eol_or_surround_comment(offense_range) end end
disable_offense_at_end_of_line(range, eol_comment)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 138 def disable_offense_at_end_of_line(range, eol_comment) Corrector.new(range).insert_after(range, eol_comment) end
disable_offense_before_and_after(range_by_lines)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 142 def disable_offense_before_and_after(range_by_lines) range_with_newline = range_by_lines.resize(range_by_lines.size + 1) leading_whitespace = range_by_lines.source_line[/^\s*/] Corrector.new(range_by_lines).wrap( range_with_newline, "#{leading_whitespace}# rubocop:todo #{cop_name}\n", "#{leading_whitespace}# rubocop:enable #{cop_name}\n" ) end
disable_offense_with_eol_or_surround_comment(range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 63 def disable_offense_with_eol_or_surround_comment(range) eol_comment = " # rubocop:todo #{cop_name}" needed_line_length = (range.source_line + eol_comment).length if needed_line_length <= max_line_length disable_offense_at_end_of_line(range_of_first_line(range), eol_comment) else disable_offense_before_and_after(range_by_lines(range)) end end
max_line_length()
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 134 def max_line_length config.for_cop('Layout/LineLength')['Max'] || 120 end
range_by_lines(range)
click to toggle source
Expand the given range to include all of any lines it covers. Does not include newline at end of the last line.
# File lib/rubocop/cop/autocorrect_logic.rb, line 124 def range_by_lines(range) begin_of_first_line = range.begin_pos - range.column last_line = range.source_buffer.source_line(range.last_line) last_line_offset = last_line.length - range.last_column end_of_last_line = range.end_pos + last_line_offset Parser::Source::Range.new(range.source_buffer, begin_of_first_line, end_of_last_line) end
range_of_first_line(range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 115 def range_of_first_line(range) begin_of_first_line = range.begin_pos - range.column end_of_first_line = begin_of_first_line + range.source_line.length Parser::Source::Range.new(range.source_buffer, begin_of_first_line, end_of_first_line) end
range_overlaps_offense?(offense_range, range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 107 def range_overlaps_offense?(offense_range, range) offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range) end
string_continuation(offense_range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 97 def string_continuation(offense_range) return nil if offense_range.empty? string_continuation_nodes = processed_source.ast.each_descendant.filter_map do |node| range_by_lines(node.source_range) if string_continuation?(node) end string_continuation_nodes.find { |range| range_overlaps_offense?(offense_range, range) } end
string_continuation?(node)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 111 def string_continuation?(node) (node.str_type? || node.dstr_type? || node.xstr_type?) && node.source.match?(/\\\s*$/) end
surrounding_heredoc(offense_range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 74 def surrounding_heredoc(offense_range) # The empty offense range is an edge case that can be reached from the Lint/Syntax cop. return nil if offense_range.empty? heredoc_nodes = processed_source.ast.each_descendant.select do |node| node.respond_to?(:heredoc?) && node.heredoc? end heredoc_nodes.map { |node| node.source_range.join(node.loc.heredoc_end) } .find { |range| range.contains?(offense_range) } end
surrounding_percent_array(offense_range)
click to toggle source
# File lib/rubocop/cop/autocorrect_logic.rb, line 85 def surrounding_percent_array(offense_range) return nil if offense_range.empty? percent_array = processed_source.ast.each_descendant.select do |node| node.array_type? && node.percent_literal? end percent_array.map(&:source_range).find do |range| range_overlaps_offense?(offense_range, range) end end