rubocop 0.90.0 → 0.93.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +79 -3
  4. data/lib/rubocop.rb +20 -5
  5. data/lib/rubocop/cached_data.rb +2 -1
  6. data/lib/rubocop/cli/command/execute_runner.rb +8 -0
  7. data/lib/rubocop/comment_config.rb +9 -5
  8. data/lib/rubocop/config_loader.rb +3 -3
  9. data/lib/rubocop/config_regeneration.rb +33 -0
  10. data/lib/rubocop/config_store.rb +3 -3
  11. data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
  12. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  13. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
  14. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  15. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
  16. data/lib/rubocop/cop/generator.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  18. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  19. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
  20. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  21. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
  22. data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
  23. data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
  24. data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
  25. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  26. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +6 -9
  28. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  29. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -12
  30. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +13 -8
  31. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
  32. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
  33. data/lib/rubocop/cop/layout/end_alignment.rb +5 -10
  34. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +26 -4
  35. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +4 -13
  36. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
  37. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
  38. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +6 -21
  39. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -8
  40. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
  44. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
  45. data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
  46. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
  47. data/lib/rubocop/cop/lint/debugger.rb +2 -3
  48. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
  50. data/lib/rubocop/cop/lint/duplicate_require.rb +7 -2
  51. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
  52. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  53. data/lib/rubocop/cop/lint/empty_file.rb +1 -4
  54. data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
  55. data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  57. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
  58. data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
  60. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  61. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  62. data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
  63. data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
  64. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -2
  65. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  66. data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
  67. data/lib/rubocop/cop/lint/rand_one.rb +2 -1
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
  70. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  71. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
  72. data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
  73. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
  75. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  76. data/lib/rubocop/cop/lint/to_json.rb +16 -5
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
  78. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
  79. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
  80. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
  81. data/lib/rubocop/cop/lint/useless_method_definition.rb +20 -27
  82. data/lib/rubocop/cop/lint/useless_times.rb +106 -0
  83. data/lib/rubocop/cop/metrics/block_length.rb +3 -1
  84. data/lib/rubocop/cop/metrics/class_length.rb +14 -6
  85. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
  86. data/lib/rubocop/cop/mixin/comments_help.rb +3 -9
  87. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  88. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  89. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +9 -0
  90. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -2
  91. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
  92. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
  93. data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
  94. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  95. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  96. data/lib/rubocop/cop/offense.rb +15 -2
  97. data/lib/rubocop/cop/security/eval.rb +1 -0
  98. data/lib/rubocop/cop/security/json_load.rb +1 -0
  99. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  100. data/lib/rubocop/cop/security/open.rb +1 -0
  101. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  102. data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
  103. data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
  104. data/lib/rubocop/cop/style/alias.rb +2 -0
  105. data/lib/rubocop/cop/style/array_coercion.rb +4 -0
  106. data/lib/rubocop/cop/style/array_join.rb +1 -0
  107. data/lib/rubocop/cop/style/attr.rb +1 -0
  108. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
  109. data/lib/rubocop/cop/style/case_equality.rb +3 -0
  110. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  111. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
  112. data/lib/rubocop/cop/style/class_check.rb +6 -9
  113. data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
  114. data/lib/rubocop/cop/style/class_methods_definitions.rb +42 -16
  115. data/lib/rubocop/cop/style/class_vars.rb +1 -2
  116. data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
  117. data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
  118. data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
  119. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
  120. data/lib/rubocop/cop/style/date_time.rb +12 -1
  121. data/lib/rubocop/cop/style/dir.rb +1 -0
  122. data/lib/rubocop/cop/style/double_negation.rb +1 -0
  123. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  124. data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
  125. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  126. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  127. data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
  128. data/lib/rubocop/cop/style/float_division.rb +2 -0
  129. data/lib/rubocop/cop/style/for.rb +0 -4
  130. data/lib/rubocop/cop/style/format_string.rb +1 -4
  131. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  132. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
  133. data/lib/rubocop/cop/style/hash_transform_keys.rb +5 -11
  134. data/lib/rubocop/cop/style/hash_transform_values.rb +5 -11
  135. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
  136. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  137. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
  138. data/lib/rubocop/cop/style/lambda_call.rb +3 -1
  139. data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
  140. data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
  141. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  142. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
  143. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
  144. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
  145. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  146. data/lib/rubocop/cop/style/non_nil_check.rb +2 -0
  147. data/lib/rubocop/cop/style/not.rb +1 -0
  148. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -3
  149. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
  150. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
  151. data/lib/rubocop/cop/style/preferred_hash_methods.rb +2 -0
  152. data/lib/rubocop/cop/style/raise_args.rb +2 -3
  153. data/lib/rubocop/cop/style/random_with_offset.rb +4 -3
  154. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
  155. data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
  156. data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
  157. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
  158. data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
  159. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  160. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -1
  161. data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
  162. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -6
  163. data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
  164. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
  165. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
  166. data/lib/rubocop/cop/style/redundant_return.rb +17 -17
  167. data/lib/rubocop/cop/style/redundant_self.rb +7 -9
  168. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
  169. data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
  170. data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
  171. data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
  172. data/lib/rubocop/cop/style/safe_navigation.rb +5 -0
  173. data/lib/rubocop/cop/style/sample.rb +2 -1
  174. data/lib/rubocop/cop/style/send.rb +2 -3
  175. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  176. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  177. data/lib/rubocop/cop/style/slicing_with_range.rb +2 -1
  178. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  179. data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
  180. data/lib/rubocop/cop/style/strip.rb +1 -0
  181. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
  182. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
  183. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  184. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -5
  185. data/lib/rubocop/cop/util.rb +0 -1
  186. data/lib/rubocop/cop/variable_force/branch.rb +0 -4
  187. data/lib/rubocop/core_ext/string.rb +1 -1
  188. data/lib/rubocop/directive_comment.rb +32 -0
  189. data/lib/rubocop/ext/regexp_node.rb +23 -7
  190. data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
  191. data/lib/rubocop/options.rb +37 -17
  192. data/lib/rubocop/result_cache.rb +38 -15
  193. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  194. data/lib/rubocop/rspec/expect_offense.rb +5 -5
  195. data/lib/rubocop/runner.rb +37 -18
  196. data/lib/rubocop/target_finder.rb +27 -26
  197. data/lib/rubocop/target_ruby.rb +1 -1
  198. data/lib/rubocop/version.rb +6 -1
  199. metadata +19 -18
  200. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
  201. data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -17,7 +17,9 @@ module RuboCop
17
17
  # time = "8 o'clock"
18
18
  # question = '"What did you say?"'
19
19
  #
20
- class RedundantPercentQ < Cop
20
+ class RedundantPercentQ < Base
21
+ extend AutoCorrector
22
+
21
23
  MSG = 'Use `%<q_type>s` only for strings that contain both ' \
22
24
  'single quotes and double quotes%<extra>s.'
23
25
  DYNAMIC_MSG = ', or for dynamic strings that contain ' \
@@ -45,22 +47,18 @@ module RuboCop
45
47
  check(node)
46
48
  end
47
49
 
48
- def autocorrect(node)
49
- delimiter =
50
- /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
51
- lambda do |corrector|
52
- corrector.replace(node.loc.begin, delimiter)
53
- corrector.replace(node.loc.end, delimiter)
54
- end
55
- end
56
-
57
50
  private
58
51
 
59
52
  def check(node)
60
53
  return unless start_with_percent_q_variant?(node)
61
54
  return if interpolated_quotes?(node) || allowed_percent_q?(node)
62
55
 
63
- add_offense(node)
56
+ add_offense(node) do |corrector|
57
+ delimiter = /^%Q[^"]+$|'/.match?(node.source) ? QUOTE : SINGLE_QUOTE
58
+
59
+ corrector.replace(node.loc.begin, delimiter)
60
+ corrector.replace(node.loc.end, delimiter)
61
+ end
64
62
  end
65
63
 
66
64
  def interpolated_quotes?(node)
@@ -22,32 +22,14 @@ module RuboCop
22
22
  # # good
23
23
  # r = /[ab]/
24
24
  class RedundantRegexpCharacterClass < Base
25
- include MatchRange
26
- include RegexpLiteralHelp
27
25
  extend AutoCorrector
28
26
 
27
+ REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS = '.*+?{}()|$'.chars.freeze
29
28
  MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \
30
29
  '`%<char_class>s` can be replaced with `%<element>s`.'
31
30
 
32
- PATTERN = /
33
- (
34
- (?<!\\) # No \-prefix (i.e. not escaped)
35
- \[ # Literal [
36
- (?!\#\{) # Not (the start of) an interpolation
37
- (?: # Either...
38
- \\[^b] | # Any escaped character except b (which would change behaviour)
39
- [^.*+?{}()|$] | # or one that doesn't require escaping outside the character class
40
- \\[upP]\{[^}]+\} # or a unicode code-point or property
41
- )
42
- (?<!\\) # No \-prefix (i.e. not escaped)
43
- \] # Literal ]
44
- )
45
- /x.freeze
46
-
47
31
  def on_regexp(node)
48
32
  each_redundant_character_class(node) do |loc|
49
- next if whitespace_in_free_space_mode?(node, loc)
50
-
51
33
  add_offense(
52
34
  loc, message: format(
53
35
  MSG_REDUNDANT_CHARACTER_CLASS,
@@ -63,19 +45,52 @@ module RuboCop
63
45
  private
64
46
 
65
47
  def each_redundant_character_class(node)
66
- pattern_source(node).scan(PATTERN) do
67
- yield match_range(node.loc.begin.end, Regexp.last_match)
48
+ each_single_element_character_class(node) do |char_class|
49
+ next unless redundant_single_element_character_class?(node, char_class)
50
+
51
+ yield node.loc.begin.adjust(begin_pos: 1 + char_class.ts, end_pos: char_class.te)
52
+ end
53
+ end
54
+
55
+ def each_single_element_character_class(node)
56
+ node.parsed_tree&.each_expression do |expr|
57
+ next if expr.type != :set || expr.expressions.size != 1
58
+ next if expr.negative?
59
+ next if %i[set posixclass nonposixclass].include?(expr.expressions.first.type)
60
+
61
+ yield expr
68
62
  end
69
63
  end
70
64
 
65
+ def redundant_single_element_character_class?(node, char_class)
66
+ class_elem = char_class.expressions.first.text
67
+
68
+ non_redundant =
69
+ whitespace_in_free_space_mode?(node, class_elem) ||
70
+ backslash_b?(class_elem) ||
71
+ requires_escape_outside_char_class?(class_elem)
72
+
73
+ !non_redundant
74
+ end
75
+
71
76
  def without_character_class(loc)
72
77
  loc.source[1..-2]
73
78
  end
74
79
 
75
- def whitespace_in_free_space_mode?(node, loc)
76
- return false unless freespace_mode_regexp?(node)
80
+ def whitespace_in_free_space_mode?(node, elem)
81
+ return false unless node.extended?
82
+
83
+ /\s/.match?(elem)
84
+ end
85
+
86
+ def backslash_b?(elem)
87
+ # \b's behaviour is different inside and outside of a character class, matching word
88
+ # boundaries outside but backspace (0x08) when inside.
89
+ elem == '\b'
90
+ end
77
91
 
78
- /\[\s\]/.match?(loc.source)
92
+ def requires_escape_outside_char_class?(elem)
93
+ REQUIRES_ESCAPE_OUTSIDE_CHAR_CLASS_CHARS.include?(elem)
79
94
  end
80
95
  end
81
96
  end
@@ -34,7 +34,6 @@ module RuboCop
34
34
  # /[+\-]\d/
35
35
  class RedundantRegexpEscape < Base
36
36
  include RangeHelp
37
- include RegexpLiteralHelp
38
37
  extend AutoCorrector
39
38
 
40
39
  MSG_REDUNDANT_ESCAPE = 'Redundant escape inside regexp literal'
@@ -59,9 +58,9 @@ module RuboCop
59
58
 
60
59
  def allowed_escape?(node, char, within_character_class)
61
60
  # Strictly speaking a few single-letter metachars are currently
62
- # unnecessary to "escape", e.g. g, i, E, F, but enumerating them is
61
+ # unnecessary to "escape", e.g. i, E, F, but enumerating them is
63
62
  # rather difficult, and their behaviour could change over time with
64
- # different versions of Ruby so that e.g. /\g/ != /g/
63
+ # different versions of Ruby so that e.g. /\i/ != /i/
65
64
  return true if /[[:alnum:]]/.match?(char)
66
65
  return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
67
66
 
@@ -82,19 +81,13 @@ module RuboCop
82
81
  end
83
82
 
84
83
  def each_escape(node)
85
- pattern_source(node).each_char.with_index.reduce(
86
- [nil, 0]
87
- ) do |(previous, char_class_depth), (current, index)|
88
- if previous == '\\'
89
- yield [current, index - 1, !char_class_depth.zero?]
90
-
91
- [nil, char_class_depth]
92
- elsif previous == '['
93
- [current, char_class_depth + 1]
94
- elsif current == ']'
95
- [current, char_class_depth - 1]
84
+ node.parsed_tree&.traverse&.reduce(0) do |char_class_depth, (event, expr)|
85
+ yield(expr.text[1], expr.ts, !char_class_depth.zero?) if expr.type == :escape
86
+
87
+ if expr.type == :set
88
+ char_class_depth + (event == :enter ? 1 : -1)
96
89
  else
97
- [current, char_class_depth]
90
+ char_class_depth
98
91
  end
99
92
  end
100
93
  end
@@ -47,8 +47,9 @@ module RuboCop
47
47
  # return x, y
48
48
  # end
49
49
  #
50
- class RedundantReturn < Cop
50
+ class RedundantReturn < Base
51
51
  include RangeHelp
52
+ extend AutoCorrector
52
53
 
53
54
  MSG = 'Redundant `return` detected.'
54
55
  MULTI_RETURN_MSG = 'To return multiple values, use an array.'
@@ -58,16 +59,6 @@ module RuboCop
58
59
  end
59
60
  alias on_defs on_def
60
61
 
61
- def autocorrect(node)
62
- lambda do |corrector|
63
- if node.arguments?
64
- correct_with_arguments(node, corrector)
65
- else
66
- correct_without_arguments(node, corrector)
67
- end
68
- end
69
- end
70
-
71
62
  private
72
63
 
73
64
  def correct_without_arguments(return_node, corrector)
@@ -108,8 +99,8 @@ module RuboCop
108
99
  when :return then check_return_node(node)
109
100
  when :case then check_case_node(node)
110
101
  when :if then check_if_node(node)
111
- when :rescue, :resbody
112
- check_rescue_node(node)
102
+ when :rescue then check_rescue_node(node)
103
+ when :resbody then check_resbody_node(node)
113
104
  when :ensure then check_ensure_node(node)
114
105
  when :begin, :kwbegin
115
106
  check_begin_node(node)
@@ -121,7 +112,13 @@ module RuboCop
121
112
  return if cop_config['AllowMultipleReturnValues'] &&
122
113
  node.children.size > 1
123
114
 
124
- add_offense(node, location: :keyword)
115
+ add_offense(node.loc.keyword, message: message(node)) do |corrector|
116
+ if node.arguments?
117
+ correct_with_arguments(node, corrector)
118
+ else
119
+ correct_without_arguments(node, corrector)
120
+ end
121
+ end
125
122
  end
126
123
 
127
124
  def check_case_node(node)
@@ -137,9 +134,12 @@ module RuboCop
137
134
  end
138
135
 
139
136
  def check_rescue_node(node)
140
- node.child_nodes.each do |child_node|
141
- check_branch(child_node)
142
- end
137
+ node.branches.each { |branch| check_branch(branch) }
138
+ check_branch(node.body) unless node.else?
139
+ end
140
+
141
+ def check_resbody_node(node)
142
+ check_branch(node.body)
143
143
  end
144
144
 
145
145
  def check_ensure_node(node)
@@ -41,7 +41,9 @@ module RuboCop
41
41
  # self.bar == bar # Resolves name clash with argument of the block.
42
42
  # end
43
43
  # end
44
- class RedundantSelf < Cop
44
+ class RedundantSelf < Base
45
+ extend AutoCorrector
46
+
45
47
  MSG = 'Redundant `self` detected.'
46
48
  KERNEL_METHODS = Kernel.methods(false)
47
49
  KEYWORDS = %i[alias and begin break case class def defined? do
@@ -106,20 +108,16 @@ module RuboCop
106
108
 
107
109
  return if allowed_send_node?(node)
108
110
 
109
- add_offense(node)
111
+ add_offense(node) do |corrector|
112
+ corrector.remove(node.receiver)
113
+ corrector.remove(node.loc.dot)
114
+ end
110
115
  end
111
116
 
112
117
  def on_block(node)
113
118
  add_scope(node, @local_variables_scopes[node])
114
119
  end
115
120
 
116
- def autocorrect(node)
117
- lambda do |corrector|
118
- corrector.remove(node.receiver)
119
- corrector.remove(node.loc.dot)
120
- end
121
- end
122
-
123
121
  private
124
122
 
125
123
  def add_scope(node, local_variables = [])
@@ -37,8 +37,8 @@ module RuboCop
37
37
  METHODS_RETURNING_SELF = %i[
38
38
  append clear collect! compare_by_identity concat delete_if
39
39
  fill initialize_copy insert keep_if map! merge! prepend push
40
- rehash replace reverse! rotate! shuffle! sort! sort_by! to_ary
41
- to_hash transform_keys! transform_values! unshift update
40
+ rehash replace reverse! rotate! shuffle! sort! sort_by!
41
+ transform_keys! transform_values! unshift update
42
42
  ].to_set.freeze
43
43
 
44
44
  ASSIGNMENT_TYPE_TO_RECEIVER_TYPE = {
@@ -49,13 +49,14 @@ module RuboCop
49
49
  # # good
50
50
  # arr.max_by(&:foo)
51
51
  #
52
- class RedundantSort < Cop
52
+ class RedundantSort < Base
53
53
  include RangeHelp
54
+ extend AutoCorrector
54
55
 
55
56
  MSG = 'Use `%<suggestion>s` instead of '\
56
57
  '`%<sorter>s...%<accessor_source>s`.'
57
58
 
58
- SORT_METHODS = %i[sort sort_by].freeze
59
+ RESTRICT_ON_SEND = %i[sort sort_by].freeze
59
60
 
60
61
  def_node_matcher :redundant_sort?, <<~MATCHER
61
62
  {
@@ -74,8 +75,6 @@ module RuboCop
74
75
  MATCHER
75
76
 
76
77
  def on_send(node)
77
- return unless sort_method?(node)
78
-
79
78
  if (sort_node, sorter, accessor = redundant_sort?(node.parent))
80
79
  ancestor = node.parent
81
80
  elsif (sort_node, sorter, accessor = redundant_sort?(node.parent&.parent))
@@ -84,37 +83,21 @@ module RuboCop
84
83
  return
85
84
  end
86
85
 
87
- add_offense(ancestor,
88
- location: offense_range(sort_node, ancestor),
89
- message: message(ancestor,
90
- sorter,
91
- accessor))
92
- end
93
-
94
- def autocorrect(node)
95
- sort_node, sorter, accessor = redundant_sort?(node)
86
+ message = message(ancestor, sorter, accessor)
96
87
 
97
- lambda do |corrector|
98
- # Remove accessor, e.g. `first` or `[-1]`.
99
- corrector.remove(
100
- range_between(
101
- accessor_start(node),
102
- node.loc.expression.end_pos
103
- )
104
- )
105
-
106
- # Replace "sort" or "sort_by" with the appropriate min/max method.
107
- corrector.replace(
108
- sort_node.loc.selector,
109
- suggestion(sorter, accessor, arg_value(node))
110
- )
88
+ add_offense(offense_range(sort_node, ancestor), message: message) do |corrector|
89
+ autocorrect(corrector, ancestor, sort_node, sorter, accessor)
111
90
  end
112
91
  end
113
92
 
114
93
  private
115
94
 
116
- def sort_method?(node)
117
- SORT_METHODS.include?(node.method_name)
95
+ def autocorrect(corrector, node, sort_node, sorter, accessor)
96
+ # Remove accessor, e.g. `first` or `[-1]`.
97
+ corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
98
+
99
+ # Replace "sort" or "sort_by" with the appropriate min/max method.
100
+ corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
118
101
  end
119
102
 
120
103
  def offense_range(sort_node, ancestor)
@@ -15,8 +15,9 @@ module RuboCop
15
15
  #
16
16
  # # good
17
17
  # array.sort
18
- class RedundantSortBy < Cop
18
+ class RedundantSortBy < Base
19
19
  include RangeHelp
20
+ extend AutoCorrector
20
21
 
21
22
  MSG = 'Use `sort` instead of `sort_by { |%<var>s| %<var>s }`.'
22
23
 
@@ -28,17 +29,12 @@ module RuboCop
28
29
  redundant_sort_by(node) do |send, var_name|
29
30
  range = sort_by_range(send, node)
30
31
 
31
- add_offense(node,
32
- location: range,
33
- message: format(MSG, var: var_name))
32
+ add_offense(range, message: format(MSG, var: var_name)) do |corrector|
33
+ corrector.replace(range, 'sort')
34
+ end
34
35
  end
35
36
  end
36
37
 
37
- def autocorrect(node)
38
- send = node.send_node
39
- ->(corrector) { corrector.replace(sort_by_range(send, node), 'sort') }
40
- end
41
-
42
38
  private
43
39
 
44
40
  def sort_by_range(send, node)
@@ -70,10 +70,11 @@ module RuboCop
70
70
  # rescue StandardError, SecurityError
71
71
  # bar
72
72
  # end
73
- class RescueStandardError < Cop
73
+ class RescueStandardError < Base
74
74
  include RescueNode
75
75
  include ConfigurableEnforcedStyle
76
76
  include RangeHelp
77
+ extend AutoCorrector
77
78
 
78
79
  MSG_IMPLICIT = 'Omit the error class when rescuing ' \
79
80
  '`StandardError` by itself.'
@@ -94,28 +95,31 @@ module RuboCop
94
95
  case style
95
96
  when :implicit
96
97
  rescue_standard_error?(node) do |error|
97
- add_offense(node,
98
- location: node.loc.keyword.join(error.loc.expression),
99
- message: MSG_IMPLICIT)
98
+ offense_for_implicit_enforced_style(node, error)
100
99
  end
101
100
  when :explicit
102
101
  rescue_without_error_class?(node) do
103
- add_offense(node, location: :keyword, message: MSG_EXPLICIT)
102
+ offense_for_exlicit_enforced_style(node)
104
103
  end
105
104
  end
106
105
  end
107
106
 
108
- def autocorrect(node)
109
- lambda do |corrector|
110
- case style
111
- when :implicit
112
- error = rescue_standard_error?(node)
113
- range = range_between(node.loc.keyword.end_pos,
114
- error.loc.expression.end_pos)
115
- corrector.remove(range)
116
- when :explicit
117
- corrector.insert_after(node.loc.keyword, ' StandardError')
118
- end
107
+ private
108
+
109
+ def offense_for_implicit_enforced_style(node, error)
110
+ range = node.loc.keyword.join(error.loc.expression)
111
+
112
+ add_offense(range, message: MSG_IMPLICIT) do |corrector|
113
+ error = rescue_standard_error?(node)
114
+ range = range_between(node.loc.keyword.end_pos, error.loc.expression.end_pos)
115
+
116
+ corrector.remove(range)
117
+ end
118
+ end
119
+
120
+ def offense_for_exlicit_enforced_style(node)
121
+ add_offense(node.loc.keyword, message: MSG_EXPLICIT) do |corrector|
122
+ corrector.insert_after(node.loc.keyword, ' StandardError')
119
123
  end
120
124
  end
121
125
  end