rubocop 0.46.0 → 0.47.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +77 -2
  4. data/config/default.yml +151 -74
  5. data/config/disabled.yml +9 -0
  6. data/config/enabled.yml +49 -9
  7. data/lib/rubocop.rb +36 -8
  8. data/lib/rubocop/ast/builder.rb +59 -0
  9. data/lib/rubocop/ast/node.rb +607 -0
  10. data/lib/rubocop/ast/node/array_node.rb +45 -0
  11. data/lib/rubocop/ast/node/case_node.rb +63 -0
  12. data/lib/rubocop/ast/node/for_node.rb +53 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +102 -0
  14. data/lib/rubocop/ast/node/if_node.rb +136 -0
  15. data/lib/rubocop/ast/node/keyword_splat_node.rb +45 -0
  16. data/lib/rubocop/ast/node/mixin/conditional_node.rb +45 -0
  17. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +125 -0
  18. data/lib/rubocop/ast/node/mixin/modifier_node.rb +17 -0
  19. data/lib/rubocop/ast/node/pair_node.rb +64 -0
  20. data/lib/rubocop/ast/node/until_node.rb +43 -0
  21. data/lib/rubocop/ast/node/when_node.rb +61 -0
  22. data/lib/rubocop/ast/node/while_node.rb +43 -0
  23. data/lib/rubocop/ast/sexp.rb +16 -0
  24. data/lib/rubocop/{ast_node → ast}/traversal.rb +1 -1
  25. data/lib/rubocop/cli.rb +18 -14
  26. data/lib/rubocop/comment_config.rb +1 -3
  27. data/lib/rubocop/config.rb +93 -35
  28. data/lib/rubocop/config_loader.rb +1 -1
  29. data/lib/rubocop/cop/badge.rb +73 -0
  30. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
  31. data/lib/rubocop/cop/bundler/ordered_gems.rb +43 -3
  32. data/lib/rubocop/cop/commissioner.rb +17 -6
  33. data/lib/rubocop/cop/cop.rb +25 -112
  34. data/lib/rubocop/cop/lint/ambiguous_operator.rb +9 -4
  35. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +7 -0
  36. data/lib/rubocop/cop/lint/assignment_in_condition.rb +18 -4
  37. data/lib/rubocop/cop/lint/block_alignment.rb +40 -9
  38. data/lib/rubocop/cop/lint/circular_argument_reference.rb +14 -0
  39. data/lib/rubocop/cop/lint/condition_position.rb +14 -16
  40. data/lib/rubocop/cop/lint/debugger.rb +28 -0
  41. data/lib/rubocop/cop/lint/def_end_alignment.rb +21 -1
  42. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +13 -1
  43. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +26 -22
  44. data/lib/rubocop/cop/lint/duplicate_methods.rb +15 -1
  45. data/lib/rubocop/cop/lint/duplicated_key.rb +16 -8
  46. data/lib/rubocop/cop/lint/each_with_object_argument.rb +9 -0
  47. data/lib/rubocop/cop/lint/else_layout.rb +26 -29
  48. data/lib/rubocop/cop/lint/empty_ensure.rb +38 -0
  49. data/lib/rubocop/cop/lint/empty_expression.rb +11 -1
  50. data/lib/rubocop/cop/lint/empty_interpolation.rb +8 -0
  51. data/lib/rubocop/cop/lint/empty_when.rb +14 -16
  52. data/lib/rubocop/cop/lint/end_alignment.rb +48 -28
  53. data/lib/rubocop/cop/lint/end_in_method.rb +23 -0
  54. data/lib/rubocop/cop/lint/ensure_return.rb +21 -0
  55. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -0
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +29 -4
  57. data/lib/rubocop/cop/lint/handle_exceptions.rb +40 -0
  58. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +7 -2
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +11 -2
  60. data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -0
  61. data/lib/rubocop/cop/lint/literal_in_condition.rb +34 -36
  62. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +8 -0
  63. data/lib/rubocop/cop/lint/loop.rb +36 -0
  64. data/lib/rubocop/cop/lint/multiple_compare.rb +46 -0
  65. data/lib/rubocop/cop/lint/nested_method_definition.rb +22 -0
  66. data/lib/rubocop/cop/lint/next_without_accumulator.rb +5 -0
  67. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -0
  68. data/lib/rubocop/cop/lint/percent_string_array.rb +27 -13
  69. data/lib/rubocop/cop/lint/percent_symbol_array.rb +14 -4
  70. data/lib/rubocop/cop/lint/rand_one.rb +7 -3
  71. data/lib/rubocop/cop/lint/require_parentheses.rb +20 -19
  72. data/lib/rubocop/cop/lint/rescue_exception.rb +20 -0
  73. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +66 -0
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -1
  75. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +24 -0
  76. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +8 -0
  77. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +24 -0
  78. data/lib/rubocop/cop/lint/unified_integer.rb +5 -0
  79. data/lib/rubocop/cop/lint/unneeded_disable.rb +2 -2
  80. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +5 -0
  81. data/lib/rubocop/cop/lint/unreachable_code.rb +17 -0
  82. data/lib/rubocop/cop/lint/unused_block_argument.rb +2 -0
  83. data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
  84. data/lib/rubocop/cop/lint/useless_access_modifier.rb +28 -1
  85. data/lib/rubocop/cop/lint/useless_assignment.rb +18 -0
  86. data/lib/rubocop/cop/lint/useless_comparison.rb +3 -1
  87. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +16 -1
  88. data/lib/rubocop/cop/lint/useless_setter_call.rb +16 -4
  89. data/lib/rubocop/cop/lint/void.rb +52 -0
  90. data/lib/rubocop/cop/message_annotator.rb +102 -0
  91. data/lib/rubocop/cop/metrics/block_length.rb +6 -0
  92. data/lib/rubocop/cop/metrics/block_nesting.rb +17 -5
  93. data/lib/rubocop/cop/metrics/line_length.rb +11 -4
  94. data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -2
  95. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -11
  96. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +12 -5
  97. data/lib/rubocop/cop/mixin/configurable_formatting.rb +48 -0
  98. data/lib/rubocop/cop/mixin/configurable_max.rb +3 -3
  99. data/lib/rubocop/cop/mixin/configurable_naming.rb +5 -33
  100. data/lib/rubocop/cop/mixin/configurable_numbering.rb +6 -47
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +7 -1
  102. data/lib/rubocop/cop/mixin/duplication.rb +46 -0
  103. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +2 -2
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +14 -11
  105. data/lib/rubocop/cop/mixin/hash_alignment.rb +114 -0
  106. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  107. data/lib/rubocop/cop/mixin/negative_conditional.rb +21 -7
  108. data/lib/rubocop/cop/mixin/on_method_def.rb +14 -0
  109. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -24
  110. data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -13
  111. data/lib/rubocop/cop/mixin/target_ruby_version.rb +16 -0
  112. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -3
  113. data/lib/rubocop/cop/offense.rb +1 -1
  114. data/lib/rubocop/cop/performance/case_when_splat.rb +56 -59
  115. data/lib/rubocop/cop/performance/detect.rb +2 -2
  116. data/lib/rubocop/cop/performance/flat_map.rb +3 -3
  117. data/lib/rubocop/cop/performance/redundant_merge.rb +3 -6
  118. data/lib/rubocop/cop/performance/regexp_match.rb +201 -0
  119. data/lib/rubocop/cop/rails/delegate.rb +2 -2
  120. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +10 -19
  121. data/lib/rubocop/cop/rails/enum_uniqueness.rb +12 -40
  122. data/lib/rubocop/cop/rails/file_path.rb +80 -0
  123. data/lib/rubocop/cop/rails/find_each.rb +5 -14
  124. data/lib/rubocop/cop/rails/http_positional_arguments.rb +30 -24
  125. data/lib/rubocop/cop/rails/not_null_column.rb +23 -0
  126. data/lib/rubocop/cop/rails/reversible_migration.rb +217 -0
  127. data/lib/rubocop/cop/rails/safe_navigation.rb +4 -2
  128. data/lib/rubocop/cop/rails/skips_model_validations.rb +46 -0
  129. data/lib/rubocop/cop/rails/time_zone.rb +1 -1
  130. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +7 -5
  131. data/lib/rubocop/cop/registry.rb +170 -0
  132. data/lib/rubocop/cop/{lint → security}/eval.rb +7 -1
  133. data/lib/rubocop/cop/security/marshal_load.rb +33 -0
  134. data/lib/rubocop/cop/security/yaml_load.rb +37 -0
  135. data/lib/rubocop/cop/style/align_hash.rb +138 -169
  136. data/lib/rubocop/cop/style/and_or.rb +1 -1
  137. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +10 -15
  138. data/lib/rubocop/cop/style/case_indentation.rb +36 -27
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +64 -47
  140. data/lib/rubocop/cop/style/each_with_object.rb +4 -1
  141. data/lib/rubocop/cop/style/else_alignment.rb +14 -20
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +16 -25
  143. data/lib/rubocop/cop/style/empty_else.rb +20 -22
  144. data/lib/rubocop/cop/style/empty_literal.rb +4 -4
  145. data/lib/rubocop/cop/style/empty_method.rb +12 -6
  146. data/lib/rubocop/cop/style/encoding.rb +1 -1
  147. data/lib/rubocop/cop/style/file_name.rb +24 -4
  148. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  149. data/lib/rubocop/cop/style/format_string.rb +17 -48
  150. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +40 -11
  151. data/lib/rubocop/cop/style/guard_clause.rb +11 -17
  152. data/lib/rubocop/cop/style/hash_syntax.rb +24 -42
  153. data/lib/rubocop/cop/style/identical_conditional_branches.rb +40 -28
  154. data/lib/rubocop/cop/style/if_inside_else.rb +6 -9
  155. data/lib/rubocop/cop/style/if_unless_modifier.rb +16 -25
  156. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -9
  157. data/lib/rubocop/cop/style/indent_array.rb +1 -1
  158. data/lib/rubocop/cop/style/indentation_width.rb +29 -60
  159. data/lib/rubocop/cop/style/infinite_loop.rb +21 -22
  160. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +86 -0
  161. data/lib/rubocop/cop/style/{method_call_parentheses.rb → method_call_without_args_parentheses.rb} +8 -1
  162. data/lib/rubocop/cop/style/missing_else.rb +40 -14
  163. data/lib/rubocop/cop/style/multiline_if_modifier.rb +5 -15
  164. data/lib/rubocop/cop/style/multiline_if_then.rb +14 -8
  165. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +3 -3
  166. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -5
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -2
  168. data/lib/rubocop/cop/style/negated_if.rb +3 -19
  169. data/lib/rubocop/cop/style/negated_while.rb +2 -17
  170. data/lib/rubocop/cop/style/nested_modifier.rb +16 -43
  171. data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -5
  172. data/lib/rubocop/cop/style/next.rb +23 -21
  173. data/lib/rubocop/cop/style/non_nil_check.rb +2 -3
  174. data/lib/rubocop/cop/style/not.rb +1 -3
  175. data/lib/rubocop/cop/style/numeric_literals.rb +2 -2
  176. data/lib/rubocop/cop/style/one_line_conditional.rb +12 -22
  177. data/lib/rubocop/cop/style/option_hash.rb +4 -15
  178. data/lib/rubocop/cop/style/parallel_assignment.rb +1 -3
  179. data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -12
  180. data/lib/rubocop/cop/style/percent_q_literals.rb +15 -12
  181. data/lib/rubocop/cop/style/redundant_freeze.rb +3 -2
  182. data/lib/rubocop/cop/style/redundant_parentheses.rb +27 -4
  183. data/lib/rubocop/cop/style/redundant_return.rb +4 -8
  184. data/lib/rubocop/cop/style/safe_navigation.rb +13 -6
  185. data/lib/rubocop/cop/style/space_after_colon.rb +2 -4
  186. data/lib/rubocop/cop/style/space_around_block_parameters.rb +1 -1
  187. data/lib/rubocop/cop/style/space_around_operators.rb +15 -13
  188. data/lib/rubocop/cop/style/string_methods.rb +1 -3
  189. data/lib/rubocop/cop/style/symbol_array.rb +1 -5
  190. data/lib/rubocop/cop/style/ternary_parentheses.rb +5 -6
  191. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +2 -5
  192. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +1 -1
  193. data/lib/rubocop/cop/style/unless_else.rb +1 -5
  194. data/lib/rubocop/cop/style/when_then.rb +4 -2
  195. data/lib/rubocop/cop/style/while_until_do.rb +9 -13
  196. data/lib/rubocop/cop/style/while_until_modifier.rb +12 -11
  197. data/lib/rubocop/cop/style/word_array.rb +5 -9
  198. data/lib/rubocop/cop/team.rb +16 -15
  199. data/lib/rubocop/cop/util.rb +13 -3
  200. data/lib/rubocop/formatter/clang_style_formatter.rb +2 -2
  201. data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
  202. data/lib/rubocop/magic_comment.rb +196 -0
  203. data/lib/rubocop/options.rb +5 -4
  204. data/lib/rubocop/processed_source.rb +1 -1
  205. data/lib/rubocop/rspec/cop_helper.rb +9 -0
  206. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  207. data/lib/rubocop/runner.rb +7 -2
  208. data/lib/rubocop/version.rb +1 -1
  209. metadata +41 -14
  210. data/lib/rubocop/ast_node.rb +0 -624
  211. data/lib/rubocop/ast_node/builder.rb +0 -30
  212. data/lib/rubocop/ast_node/sexp.rb +0 -13
  213. data/lib/rubocop/cop/mixin/hash_node.rb +0 -14
  214. data/lib/rubocop/cop/mixin/if_node.rb +0 -42
@@ -6,13 +6,18 @@ module RuboCop
6
6
  # Don't omit the accumulator when calling `next` in a `reduce` block.
7
7
  #
8
8
  # @example
9
+ #
9
10
  # # bad
11
+ #
10
12
  # result = (1..4).reduce(0) do |acc, i|
11
13
  # next if i.odd?
12
14
  # acc + i
13
15
  # end
14
16
  #
17
+ # @example
18
+ #
15
19
  # # good
20
+ #
16
21
  # result = (1..4).reduce(0) do |acc, i|
17
22
  # next acc if i.odd?
18
23
  # acc + i
@@ -8,7 +8,15 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
+ # # bad
12
+ #
11
13
  # puts (x + y)
14
+ #
15
+ # @example
16
+ #
17
+ # # good
18
+ #
19
+ # puts(x + y)
12
20
  class ParenthesesAsGroupedExpression < Cop
13
21
  MSG = '`(...)` interpreted as grouped expression.'.freeze
14
22
 
@@ -3,16 +3,30 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop checks for quotes and commas in %w, e.g.
6
+ # This cop checks for quotes and commas in %w, e.g. `%w('foo', "bar")`
7
7
  #
8
- # `%w('foo', "bar")`
9
- #
10
- # it is more likely that the additional characters are unintended (for
8
+ # It is more likely that the additional characters are unintended (for
11
9
  # example, mistranslating an array of literals to percent string notation)
12
10
  # rather than meant to be part of the resulting strings.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ #
16
+ # %w('foo', "bar")
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # %w(foo bar)
13
23
  class PercentStringArray < Cop
14
24
  include PercentLiteral
15
25
 
26
+ QUOTES_AND_COMMAS = [/,$/, /^'.*'$/, /^".*"$/].freeze
27
+ LEADING_QUOTE = /^['"]/
28
+ TRAILING_QUOTE = /['"]?,?$/
29
+
16
30
  MSG = "Within `%w`/`%W`, quotes and ',' are unnecessary and may be " \
17
31
  'unwanted in the resulting strings.'.freeze
18
32
 
@@ -29,27 +43,27 @@ module RuboCop
29
43
  private
30
44
 
31
45
  def contains_quotes_or_commas?(node)
32
- patterns = [/,$/, /^'.*'$/, /^".*"$/]
33
-
34
- node.children.any? do |child|
35
- literal = scrub_string(child.children.first.to_s)
46
+ node.values.any? do |value|
47
+ literal = scrub_string(value.children.first.to_s)
36
48
 
37
49
  # To avoid likely false positives (e.g. a single ' or ")
38
50
  next if literal.gsub(/[^\p{Alnum}]/, '').empty?
39
51
 
40
- patterns.any? { |pat| literal =~ pat }
52
+ QUOTES_AND_COMMAS.any? { |pat| literal =~ pat }
41
53
  end
42
54
  end
43
55
 
44
56
  def autocorrect(node)
45
57
  lambda do |corrector|
46
- node.children.each do |child|
47
- range = child.loc.expression
58
+ node.values.each do |value|
59
+ range = value.loc.expression
48
60
 
49
- match = /['"]?,?$/.match(range.source)
61
+ match = range.source.match(TRAILING_QUOTE)
50
62
  corrector.remove_trailing(range, match[0].length) if match
51
63
 
52
- corrector.remove_leading(range, 1) if /^['"]/ =~ range.source
64
+ if range.source =~ LEADING_QUOTE
65
+ corrector.remove_leading(range, 1)
66
+ end
53
67
  end
54
68
  end
55
69
  end
@@ -3,13 +3,23 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop checks for colons and commas in %i, e.g.
6
+ # This cop checks for colons and commas in %i, e.g. `%i(:foo, :bar)`
7
7
  #
8
- # `%i(:foo, :bar)`
9
- #
10
- # it is more likely that the additional characters are unintended (for
8
+ # It is more likely that the additional characters are unintended (for
11
9
  # example, mistranslating an array of literals to percent string notation)
12
10
  # rather than meant to be part of the resulting symbols.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ #
16
+ # %i(:foo, :bar)
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # %i(foo bar)
13
23
  class PercentSymbolArray < Cop
14
24
  include PercentLiteral
15
25
 
@@ -8,14 +8,18 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
- # @bad
11
+ # # bad
12
+ #
12
13
  # rand 1
13
14
  # Kernel.rand(-1)
14
15
  # rand 1.0
15
16
  # rand(-1.0)
16
17
  #
17
- # @good
18
- # 0
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # 0 # just use 0 instead
19
23
  class RandOne < Cop
20
24
  MSG = '`%s` always returns `0`. ' \
21
25
  'Perhaps you meant `rand(2)` or `rand`?'.freeze
@@ -14,47 +14,48 @@ module RuboCop
14
14
  #
15
15
  # @example
16
16
  #
17
+ # # bad
18
+ #
17
19
  # if day.is? :tuesday && month == :jan
18
20
  # ...
19
21
  # end
22
+ #
23
+ # @example
24
+ #
25
+ # # good
26
+ #
27
+ # if day.is?(:tuesday) && month == :jan
20
28
  class RequireParentheses < Cop
21
- include IfNode
22
-
23
29
  MSG = 'Use parentheses in the method call to avoid confusion about ' \
24
30
  'precedence.'.freeze
25
31
 
26
32
  def on_send(node)
27
33
  _receiver, method_name, *args = *node
28
34
 
29
- return if parentheses?(node)
30
- return if args.empty?
35
+ return if parentheses?(node) || args.empty?
31
36
 
32
- if ternary?(args.first)
37
+ if args.first.if_type? && args.first.ternary?
33
38
  check_ternary(args.first, node)
34
- elsif predicate?(method_name)
35
- # We're only checking predicate methods. There would be false
36
- # positives otherwise.
37
- check_send(args.last, node)
39
+ elsif method_name.to_s.end_with?('?')
40
+ check_predicate(args.last, node)
38
41
  end
39
42
  end
40
43
 
41
44
  private
42
45
 
43
- def check_ternary(arg, node)
44
- condition, = *arg
45
- return unless offense?(condition)
46
+ def check_ternary(ternary, node)
47
+ return unless offense?(ternary.condition)
48
+
49
+ range = range_between(node.source_range.begin_pos,
50
+ ternary.condition.source_range.end_pos)
46
51
 
47
- expr = node.source_range
48
- range = range_between(expr.begin_pos, condition.source_range.end_pos)
49
52
  add_offense(range, range)
50
53
  end
51
54
 
52
- def check_send(arg, node)
53
- add_offense(node, :expression) if offense?(arg)
54
- end
55
+ def check_predicate(predicate, node)
56
+ return unless offense?(predicate)
55
57
 
56
- def predicate?(method_name)
57
- method_name.to_s.end_with?('?')
58
+ add_offense(node, :expression)
58
59
  end
59
60
 
60
61
  def offense?(node)
@@ -4,6 +4,26 @@ module RuboCop
4
4
  module Cop
5
5
  module Lint
6
6
  # This cop checks for *rescue* blocks targeting the Exception class.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ #
12
+ # begin
13
+ # do_something
14
+ # rescue Exception
15
+ # handle_exception
16
+ # end
17
+ #
18
+ # @example
19
+ #
20
+ # # good
21
+ #
22
+ # begin
23
+ # do_something
24
+ # rescue ArgumentError
25
+ # handle_exception
26
+ # end
7
27
  class RescueException < Cop
8
28
  MSG = 'Avoid rescuing the `Exception` class. ' \
9
29
  'Perhaps you meant to rescue `StandardError`?'.freeze
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # The safe navigation operator returns nil if the receiver is
7
+ # nil. If you chain an ordinary method call after a safe
8
+ # navigation operator, it raises NoMethodError. We should use a
9
+ # safe navigation operator after a safe navigation operator.
10
+ # This cop checks for the problem outlined above.
11
+ #
12
+ # @example
13
+ #
14
+ # # bad
15
+ #
16
+ # x&.foo.bar
17
+ # x&.foo + bar
18
+ # x&.foo[bar]
19
+ #
20
+ # @example
21
+ #
22
+ # # good
23
+ #
24
+ # x&.foo&.bar
25
+ # x&.foo || bar
26
+ class SafeNavigationChain < Cop
27
+ extend TargetRubyVersion
28
+
29
+ MSG = 'Do not chain ordinary method call' \
30
+ ' after safe navigation operator.'.freeze
31
+
32
+ ADDITIONAL_NIL_METHODS = %i(present? blank?).freeze
33
+
34
+ def_node_matcher :bad_method?, <<-PATTERN
35
+ (send (csend ...) $_ ...)
36
+ PATTERN
37
+
38
+ minimum_target_ruby_version 2.3
39
+
40
+ def on_send(node)
41
+ bad_method?(node) do |method|
42
+ return if nil_methods.include?(method)
43
+
44
+ loc = node.loc.dot || :selector
45
+ add_offense(node, loc)
46
+ end
47
+ end
48
+
49
+ def autocorrect(node)
50
+ dot = node.loc.dot
51
+ return unless dot
52
+
53
+ lambda do |corrector|
54
+ corrector.insert_before(dot, '&')
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def nil_methods
61
+ nil.methods + ADDITIONAL_NIL_METHODS
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -8,7 +8,9 @@ module RuboCop
8
8
  # exception is rescued.
9
9
  #
10
10
  # @example
11
+ #
11
12
  # # bad
13
+ #
12
14
  # begin
13
15
  # something
14
16
  # rescue Exception
@@ -17,7 +19,10 @@ module RuboCop
17
19
  # handle_standard_error
18
20
  # end
19
21
  #
22
+ # @example
23
+ #
20
24
  # # good
25
+ #
21
26
  # begin
22
27
  # something
23
28
  # rescue StandardError
@@ -111,7 +116,7 @@ module RuboCop
111
116
  end
112
117
  end
113
118
 
114
- # @param [RuboCop::Node] rescue_group is a node of array_type
119
+ # @param [RuboCop::AST::Node] rescue_group is a node of array_type
115
120
  def rescued_exceptions(rescue_group)
116
121
  klasses = *rescue_group
117
122
  klasses.map do |klass|
@@ -7,6 +7,30 @@ module RuboCop
7
7
  # for block arguments or block local variables.
8
8
  # This is a mimic of the warning
9
9
  # "shadowing outer local variable - foo" from `ruby -cw`.
10
+ #
11
+ # @example
12
+ #
13
+ # # bad
14
+ #
15
+ # def some_method
16
+ # foo = 1
17
+ #
18
+ # 2.times do |foo| # shadowing outer `foo`
19
+ # do_something(foo)
20
+ # end
21
+ # end
22
+ #
23
+ # @example
24
+ #
25
+ # # good
26
+ #
27
+ # def some_method
28
+ # foo = 1
29
+ #
30
+ # 2.times do |bar|
31
+ # do_something(bar)
32
+ # end
33
+ # end
10
34
  class ShadowingOuterLocalVariable < Cop
11
35
  MSG = 'Shadowing outer local variable - `%s`.'.freeze
12
36
 
@@ -8,7 +8,15 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  #
11
+ # # bad
12
+ #
11
13
  # "result is #{something.to_s}"
14
+ #
15
+ # @example
16
+ #
17
+ # # good
18
+ #
19
+ # "result is #{something}"
12
20
  class StringConversionInInterpolation < Cop
13
21
  MSG_DEFAULT = 'Redundant use of `Object#to_s` in interpolation.'.freeze
14
22
  MSG_SELF = 'Use `self` instead of `Object#to_s` in ' \
@@ -5,6 +5,30 @@ module RuboCop
5
5
  module Lint
6
6
  # This cop checks for underscore-prefixed variables that are actually
7
7
  # used.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ #
13
+ # [1, 2, 3].each do |_num|
14
+ # do_something(_num)
15
+ # end
16
+ #
17
+ # @example
18
+ #
19
+ # # good
20
+ #
21
+ # [1, 2, 3].each do |num|
22
+ # do_something(num)
23
+ # end
24
+ #
25
+ # @example
26
+ #
27
+ # # good
28
+ #
29
+ # [1, 2, 3].each do |_num|
30
+ # do_something # not using `_num`
31
+ # end
8
32
  class UnderscorePrefixedVariableName < Cop
9
33
  MSG = 'Do not use prefix `_` for a variable that is used.'.freeze
10
34
 
@@ -6,11 +6,16 @@ module RuboCop
6
6
  # This cop checks for using Fixnum or Bignum constant.
7
7
  #
8
8
  # @example
9
+ #
9
10
  # # bad
11
+ #
10
12
  # 1.is_a?(Fixnum)
11
13
  # 1.is_a?(Bignum)
12
14
  #
15
+ # @example
16
+ #
13
17
  # # good
18
+ #
14
19
  # 1.is_a?(Integer)
15
20
  class UnifiedInteger < Cop
16
21
  MSG = 'Use `Integer` instead of `%s`.'.freeze