rubocop 0.47.1 → 0.48.0

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.

Potentially problematic release.


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

Files changed (242) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -16
  3. data/config/default.yml +203 -115
  4. data/config/disabled.yml +0 -5
  5. data/config/enabled.yml +92 -8
  6. data/lib/rubocop.rb +24 -1
  7. data/lib/rubocop/ast/builder.rb +7 -2
  8. data/lib/rubocop/ast/node.rb +23 -20
  9. data/lib/rubocop/ast/node/and_node.rb +37 -0
  10. data/lib/rubocop/ast/node/array_node.rb +4 -1
  11. data/lib/rubocop/ast/node/case_node.rb +1 -0
  12. data/lib/rubocop/ast/node/ensure_node.rb +25 -0
  13. data/lib/rubocop/ast/node/hash_node.rb +10 -3
  14. data/lib/rubocop/ast/node/if_node.rb +2 -0
  15. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +23 -0
  16. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +35 -0
  17. data/lib/rubocop/ast/node/or_node.rb +37 -0
  18. data/lib/rubocop/ast/node/resbody_node.rb +25 -0
  19. data/lib/rubocop/ast/node/send_node.rb +190 -0
  20. data/lib/rubocop/ast/node/when_node.rb +1 -1
  21. data/lib/rubocop/ast/traversal.rb +15 -15
  22. data/lib/rubocop/comment_config.rb +1 -1
  23. data/lib/rubocop/config.rb +39 -15
  24. data/lib/rubocop/config_loader.rb +34 -13
  25. data/lib/rubocop/cop/bundler/ordered_gems.rb +23 -4
  26. data/lib/rubocop/cop/commissioner.rb +4 -0
  27. data/lib/rubocop/cop/cop.rb +5 -0
  28. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +53 -0
  29. data/lib/rubocop/cop/lint/debugger.rb +8 -1
  30. data/lib/rubocop/cop/lint/def_end_alignment.rb +2 -1
  31. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +2 -4
  32. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  33. data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -1
  34. data/lib/rubocop/cop/lint/empty_ensure.rb +6 -2
  35. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  36. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +20 -18
  37. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -3
  38. data/lib/rubocop/cop/lint/literal_in_condition.rb +1 -1
  39. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  40. data/lib/rubocop/cop/lint/multiple_compare.rb +5 -3
  41. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +26 -18
  42. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +7 -8
  43. data/lib/rubocop/cop/lint/require_parentheses.rb +7 -13
  44. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +7 -3
  45. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -6
  46. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -8
  47. data/lib/rubocop/cop/lint/unneeded_disable.rb +35 -11
  48. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +1 -1
  49. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -2
  50. data/lib/rubocop/cop/lint/unused_block_argument.rb +6 -6
  51. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
  52. data/lib/rubocop/cop/lint/useless_comparison.rb +5 -4
  53. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  54. data/lib/rubocop/cop/message_annotator.rb +7 -3
  55. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  56. data/lib/rubocop/cop/metrics/block_nesting.rb +4 -4
  57. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -2
  58. data/lib/rubocop/cop/metrics/line_length.rb +2 -9
  59. data/lib/rubocop/cop/metrics/parameter_lists.rb +4 -3
  60. data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -2
  61. data/lib/rubocop/cop/mixin/access_modifier_node.rb +1 -1
  62. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +2 -2
  63. data/lib/rubocop/cop/mixin/check_assignment.rb +6 -6
  64. data/lib/rubocop/cop/mixin/duplication.rb +1 -1
  65. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  66. data/lib/rubocop/cop/mixin/ignored_pattern.rb +27 -0
  67. data/lib/rubocop/cop/mixin/method_preference.rb +2 -0
  68. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +17 -29
  69. data/lib/rubocop/cop/mixin/on_method_def.rb +3 -3
  70. data/lib/rubocop/cop/mixin/percent_literal.rb +27 -0
  71. data/lib/rubocop/cop/mixin/rescue_node.rb +21 -0
  72. data/lib/rubocop/cop/mixin/safe_mode.rb +1 -1
  73. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
  74. data/lib/rubocop/cop/mixin/statement_modifier.rb +2 -1
  75. data/lib/rubocop/cop/mixin/target_rails_version.rb +16 -0
  76. data/lib/rubocop/cop/mixin/unused_argument.rb +1 -1
  77. data/lib/rubocop/cop/offense.rb +3 -3
  78. data/lib/rubocop/cop/performance/casecmp.rb +1 -1
  79. data/lib/rubocop/cop/performance/detect.rb +2 -1
  80. data/lib/rubocop/cop/performance/double_start_end_with.rb +35 -1
  81. data/lib/rubocop/cop/performance/end_with.rb +3 -1
  82. data/lib/rubocop/cop/performance/flat_map.rb +6 -6
  83. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -2
  84. data/lib/rubocop/cop/performance/range_include.rb +3 -1
  85. data/lib/rubocop/cop/performance/redundant_match.rb +6 -5
  86. data/lib/rubocop/cop/performance/regexp_match.rb +10 -3
  87. data/lib/rubocop/cop/performance/reverse_each.rb +2 -1
  88. data/lib/rubocop/cop/performance/size.rb +6 -11
  89. data/lib/rubocop/cop/performance/start_with.rb +3 -1
  90. data/lib/rubocop/cop/performance/string_replacement.rb +13 -18
  91. data/lib/rubocop/cop/performance/times_map.rb +4 -4
  92. data/lib/rubocop/cop/rails/action_filter.rb +42 -42
  93. data/lib/rubocop/cop/rails/active_support_aliases.rb +68 -0
  94. data/lib/rubocop/cop/rails/blank.rb +131 -0
  95. data/lib/rubocop/cop/rails/date.rb +25 -28
  96. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +5 -7
  97. data/lib/rubocop/cop/rails/dynamic_find_by.rb +7 -3
  98. data/lib/rubocop/cop/rails/exit.rb +9 -9
  99. data/lib/rubocop/cop/rails/file_path.rb +5 -14
  100. data/lib/rubocop/cop/rails/find_by.rb +8 -10
  101. data/lib/rubocop/cop/rails/find_each.rb +6 -9
  102. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +1 -0
  103. data/lib/rubocop/cop/rails/http_positional_arguments.rb +15 -7
  104. data/lib/rubocop/cop/rails/output.rb +3 -5
  105. data/lib/rubocop/cop/rails/output_safety.rb +4 -8
  106. data/lib/rubocop/cop/rails/pluralization_grammar.rb +25 -24
  107. data/lib/rubocop/cop/rails/present.rb +137 -0
  108. data/lib/rubocop/cop/rails/read_write_attribute.rb +9 -18
  109. data/lib/rubocop/cop/rails/relative_date_constant.rb +53 -0
  110. data/lib/rubocop/cop/rails/request_referer.rb +7 -4
  111. data/lib/rubocop/cop/rails/reversible_migration.rb +1 -2
  112. data/lib/rubocop/cop/rails/safe_navigation.rb +2 -1
  113. data/lib/rubocop/cop/rails/save_bang.rb +10 -10
  114. data/lib/rubocop/cop/rails/skips_model_validations.rb +23 -6
  115. data/lib/rubocop/cop/rails/time_zone.rb +20 -18
  116. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +3 -2
  117. data/lib/rubocop/cop/rails/validation.rb +8 -11
  118. data/lib/rubocop/cop/registry.rb +3 -3
  119. data/lib/rubocop/cop/security/json_load.rb +1 -1
  120. data/lib/rubocop/cop/security/marshal_load.rb +5 -1
  121. data/lib/rubocop/cop/security/yaml_load.rb +3 -3
  122. data/lib/rubocop/cop/severity.rb +1 -1
  123. data/lib/rubocop/cop/style/alias.rb +5 -5
  124. data/lib/rubocop/cop/style/align_hash.rb +1 -1
  125. data/lib/rubocop/cop/style/align_parameters.rb +5 -5
  126. data/lib/rubocop/cop/style/and_or.rb +16 -31
  127. data/lib/rubocop/cop/style/attr.rb +14 -8
  128. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +8 -11
  129. data/lib/rubocop/cop/style/block_delimiters.rb +11 -13
  130. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +19 -23
  131. data/lib/rubocop/cop/style/case_indentation.rb +2 -0
  132. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  133. data/lib/rubocop/cop/style/class_check.rb +5 -7
  134. data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +5 -4
  135. data/lib/rubocop/cop/style/collection_methods.rb +8 -8
  136. data/lib/rubocop/cop/style/colon_method_call.rb +2 -9
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +38 -45
  138. data/lib/rubocop/cop/style/constant_name.rb +1 -1
  139. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  140. data/lib/rubocop/cop/style/dot_position.rb +3 -7
  141. data/lib/rubocop/cop/style/double_negation.rb +2 -1
  142. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  143. data/lib/rubocop/cop/style/empty_else.rb +2 -2
  144. data/lib/rubocop/cop/style/empty_line_after_magic_comment.rb +63 -0
  145. data/lib/rubocop/cop/style/empty_line_between_defs.rb +74 -4
  146. data/lib/rubocop/cop/style/empty_lines_around_begin_body.rb +42 -0
  147. data/lib/rubocop/cop/style/empty_lines_around_exception_handling_keywords.rb +127 -0
  148. data/lib/rubocop/cop/style/empty_literal.rb +17 -9
  149. data/lib/rubocop/cop/style/end_of_line.rb +25 -3
  150. data/lib/rubocop/cop/style/file_name.rb +1 -1
  151. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +1 -1
  152. data/lib/rubocop/cop/style/first_parameter_indentation.rb +17 -19
  153. data/lib/rubocop/cop/style/for.rb +2 -4
  154. data/lib/rubocop/cop/style/format_string.rb +5 -4
  155. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/identical_conditional_branches.rb +27 -1
  157. data/lib/rubocop/cop/style/if_unless_modifier.rb +2 -2
  158. data/lib/rubocop/cop/style/indent_assignment.rb +2 -2
  159. data/lib/rubocop/cop/style/indent_hash.rb +2 -1
  160. data/lib/rubocop/cop/style/indent_heredoc.rb +173 -0
  161. data/lib/rubocop/cop/style/indentation_width.rb +61 -29
  162. data/lib/rubocop/cop/style/inverse_methods.rb +130 -0
  163. data/lib/rubocop/cop/style/lambda_call.rb +15 -11
  164. data/lib/rubocop/cop/style/line_end_concatenation.rb +4 -4
  165. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -14
  166. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -16
  167. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  168. data/lib/rubocop/cop/style/missing_else.rb +4 -3
  169. data/lib/rubocop/cop/style/mixin_grouping.rb +97 -0
  170. data/lib/rubocop/cop/style/multiline_memoization.rb +38 -5
  171. data/lib/rubocop/cop/style/multiline_method_call_brace_layout.rb +2 -3
  172. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +38 -19
  173. data/lib/rubocop/cop/style/mutable_constant.rb +5 -1
  174. data/lib/rubocop/cop/style/negated_if.rb +73 -1
  175. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +21 -19
  176. data/lib/rubocop/cop/style/next.rb +5 -5
  177. data/lib/rubocop/cop/style/non_nil_check.rb +7 -10
  178. data/lib/rubocop/cop/style/not.rb +3 -4
  179. data/lib/rubocop/cop/style/numeric_literals.rb +25 -3
  180. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -1
  181. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  182. data/lib/rubocop/cop/style/op_method.rb +2 -2
  183. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -3
  184. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +52 -6
  185. data/lib/rubocop/cop/style/perl_backrefs.rb +1 -1
  186. data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -9
  187. data/lib/rubocop/cop/style/raise_args.rb +28 -24
  188. data/lib/rubocop/cop/style/redundant_freeze.rb +5 -7
  189. data/lib/rubocop/cop/style/redundant_parentheses.rb +2 -3
  190. data/lib/rubocop/cop/style/redundant_self.rb +17 -35
  191. data/lib/rubocop/cop/style/rescue_modifier.rb +2 -14
  192. data/lib/rubocop/cop/style/self_assignment.rb +3 -3
  193. data/lib/rubocop/cop/style/send.rb +4 -5
  194. data/lib/rubocop/cop/style/space_after_not.rb +7 -8
  195. data/lib/rubocop/cop/style/space_around_keyword.rb +8 -9
  196. data/lib/rubocop/cop/style/space_around_operators.rb +19 -15
  197. data/lib/rubocop/cop/style/space_before_first_arg.rb +17 -14
  198. data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -1
  199. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +3 -3
  200. data/lib/rubocop/cop/style/space_inside_parens.rb +1 -1
  201. data/lib/rubocop/cop/style/special_global_vars.rb +14 -14
  202. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +2 -1
  203. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  204. data/lib/rubocop/cop/style/string_methods.rb +10 -5
  205. data/lib/rubocop/cop/style/struct_inheritance.rb +4 -15
  206. data/lib/rubocop/cop/style/symbol_array.rb +31 -35
  207. data/lib/rubocop/cop/style/symbol_proc.rb +2 -2
  208. data/lib/rubocop/cop/style/ternary_parentheses.rb +41 -13
  209. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +6 -9
  210. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +4 -1
  211. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  212. data/lib/rubocop/cop/style/unneeded_capital_w.rb +1 -2
  213. data/lib/rubocop/cop/style/unneeded_percent_q.rb +1 -1
  214. data/lib/rubocop/cop/style/word_array.rb +12 -34
  215. data/lib/rubocop/cop/style/zero_length_predicate.rb +11 -4
  216. data/lib/rubocop/cop/team.rb +4 -1
  217. data/lib/rubocop/cop/util.rb +33 -26
  218. data/lib/rubocop/cop/variable_force.rb +13 -13
  219. data/lib/rubocop/cop/variable_force/assignment.rb +1 -8
  220. data/lib/rubocop/cop/variable_force/branch.rb +318 -0
  221. data/lib/rubocop/cop/variable_force/branchable.rb +21 -0
  222. data/lib/rubocop/cop/variable_force/reference.rb +1 -3
  223. data/lib/rubocop/cop/variable_force/scope.rb +36 -20
  224. data/lib/rubocop/cop/variable_force/variable.rb +9 -8
  225. data/lib/rubocop/formatter/colorizable.rb +10 -10
  226. data/lib/rubocop/formatter/formatter_set.rb +1 -1
  227. data/lib/rubocop/formatter/html_formatter.rb +2 -1
  228. data/lib/rubocop/formatter/simple_text_formatter.rb +4 -2
  229. data/lib/rubocop/magic_comment.rb +20 -6
  230. data/lib/rubocop/options.rb +1 -1
  231. data/lib/rubocop/platform.rb +11 -0
  232. data/lib/rubocop/processed_source.rb +1 -1
  233. data/lib/rubocop/remote_config.rb +18 -6
  234. data/lib/rubocop/result_cache.rb +8 -8
  235. data/lib/rubocop/rspec/cop_helper.rb +2 -0
  236. data/lib/rubocop/rspec/shared_contexts.rb +20 -0
  237. data/lib/rubocop/rspec/shared_examples.rb +1 -1
  238. data/lib/rubocop/runner.rb +2 -2
  239. data/lib/rubocop/target_finder.rb +64 -6
  240. data/lib/rubocop/version.rb +2 -4
  241. metadata +27 -4
  242. data/lib/rubocop/cop/variable_force/locatable.rb +0 -200
@@ -46,7 +46,7 @@ module RuboCop
46
46
  expr = node.source_range
47
47
 
48
48
  lambda do |corrector|
49
- if node.array_type? && !node.square_brackets?
49
+ if unbracketed_array?(node)
50
50
  corrector.insert_before(expr, '[')
51
51
  corrector.insert_after(expr, '].freeze')
52
52
  else
@@ -55,6 +55,10 @@ module RuboCop
55
55
  end
56
56
  end
57
57
 
58
+ def unbracketed_array?(node)
59
+ node.array_type? && !node.square_brackets? && !node.percent_literal?
60
+ end
61
+
58
62
  def_node_matcher :splat_value, <<-PATTERN
59
63
  (array (splat $_))
60
64
  PATTERN
@@ -4,14 +4,86 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # Checks for uses of if with a negated condition. Only ifs
7
- # without else are considered.
7
+ # without else are considered. There are three different styles:
8
+ #
9
+ # - both
10
+ # - prefix
11
+ # - postfix
12
+ #
13
+ # @example
14
+ #
15
+ # # EnforcedStyle: both
16
+ # # enforces `unless` for `prefix` and `postfix` conditionals
17
+ #
18
+ # # good
19
+ #
20
+ # unless foo
21
+ # bar
22
+ # end
23
+ #
24
+ # # bad
25
+ #
26
+ # if !foo
27
+ # bar
28
+ # end
29
+ #
30
+ # # good
31
+ #
32
+ # bar unless foo
33
+ #
34
+ # # bad
35
+ #
36
+ # bar if !foo
37
+ #
38
+ # @example
39
+ #
40
+ # # EnforcedStyle: prefix
41
+ # # enforces `unless` for just `prefix` conditionals
42
+ #
43
+ # # good
44
+ #
45
+ # unless foo
46
+ # bar
47
+ # end
48
+ #
49
+ # # bad
50
+ #
51
+ # if !foo
52
+ # bar
53
+ # end
54
+ #
55
+ # # good
56
+ #
57
+ # bar if !foo
58
+ #
59
+ # @example
60
+ #
61
+ # # EnforcedStyle: postfix
62
+ # # enforces `unless` for just `postfix` conditionals
63
+ #
64
+ # # good
65
+ #
66
+ # bar unless foo
67
+ #
68
+ # # bad
69
+ #
70
+ # bar if !foo
71
+ #
72
+ # # good
73
+ #
74
+ # if !foo
75
+ # bar
76
+ # end
8
77
  class NegatedIf < Cop
78
+ include ConfigurableEnforcedStyle
9
79
  include NegativeConditional
10
80
 
11
81
  MSG = 'Favor `%s` over `%s` for negative conditions.'.freeze
12
82
 
13
83
  def on_if(node)
14
84
  return if node.elsif? || node.ternary?
85
+ return if style == :prefix && node.modifier_form?
86
+ return if style == :postfix && !node.modifier_form?
15
87
 
16
88
  check_negative_conditional(node)
17
89
  end
@@ -14,39 +14,41 @@ module RuboCop
14
14
  # method1(method2 arg, method3, arg)
15
15
  class NestedParenthesizedCalls < Cop
16
16
  MSG = 'Add parentheses to nested method call `%s`.'.freeze
17
- RSPEC_MATCHERS = [:be, :eq, :eql, :equal, :be_kind_of, :be_instance_of,
18
- :respond_to, :be_between, :match, :be_within,
19
- :start_with, :end_with, :include, :raise_error].freeze
17
+ RSPEC_MATCHERS = %i(be eq eql equal be_kind_of be_instance_of
18
+ respond_to be_between match be_within
19
+ start_with end_with include raise_error).freeze
20
20
 
21
21
  def on_send(node)
22
- return unless parenthesized_call?(node)
22
+ return unless node.parenthesized?
23
23
 
24
24
  node.each_child_node(:send) do |nested|
25
- next if nested.method_args.empty? ||
26
- parenthesized_call?(nested) ||
27
- operator?(nested.method_name) ||
28
- rspec_matcher?(node, nested) ||
29
- nested.asgn_method_call?
25
+ next if allowed_omission?(nested)
26
+
30
27
  add_offense(nested, nested.source_range, format(MSG, nested.source))
31
28
  end
32
29
  end
33
30
 
34
31
  private
35
32
 
36
- def rspec_matcher?(parent, send)
37
- parent.method_args.one? && # .to, .not_to, etc
38
- RSPEC_MATCHERS.include?(send.method_name) &&
39
- send.method_args.one?
33
+ def allowed_omission?(send_node)
34
+ !send_node.arguments? || send_node.parenthesized? ||
35
+ send_node.setter_method? || send_node.operator_method? ||
36
+ rspec_matcher?(send_node)
40
37
  end
41
38
 
42
- def autocorrect(nested)
43
- _scope, _method_name, *args = *nested
39
+ # TODO: Relegate this from RuboCop core
40
+ def rspec_matcher?(send_node)
41
+ send_node.parent.arguments.one? && # .to, .not_to, etc
42
+ RSPEC_MATCHERS.include?(send_node.method_name) &&
43
+ send_node.arguments.one?
44
+ end
44
45
 
45
- first_arg = args.first.source_range
46
- last_arg = args.last.source_range
46
+ def autocorrect(nested)
47
+ first_arg = nested.first_argument.source_range
48
+ last_arg = nested.last_argument.source_range
47
49
 
48
- first_arg_with_space = range_with_surrounding_space(first_arg, :left)
49
- leading_space = first_arg_with_space.begin.resize(1)
50
+ leading_space =
51
+ range_with_surrounding_space(first_arg, :left).begin.resize(1)
50
52
 
51
53
  lambda do |corrector|
52
54
  corrector.replace(leading_space, '(')
@@ -23,12 +23,12 @@ module RuboCop
23
23
  include MinBodyLength
24
24
 
25
25
  MSG = 'Use `next` to skip iteration.'.freeze
26
- EXIT_TYPES = [:break, :return].freeze
26
+ EXIT_TYPES = %i(break return).freeze
27
27
  EACH_ = 'each_'.freeze
28
- ENUMERATORS = [:collect, :collect_concat, :detect, :downto, :each,
29
- :find, :find_all, :find_index, :inject, :loop, :map!,
30
- :map, :reduce, :reject, :reject!, :reverse_each, :select,
31
- :select!, :times, :upto].freeze
28
+ ENUMERATORS = %i(collect collect_concat detect downto each
29
+ find find_all find_index inject loop map!
30
+ map reduce reject reject! reverse_each select
31
+ select! times upto).freeze
32
32
 
33
33
  def investigate(_processed_source)
34
34
  # When correcting nested offenses, we need to keep track of how much
@@ -46,13 +46,13 @@ module RuboCop
46
46
 
47
47
  def unless_and_nil_check?(send_node)
48
48
  parent = send_node.parent
49
+
49
50
  nil_check?(send_node) && unless_check?(parent) && !parent.ternary? &&
50
51
  parent.unless?
51
52
  end
52
53
 
53
54
  def message(node)
54
- _receiver, method, _args = *node
55
- if method == :!=
55
+ if node.method?(:!=)
56
56
  'Prefer `!expression.nil?` over `expression != nil`.'
57
57
  else
58
58
  'Explicit non-nil checks are usually redundant.'
@@ -75,15 +75,13 @@ module RuboCop
75
75
  end
76
76
 
77
77
  def autocorrect(node)
78
- receiver, method, _args = *node
79
-
80
- case method
78
+ case node.method_name
81
79
  when :!=
82
80
  autocorrect_comparison(node)
83
81
  when :!
84
- autocorrect_non_nil(node, receiver)
82
+ autocorrect_non_nil(node, node.receiver)
85
83
  when :nil?
86
- autocorrect_unless_nil(node, receiver)
84
+ autocorrect_unless_nil(node, node.receiver)
87
85
  end
88
86
  end
89
87
 
@@ -103,9 +101,8 @@ module RuboCop
103
101
 
104
102
  def autocorrect_non_nil(node, inner_node)
105
103
  lambda do |corrector|
106
- receiver, _method, _args = *inner_node
107
- if receiver
108
- corrector.replace(node.source_range, receiver.source)
104
+ if inner_node.receiver
105
+ corrector.replace(node.source_range, inner_node.receiver.source)
109
106
  else
110
107
  corrector.replace(node.source_range, 'self')
111
108
  end
@@ -26,11 +26,10 @@ module RuboCop
26
26
 
27
27
  def autocorrect(node)
28
28
  range = range_with_surrounding_space(node.loc.selector, :right)
29
- child = node.children.first
30
29
 
31
- if opposite_method?(child)
32
- correct_opposite_method(range, child)
33
- elsif requires_parens?(child)
30
+ if opposite_method?(node.receiver)
31
+ correct_opposite_method(range, node.receiver)
32
+ elsif requires_parens?(node.receiver)
34
33
  correct_with_parens(range, node)
35
34
  else
36
35
  correct_without_parens(range)
@@ -5,6 +5,24 @@ module RuboCop
5
5
  module Style
6
6
  # This cop checks for big numeric literals without _ between groups
7
7
  # of digits in them.
8
+ #
9
+ # @example
10
+ #
11
+ # # bad
12
+ #
13
+ # 1000000
14
+ # 1_00_000
15
+ # 1_0000
16
+ #
17
+ # # good
18
+ #
19
+ # 1_000_000
20
+ # 1000
21
+ #
22
+ # # good unless Strict is set
23
+ #
24
+ # 10_000_00 # typical representation of $10,000 in cents
25
+ #
8
26
  class NumericLiterals < Cop
9
27
  # The parameter is called MinDigits (meaning the minimum number of
10
28
  # digits for which an offense can be registered), but essentially it's
@@ -12,8 +30,8 @@ module RuboCop
12
30
  include ConfigurableMax
13
31
  include IntegerNode
14
32
 
15
- MSG = 'Separate every 3 digits in the integer portion of a number ' \
16
- 'with underscores(_).'.freeze
33
+ MSG = 'Use underscores(_) as decimal mark and ' \
34
+ 'separate every 3 digits with them.'.freeze
17
35
 
18
36
  def on_int(node)
19
37
  check(node)
@@ -39,13 +57,17 @@ module RuboCop
39
57
  case int
40
58
  when /^\d+$/
41
59
  add_offense(node, :expression) { self.max = int.size + 1 }
42
- when /\d{4}/, /_\d{1,2}(_|$)/
60
+ when /\d{4}/, short_group_regex
43
61
  add_offense(node, :expression) do
44
62
  self.config_to_allow_offenses = { 'Enabled' => false }
45
63
  end
46
64
  end
47
65
  end
48
66
 
67
+ def short_group_regex
68
+ cop_config['Strict'] ? /_\d{1,2}(_|$)/ : /_\d{1,2}_/
69
+ end
70
+
49
71
  def autocorrect(node)
50
72
  lambda do |corrector|
51
73
  corrector.replace(node.source_range, format_number(node))
@@ -108,7 +108,7 @@ module RuboCop
108
108
  end
109
109
 
110
110
  def replacement_supported?(operator)
111
- if [:>, :<].include?(operator)
111
+ if %i(> <).include?(operator)
112
112
  target_ruby_version >= 2.3
113
113
  else
114
114
  true
@@ -26,7 +26,7 @@ module RuboCop
26
26
  def replacement(node)
27
27
  return to_ternary(node) unless node.parent
28
28
 
29
- if [:and, :or].include?(node.parent.type)
29
+ if %i(and or).include?(node.parent.type)
30
30
  return "(#{to_ternary(node)})"
31
31
  end
32
32
 
@@ -48,7 +48,7 @@ module RuboCop
48
48
  end
49
49
 
50
50
  def requires_parentheses?(node)
51
- return true if [:and, :or, :if].include?(node.type)
51
+ return true if %i(and or if).include?(node.type)
52
52
  return true if node.assignment?
53
53
  return true if method_call_with_changed_precedence?(node)
54
54
 
@@ -17,8 +17,8 @@ module RuboCop
17
17
  MSG = 'When defining the `%s` operator, ' \
18
18
  'name its argument `other`.'.freeze
19
19
 
20
- OP_LIKE_METHODS = [:eql?, :equal?].freeze
21
- BLACKLISTED = [:+@, :-@, :[], :[]=, :<<, :`].freeze
20
+ OP_LIKE_METHODS = %i(eql? equal?).freeze
21
+ BLACKLISTED = %i(+@ -@ [] []= << `).freeze
22
22
 
23
23
  def_node_matcher :op_method_candidate?, <<-PATTERN
24
24
  (def $_ (args $(arg [!:other !:_other])) _)
@@ -23,6 +23,8 @@ module RuboCop
23
23
  # b = 2
24
24
  # c = 3
25
25
  class ParallelAssignment < Cop
26
+ include RescueNode
27
+
26
28
  MSG = 'Do not use parallel assignment.'.freeze
27
29
 
28
30
  def on_masgn(node)
@@ -80,9 +82,10 @@ module RuboCop
80
82
  end
81
83
 
82
84
  def assignment_corrector(node, order)
85
+ _assignment, modifier = *node.parent
83
86
  if modifier_statement?(node.parent)
84
87
  ModifierCorrector.new(node, config, order)
85
- elsif rescue_modifier?(node.parent)
88
+ elsif rescue_modifier?(modifier)
86
89
  RescueCorrector.new(node, config, order)
87
90
  else
88
91
  GenericCorrector.new(node, config, order)
@@ -149,7 +152,7 @@ module RuboCop
149
152
  # `lhs` is an assignment method call like `obj.attr=` or `ary[idx]=`.
150
153
  # Does `rhs` access the same value which is assigned by `lhs`?
151
154
  def accesses?(rhs, lhs)
152
- if lhs.method_name == :[]=
155
+ if lhs.method?(:[]=)
153
156
  matching_calls(rhs, lhs.receiver, :[]).any? do |args|
154
157
  args == lhs.method_args
155
158
  end
@@ -172,7 +175,7 @@ module RuboCop
172
175
  node.modifier_form?
173
176
  end
174
177
 
175
- def rescue_modifier?(node)
178
+ def rescue_modifier_old?(node)
176
179
  node && node.rescue_type? &&
177
180
  (node.parent.nil? || !(node.parent.kwbegin_type? ||
178
181
  node.parent.ensure_type?))
@@ -4,9 +4,30 @@ module RuboCop
4
4
  module Cop
5
5
  module Style
6
6
  # This cop enforces the consistent usage of `%`-literal delimiters.
7
+ #
8
+ # Specify the 'default' key to set all preferred delimiters at once. You
9
+ # can continue to specify individual preferred delimiters to override the
10
+ # default.
11
+ #
12
+ # @example
13
+ # # Style/PercentLiteralDelimiters:
14
+ # # PreferredDelimiters:
15
+ # # default: ()
16
+ # # %i: []
17
+ #
18
+ # # good
19
+ # %w(alpha beta) + %i[gamma delta]
20
+ #
21
+ # # bad
22
+ # %W[alpha #{beta}]
23
+ #
24
+ # # bad
25
+ # %I[alpha beta]
7
26
  class PercentLiteralDelimiters < Cop
8
27
  include PercentLiteral
9
28
 
29
+ PERCENT_LITERAL_TYPES = %w(% %i %I %q %Q %r %s %w %W %x).freeze
30
+
10
31
  def on_array(node)
11
32
  process(node, '%w', '%W', '%i', '%I')
12
33
  end
@@ -30,7 +51,7 @@ module RuboCop
30
51
 
31
52
  def message(node)
32
53
  type = type(node)
33
- delimiters = preferred_delimiters(type)
54
+ delimiters = preferred_delimiters_for(type)
34
55
 
35
56
  "`#{type}`-literals should be delimited by " \
36
57
  "`#{delimiters[0]}` and `#{delimiters[1]}`."
@@ -41,7 +62,7 @@ module RuboCop
41
62
  def autocorrect(node)
42
63
  type = type(node)
43
64
 
44
- opening_delimiter, closing_delimiter = preferred_delimiters(type)
65
+ opening_delimiter, closing_delimiter = preferred_delimiters_for(type)
45
66
 
46
67
  lambda do |corrector|
47
68
  corrector.replace(node.loc.begin, "#{type}#{opening_delimiter}")
@@ -57,16 +78,41 @@ module RuboCop
57
78
  add_offense(node, :expression)
58
79
  end
59
80
 
60
- def preferred_delimiters(type)
61
- cop_config['PreferredDelimiters'][type].split(//)
81
+ def preferred_delimiters
82
+ @preferred_delimiters ||=
83
+ begin
84
+ ensure_valid_preferred_delimiters
85
+
86
+ if cop_config['PreferredDelimiters'].key?('default')
87
+ Hash[PERCENT_LITERAL_TYPES.map do |type|
88
+ [type, cop_config['PreferredDelimiters'][type] ||
89
+ cop_config['PreferredDelimiters']['default']]
90
+ end]
91
+ else
92
+ cop_config['PreferredDelimiters']
93
+ end
94
+ end
95
+ end
96
+
97
+ def ensure_valid_preferred_delimiters
98
+ invalid = cop_config['PreferredDelimiters'].keys -
99
+ (PERCENT_LITERAL_TYPES + %w(default))
100
+ return if invalid.empty?
101
+
102
+ raise ArgumentError,
103
+ "Invalid preferred delimiter config key: #{invalid.join(', ')}"
104
+ end
105
+
106
+ def preferred_delimiters_for(type)
107
+ preferred_delimiters[type].split(//)
62
108
  end
63
109
 
64
110
  def uses_preferred_delimiter?(node, type)
65
- preferred_delimiters(type)[0] == begin_source(node)[-1]
111
+ preferred_delimiters_for(type)[0] == begin_source(node)[-1]
66
112
  end
67
113
 
68
114
  def contains_preferred_delimiter?(node, type)
69
- preferred_delimiters = preferred_delimiters(type)
115
+ preferred_delimiters = preferred_delimiters_for(type)
70
116
  node
71
117
  .children.map { |n| string_source(n) }.compact
72
118
  .any? { |s| preferred_delimiters.any? { |d| s.include?(d) } }