Class: RuboCop::Cop::Lint::UnneededDisable

Inherits:
Cop
  • Object
show all
Includes:
NameSimilarity
Defined in:
lib/rubocop/cop/lint/unneeded_disable.rb

Overview

This cop detects instances of rubocop:disable comments that can be removed without causing any offenses to be reported. It’s implemented as a cop in that it inherits from the Cop base class and calls add_offense. The unusual part of its implementation is that it doesn’t have any on_* methods or an investigate method. This means that it doesn’t take part in the investigation phase when the other cops do their work. Instead, it waits until it’s called in a later stage of the execution. The reason it can’t be implemented as a normal cop is that it depends on the results of all other cops to do its work.

Constant Summary collapse

COP_NAME =
'Lint/UnneededDisable'.freeze

Constants included from NameSimilarity

NameSimilarity::MINIMUM_SIMILARITY_TO_SUGGEST

Constants included from Util

Util::ASGN_NODES, Util::BYTE_ORDER_MARK, Util::EQUALS_ASGN_NODES, Util::LITERAL_REGEX, Util::OPERATOR_METHODS, Util::SHORTHAND_ASGN_NODES, Util::STRING_ESCAPES, Util::STRING_ESCAPE_REGEX

Instance Attribute Summary

Attributes inherited from Cop

#config, #corrections, #offenses, #processed_source

Instance Method Summary collapse

Methods included from NameSimilarity

#find_similar_name

Methods inherited from Cop

#add_offense, all, #config_to_allow_offenses, #config_to_allow_offenses=, #cop_config, cop_name, #cop_name, cop_type, #correct, #debug?, #details, #display_cop_names?, #display_style_guide?, #excluded_file?, #extra_details?, inherited, #initialize, #join_force?, lint?, match?, #message, non_rails, #parse, qualified_cop_name, #reference_url, #relevant_file?, #style_guide_url, #target_ruby_version

Methods included from Sexp

#s

Methods included from NodePattern::Macros

#def_node_matcher, #def_node_search, #node_search_body

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #support_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

begins_its_line?, block_length, comment_line?, directions, double_quotes_acceptable?, double_quotes_required?, effective_column, ends_its_line?, first_part_of_call_chain, interpret_string_escapes, line_range, move_pos, numeric_range_size, on_node, operator?, parentheses?, range_with_surrounding_comma, range_with_surrounding_space, source_range, strip_quotes, to_string_literal, to_symbol_literal, within_node?

Methods included from PathUtil

absolute?, hidden?, issue_deprecation_warning, match_path?, relative_path

Constructor Details

This class inherits a constructor from RuboCop::Cop::Cop

Instance Method Details

#autocorrect(args) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/rubocop/cop/lint/unneeded_disable.rb', line 52

def autocorrect(args)
  lambda do |corrector|
    ranges, range = *args # ranges are sorted by position

    if range.source.start_with?('#')
      # eat the entire comment and following newline
      corrector.remove(range_with_surrounding_space(range, :right))
    else
      # is there any cop between this one and the end of the line, which
      # is NOT being removed?

      if ends_its_line?(ranges.last) && trailing_range?(ranges, range)
        # eat the comma on the left
        range = range_with_surrounding_space(range, :left)
        range = range_with_surrounding_comma(range, :left)
      end

      range = range_with_surrounding_comma(range, :right)
      # eat following spaces up to EOL, but not the newline itself
      range = range_with_surrounding_space(range, :right, false)

      corrector.remove(range)
    end
  end
end

#check(offenses, cop_disabled_line_ranges, comments) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/rubocop/cop/lint/unneeded_disable.rb', line 21

def check(offenses, cop_disabled_line_ranges, comments)
  unneeded_cops = Hash.new { |h, k| h[k] = Set.new }
  disabled_ranges = cop_disabled_line_ranges[COP_NAME] || [0..0]

  cop_disabled_line_ranges.each do |cop, line_ranges|
    line_ranges.each_cons(2) do |previous_range, range|
      next if previous_range.end != range.begin

      # If a cop is disabled in a range that begins on the same line as
      # the end of the previous range, it means that the cop was
      # already disabled by an earlier comment. So it's unneeded
      # whether there are offenses or not.
      comment = comments.find { |c| c.loc.line == range.begin }
      unneeded_cops[comment].add(cop)
    end

    line_ranges.each do |line_range|
      comment = comments.find { |c| c.loc.line == line_range.begin }

      unless all_disabled?(comment)
        next if ignore_offense?(disabled_ranges, line_range)
      end

      unneeded_cop = find_unneeded(comment, offenses, cop, line_range)
      unneeded_cops[comment].add(unneeded_cop) if unneeded_cop
    end
  end

  add_offenses(unneeded_cops)
end