rubocop 1.32.0 → 1.37.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.
Files changed (189) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +104 -16
  4. data/config/obsoletion.yml +23 -1
  5. data/lib/rubocop/arguments_env.rb +17 -0
  6. data/lib/rubocop/arguments_file.rb +17 -0
  7. data/lib/rubocop/cache_config.rb +29 -0
  8. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
  9. data/lib/rubocop/cli/command/execute_runner.rb +7 -7
  10. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  11. data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
  12. data/lib/rubocop/config.rb +1 -1
  13. data/lib/rubocop/config_finder.rb +68 -0
  14. data/lib/rubocop/config_loader.rb +12 -40
  15. data/lib/rubocop/config_loader_resolver.rb +1 -5
  16. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  17. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  18. data/lib/rubocop/config_obsoletion.rb +7 -2
  19. data/lib/rubocop/cop/cop.rb +1 -1
  20. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
  21. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  22. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  23. data/lib/rubocop/cop/generator.rb +1 -2
  24. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  25. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
  26. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  27. data/lib/rubocop/cop/layout/block_alignment.rb +16 -12
  28. data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
  29. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
  30. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  31. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  32. data/lib/rubocop/cop/layout/first_argument_indentation.rb +7 -1
  33. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
  34. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
  35. data/lib/rubocop/cop/layout/indentation_width.rb +6 -2
  36. data/lib/rubocop/cop/layout/line_length.rb +4 -1
  37. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  38. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  39. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  40. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  41. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  42. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  43. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +13 -9
  44. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +25 -9
  45. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +28 -3
  46. data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
  47. data/lib/rubocop/cop/legacy/corrector.rb +1 -1
  48. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
  49. data/lib/rubocop/cop/lint/debugger.rb +26 -16
  50. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  51. data/lib/rubocop/cop/lint/duplicate_magic_comment.rb +73 -0
  52. data/lib/rubocop/cop/lint/duplicate_methods.rb +11 -1
  53. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +25 -6
  54. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -1
  55. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  56. data/lib/rubocop/cop/lint/empty_class.rb +3 -1
  57. data/lib/rubocop/cop/lint/empty_conditional_body.rb +107 -1
  58. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
  59. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
  60. data/lib/rubocop/cop/lint/nested_method_definition.rb +50 -1
  61. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  62. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
  63. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  64. data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
  65. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +4 -5
  66. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -1
  67. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +12 -1
  68. data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +7 -0
  69. data/lib/rubocop/cop/lint/redundant_require_statement.rb +29 -9
  70. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
  71. data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
  72. data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
  73. data/lib/rubocop/cop/lint/require_parentheses.rb +1 -1
  74. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -2
  75. data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -10
  76. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +27 -3
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +9 -3
  78. data/lib/rubocop/cop/lint/unused_method_argument.rb +4 -0
  79. data/lib/rubocop/cop/lint/useless_access_modifier.rb +8 -6
  80. data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +1 -1
  81. data/lib/rubocop/cop/lint/void.rb +2 -0
  82. data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
  83. data/lib/rubocop/cop/metrics/block_length.rb +6 -7
  84. data/lib/rubocop/cop/metrics/method_length.rb +8 -8
  85. data/lib/rubocop/cop/mixin/allowed_methods.rb +20 -1
  86. data/lib/rubocop/cop/mixin/allowed_pattern.rb +17 -1
  87. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  88. data/lib/rubocop/cop/mixin/comments_help.rb +17 -1
  89. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
  90. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  91. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +82 -4
  92. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -6
  93. data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
  94. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  95. data/lib/rubocop/cop/mixin/range_help.rb +4 -5
  96. data/lib/rubocop/cop/mixin/rescue_node.rb +3 -1
  97. data/lib/rubocop/cop/mixin/surrounding_space.rb +6 -5
  98. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  99. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  100. data/lib/rubocop/cop/naming/inclusive_language.rb +1 -1
  101. data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
  102. data/lib/rubocop/cop/style/access_modifier_declarations.rb +97 -1
  103. data/lib/rubocop/cop/style/accessor_grouping.rb +7 -3
  104. data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
  105. data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
  106. data/lib/rubocop/cop/style/case_equality.rb +40 -10
  107. data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
  108. data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
  109. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  110. data/lib/rubocop/cop/style/collection_compact.rb +6 -1
  111. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  112. data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
  113. data/lib/rubocop/cop/style/double_negation.rb +2 -0
  114. data/lib/rubocop/cop/style/each_for_simple_loop.rb +41 -6
  115. data/lib/rubocop/cop/style/each_with_object.rb +39 -8
  116. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  117. data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
  118. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  119. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  120. data/lib/rubocop/cop/style/endless_method.rb +1 -1
  121. data/lib/rubocop/cop/style/explicit_block_argument.rb +4 -0
  122. data/lib/rubocop/cop/style/for.rb +2 -0
  123. data/lib/rubocop/cop/style/format_string_token.rb +21 -8
  124. data/lib/rubocop/cop/style/guard_clause.rb +27 -16
  125. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
  126. data/lib/rubocop/cop/style/hash_except.rb +0 -4
  127. data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
  128. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  129. data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
  130. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  131. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +15 -4
  132. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  133. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
  134. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
  135. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  136. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  137. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  138. data/lib/rubocop/cop/style/negated_if_else_condition.rb +7 -1
  139. data/lib/rubocop/cop/style/next.rb +3 -5
  140. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  141. data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
  142. data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
  143. data/lib/rubocop/cop/style/object_then.rb +2 -0
  144. data/lib/rubocop/cop/style/operator_method_call.rb +39 -0
  145. data/lib/rubocop/cop/style/perl_backrefs.rb +22 -1
  146. data/lib/rubocop/cop/style/proc.rb +4 -1
  147. data/lib/rubocop/cop/style/redundant_begin.rb +3 -0
  148. data/lib/rubocop/cop/style/redundant_condition.rb +24 -6
  149. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  150. data/lib/rubocop/cop/style/redundant_initialize.rb +3 -1
  151. data/lib/rubocop/cop/style/redundant_parentheses.rb +19 -22
  152. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +8 -1
  153. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  154. data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
  155. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  156. data/lib/rubocop/cop/style/redundant_string_escape.rb +173 -0
  157. data/lib/rubocop/cop/style/rescue_modifier.rb +1 -1
  158. data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
  159. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  160. data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
  161. data/lib/rubocop/cop/style/static_class.rb +32 -1
  162. data/lib/rubocop/cop/style/symbol_array.rb +3 -1
  163. data/lib/rubocop/cop/style/symbol_proc.rb +38 -12
  164. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
  165. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  166. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  167. data/lib/rubocop/cop/style/word_array.rb +3 -1
  168. data/lib/rubocop/cop/util.rb +1 -1
  169. data/lib/rubocop/ext/range.rb +15 -0
  170. data/lib/rubocop/feature_loader.rb +94 -0
  171. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  172. data/lib/rubocop/formatter/disabled_config_formatter.rb +9 -3
  173. data/lib/rubocop/formatter/html_formatter.rb +3 -3
  174. data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
  175. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  176. data/lib/rubocop/options.rb +13 -13
  177. data/lib/rubocop/result_cache.rb +22 -20
  178. data/lib/rubocop/rspec/shared_contexts.rb +13 -1
  179. data/lib/rubocop/runner.rb +4 -0
  180. data/lib/rubocop/server/cache.rb +41 -2
  181. data/lib/rubocop/server/cli.rb +26 -2
  182. data/lib/rubocop/server/client_command/exec.rb +5 -0
  183. data/lib/rubocop/server/core.rb +2 -1
  184. data/lib/rubocop/server/socket_reader.rb +5 -1
  185. data/lib/rubocop/server.rb +1 -1
  186. data/lib/rubocop/version.rb +8 -2
  187. data/lib/rubocop.rb +8 -3
  188. metadata +20 -9
  189. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -36,8 +36,8 @@ module RuboCop
36
36
  extend AutoCorrector
37
37
 
38
38
  MSG = 'Use `%<good>s` instead of `%<bad>s`.'
39
-
40
39
  RESTRICT_ON_SEND = %i[reject reject! select select!].freeze
40
+ TO_ENUM_METHODS = %i[to_enum lazy].freeze
41
41
 
42
42
  # @!method reject_method_with_block_pass?(node)
43
43
  def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
@@ -69,6 +69,7 @@ module RuboCop
69
69
 
70
70
  def on_send(node)
71
71
  return unless (range = offense_range(node))
72
+ return if target_ruby_version <= 3.0 && to_enum_method?(node)
72
73
 
73
74
  good = good_method_name(node)
74
75
  message = format(MSG, good: good, bad: range.source)
@@ -94,6 +95,10 @@ module RuboCop
94
95
  end
95
96
  end
96
97
 
98
+ def to_enum_method?(node)
99
+ TO_ENUM_METHODS.include?(node.children.first.method_name)
100
+ end
101
+
97
102
  def good_method_name(node)
98
103
  if node.bang_method?
99
104
  'compact!'
@@ -48,6 +48,8 @@ module RuboCop
48
48
  check_method_node(node.send_node)
49
49
  end
50
50
 
51
+ alias on_numblock on_block
52
+
51
53
  def on_send(node)
52
54
  return unless implicit_block?(node)
53
55
 
@@ -66,6 +66,8 @@ module RuboCop
66
66
  add_offense(node) if same_collection_looping?(node, node.left_sibling)
67
67
  end
68
68
 
69
+ alias on_numblock on_block
70
+
69
71
  def on_for(node)
70
72
  return unless node.parent&.begin_type?
71
73
 
@@ -82,7 +84,7 @@ module RuboCop
82
84
  end
83
85
 
84
86
  def same_collection_looping?(node, sibling)
85
- sibling&.block_type? &&
87
+ (sibling&.block_type? || sibling&.numblock_type?) &&
86
88
  sibling.send_node.method?(node.method_name) &&
87
89
  sibling.receiver == node.receiver &&
88
90
  sibling.send_node.arguments == node.send_node.arguments
@@ -93,6 +93,8 @@ module RuboCop
93
93
 
94
94
  if conditional_node
95
95
  double_negative_condition_return_value?(node, last_child, conditional_node)
96
+ elsif last_child.pair_type? || last_child.hash_type? || last_child.parent.array_type?
97
+ false
96
98
  else
97
99
  last_child.last_line <= node.last_line
98
100
  end
@@ -27,15 +27,15 @@ module RuboCop
27
27
 
28
28
  MSG = 'Use `Integer#times` for a simple loop which iterates a fixed number of times.'
29
29
 
30
- def on_block(node)
31
- return unless offending_each_range(node)
30
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
31
+ return unless offending?(node)
32
32
 
33
33
  send_node = node.send_node
34
34
 
35
35
  range = send_node.receiver.source_range.join(send_node.loc.selector)
36
36
 
37
37
  add_offense(range) do |corrector|
38
- range_type, min, max = offending_each_range(node)
38
+ range_type, min, max = each_range(node)
39
39
 
40
40
  max += 1 if range_type == :irange
41
41
 
@@ -45,9 +45,44 @@ module RuboCop
45
45
 
46
46
  private
47
47
 
48
- # @!method offending_each_range(node)
49
- def_node_matcher :offending_each_range, <<~PATTERN
50
- (block (send (begin (${irange erange} (int $_) (int $_))) :each) (args) ...)
48
+ def offending?(node)
49
+ each_range_with_zero_origin?(node) || each_range_without_block_argument?(node)
50
+ end
51
+
52
+ # @!method each_range(node)
53
+ def_node_matcher :each_range, <<~PATTERN
54
+ (block
55
+ (send
56
+ (begin
57
+ (${irange erange}
58
+ (int $_) (int $_)))
59
+ :each)
60
+ (args ...)
61
+ ...)
62
+ PATTERN
63
+
64
+ # @!method each_range_with_zero_origin?(node)
65
+ def_node_matcher :each_range_with_zero_origin?, <<~PATTERN
66
+ (block
67
+ (send
68
+ (begin
69
+ ({irange erange}
70
+ (int 0) (int _)))
71
+ :each)
72
+ (args ...)
73
+ ...)
74
+ PATTERN
75
+
76
+ # @!method each_range_without_block_argument?(node)
77
+ def_node_matcher :each_range_without_block_argument?, <<~PATTERN
78
+ (block
79
+ (send
80
+ (begin
81
+ ({irange erange}
82
+ (int _) (int _)))
83
+ :each)
84
+ (args)
85
+ ...)
51
86
  PATTERN
52
87
  end
53
88
  end
@@ -23,13 +23,8 @@ module RuboCop
23
23
  MSG = 'Use `each_with_object` instead of `%<method>s`.'
24
24
  METHODS = %i[inject reduce].freeze
25
25
 
26
- # @!method each_with_object_candidate?(node)
27
- def_node_matcher :each_with_object_candidate?, <<~PATTERN
28
- (block $(send _ {:inject :reduce} _) $_ $_)
29
- PATTERN
30
-
31
26
  def on_block(node)
32
- each_with_object_candidate?(node) do |method, args, body|
27
+ each_with_object_block_candidate?(node) do |method, args, body|
33
28
  _, method_name, method_arg = *method
34
29
  return if simple_method_arg?(method_arg)
35
30
 
@@ -40,14 +35,38 @@ module RuboCop
40
35
 
41
36
  message = format(MSG, method: method_name)
42
37
  add_offense(method.loc.selector, message: message) do |corrector|
43
- autocorrect(corrector, node, return_value)
38
+ autocorrect_block(corrector, node, return_value)
39
+ end
40
+ end
41
+ end
42
+
43
+ def on_numblock(node)
44
+ each_with_object_numblock_candidate?(node) do |method, body|
45
+ _, method_name, method_arg = *method
46
+ return if simple_method_arg?(method_arg)
47
+
48
+ return unless return_value(body)&.source == '_1'
49
+
50
+ message = format(MSG, method: method_name)
51
+ add_offense(method.loc.selector, message: message) do |corrector|
52
+ autocorrect_numblock(corrector, node)
44
53
  end
45
54
  end
46
55
  end
47
56
 
48
57
  private
49
58
 
50
- def autocorrect(corrector, node, return_value)
59
+ # @!method each_with_object_block_candidate?(node)
60
+ def_node_matcher :each_with_object_block_candidate?, <<~PATTERN
61
+ (block $(send _ {:inject :reduce} _) $_ $_)
62
+ PATTERN
63
+
64
+ # @!method each_with_object_numblock_candidate?(node)
65
+ def_node_matcher :each_with_object_numblock_candidate?, <<~PATTERN
66
+ (numblock $(send _ {:inject :reduce} _) 2 $_)
67
+ PATTERN
68
+
69
+ def autocorrect_block(corrector, node, return_value)
51
70
  corrector.replace(node.send_node.loc.selector, 'each_with_object')
52
71
 
53
72
  first_arg, second_arg = *node.arguments
@@ -62,6 +81,18 @@ module RuboCop
62
81
  end
63
82
  end
64
83
 
84
+ def autocorrect_numblock(corrector, node)
85
+ corrector.replace(node.send_node.loc.selector, 'each_with_object')
86
+
87
+ # We don't remove the return value to avoid a clobbering error.
88
+ node.body.each_descendant do |var|
89
+ next unless var.lvar_type?
90
+
91
+ corrector.replace(var, '_2') if var.source == '_1'
92
+ corrector.replace(var, '_1') if var.source == '_2'
93
+ end
94
+ end
95
+
65
96
  def simple_method_arg?(method_arg)
66
97
  method_arg&.basic_literal?
67
98
  end
@@ -28,7 +28,7 @@ module RuboCop
28
28
 
29
29
  MSG = 'Omit pipes for the empty block parameters.'
30
30
 
31
- def on_block(node)
31
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
32
32
  send_node = node.send_node
33
33
  check(node) unless send_node.send_type? && send_node.lambda_literal?
34
34
  end
@@ -48,11 +48,25 @@ module RuboCop
48
48
  add_offense(node) do |corrector|
49
49
  heredoc_end = node.loc.heredoc_end
50
50
 
51
- corrector.replace(node, "''")
51
+ corrector.replace(node, preferred_string_literal)
52
52
  corrector.remove(range_by_whole_lines(heredoc_body, include_final_newline: true))
53
53
  corrector.remove(range_by_whole_lines(heredoc_end, include_final_newline: true))
54
54
  end
55
55
  end
56
+
57
+ private
58
+
59
+ def preferred_string_literal
60
+ enforce_double_quotes? ? '""' : "''"
61
+ end
62
+
63
+ def enforce_double_quotes?
64
+ string_literals_config['EnforcedStyle'] == 'double_quotes'
65
+ end
66
+
67
+ def string_literals_config
68
+ config.for_cop('Style/StringLiterals')
69
+ end
56
70
  end
57
71
  end
58
72
  end
@@ -23,7 +23,7 @@ module RuboCop
23
23
 
24
24
  MSG = 'Omit parentheses for the empty lambda parameters.'
25
25
 
26
- def on_block(node)
26
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
27
27
  send_node = node.send_node
28
28
  return unless send_node.send_type?
29
29
 
@@ -52,7 +52,7 @@ module RuboCop
52
52
  MSG_EXPANDED = 'Put the `end` of empty method definitions on the next line.'
53
53
 
54
54
  def on_def(node)
55
- return if node.body || comment_lines?(node)
55
+ return if node.body || processed_source.contains_comment?(node.source_range)
56
56
  return if correct_style?(node)
57
57
 
58
58
  add_offense(node) do |corrector|
@@ -39,7 +39,7 @@ module RuboCop
39
39
  #
40
40
  # @example EnforcedStyle: disallow
41
41
  # # bad
42
- # def my_method; x end
42
+ # def my_method() = x
43
43
  #
44
44
  # # bad
45
45
  # def my_method() = x.foo
@@ -50,6 +50,10 @@ module RuboCop
50
50
  (block $_ (args $...) (yield $...))
51
51
  PATTERN
52
52
 
53
+ def self.autocorrect_incompatible_with
54
+ [Lint::UnusedMethodArgument]
55
+ end
56
+
53
57
  def initialize(config = nil, options = nil)
54
58
  super
55
59
  @def_nodes = Set.new
@@ -75,6 +75,8 @@ module RuboCop
75
75
  end
76
76
  end
77
77
 
78
+ alias on_numblock on_block
79
+
78
80
  private
79
81
 
80
82
  def suspect_enumerable?(node)
@@ -11,8 +11,8 @@ module RuboCop
11
11
  # The reason is that _unannotated_ format is very similar
12
12
  # to encoded URLs or Date/Time formatting strings.
13
13
  #
14
- # This cop can be customized ignored methods with `IgnoredMethods`.
15
- # By default, there are no methods to ignored.
14
+ # This cop can be customized allowed methods with `AllowedMethods`.
15
+ # By default, there are no methods to allowed.
16
16
  #
17
17
  # @example EnforcedStyle: annotated (default)
18
18
  #
@@ -62,23 +62,34 @@ module RuboCop
62
62
  # # good
63
63
  # format('%06d', 10)
64
64
  #
65
- # @example IgnoredMethods: [] (default)
65
+ # @example AllowedMethods: [] (default)
66
66
  #
67
67
  # # bad
68
68
  # redirect('foo/%{bar_id}')
69
69
  #
70
- # @example IgnoredMethods: [redirect]
70
+ # @example AllowedMethods: [redirect]
71
+ #
72
+ # # good
73
+ # redirect('foo/%{bar_id}')
74
+ #
75
+ # @example AllowedPatterns: [] (default)
76
+ #
77
+ # # bad
78
+ # redirect('foo/%{bar_id}')
79
+ #
80
+ # @example AllowedPatterns: ['redirect']
71
81
  #
72
82
  # # good
73
83
  # redirect('foo/%{bar_id}')
74
84
  #
75
85
  class FormatStringToken < Base
76
86
  include ConfigurableEnforcedStyle
77
- include IgnoredMethods
87
+ include AllowedMethods
88
+ include AllowedPattern
78
89
  extend AutoCorrector
79
90
 
80
91
  def on_str(node)
81
- return if format_string_token?(node) || use_ignored_method?(node)
92
+ return if format_string_token?(node) || use_allowed_method?(node)
82
93
 
83
94
  detections = collect_detections(node)
84
95
  return if detections.empty?
@@ -103,9 +114,11 @@ module RuboCop
103
114
  !node.value.include?('%') || node.each_ancestor(:xstr, :regexp).any?
104
115
  end
105
116
 
106
- def use_ignored_method?(node)
117
+ def use_allowed_method?(node)
107
118
  send_parent = node.each_ancestor(:send).first
108
- send_parent && ignored_method?(send_parent.method_name)
119
+ send_parent &&
120
+ (allowed_method?(send_parent.method_name) ||
121
+ matches_allowed_pattern?(send_parent.method_name))
109
122
  end
110
123
 
111
124
  def check_sequence(detected_sequence, token_range)
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # Use a guard clause instead of wrapping the code inside a conditional
7
7
  # expression
8
8
  #
9
+ # A condition with an `elsif` or `else` branch is allowed unless
10
+ # one of `return`, `break`, `next`, `raise`, or `fail` is used
11
+ # in the body of the conditional expression.
12
+ #
9
13
  # @example
10
14
  # # bad
11
15
  # def test
@@ -50,34 +54,41 @@ module RuboCop
50
54
  #
51
55
  # @example AllowConsecutiveConditionals: false (default)
52
56
  # # bad
53
- # if foo?
54
- # work
55
- # end
57
+ # def test
58
+ # if foo?
59
+ # work
60
+ # end
56
61
  #
57
- # if bar? # <- reports an offense
58
- # work
62
+ # if bar? # <- reports an offense
63
+ # work
64
+ # end
59
65
  # end
60
66
  #
61
67
  # @example AllowConsecutiveConditionals: true
62
68
  # # good
63
- # if foo?
64
- # work
65
- # end
69
+ # def test
70
+ # if foo?
71
+ # work
72
+ # end
66
73
  #
67
- # if bar?
68
- # work
74
+ # if bar?
75
+ # work
76
+ # end
69
77
  # end
70
78
  #
71
79
  # # bad
72
- # if foo?
73
- # work
74
- # end
80
+ # def test
81
+ # if foo?
82
+ # work
83
+ # end
75
84
  #
76
- # do_something
85
+ # do_something
77
86
  #
78
- # if bar? # <- reports an offense
79
- # work
87
+ # if bar? # <- reports an offense
88
+ # work
89
+ # end
80
90
  # end
91
+ #
81
92
  class GuardClause < Base
82
93
  include MinBodyLength
83
94
  include StatementModifier
@@ -35,13 +35,15 @@ module RuboCop
35
35
 
36
36
  # @!method kv_each(node)
37
37
  def_node_matcher :kv_each, <<~PATTERN
38
- (block $(send (send _ ${:keys :values}) :each) ...)
38
+ ({block numblock} $(send (send _ ${:keys :values}) :each) ...)
39
39
  PATTERN
40
40
 
41
41
  def on_block(node)
42
42
  register_kv_offense(node)
43
43
  end
44
44
 
45
+ alias on_numblock on_block
46
+
45
47
  private
46
48
 
47
49
  def register_kv_offense(node)
@@ -159,10 +159,6 @@ module RuboCop
159
159
  key_argument = node.argument_list.first.source
160
160
  body = extract_body_if_nagated(node.body)
161
161
  lhs, _method_name, rhs = *body
162
-
163
- return lhs if body.method?('include?')
164
- return lhs if body.method?('exclude?')
165
- return rhs if body.method?('in?')
166
162
  return if [lhs, rhs].map(&:source).none?(key_argument)
167
163
 
168
164
  [lhs, rhs].find { |operand| operand.source != key_argument }
@@ -28,6 +28,7 @@ module RuboCop
28
28
  # * always - forces use of the 3.1 syntax (e.g. {foo:})
29
29
  # * never - forces use of explicit hash literal value
30
30
  # * either - accepts both shorthand and explicit use of hash literal value
31
+ # * consistent - like "either", but will avoid mixing styles in a single hash
31
32
  #
32
33
  # @example EnforcedStyle: ruby19 (default)
33
34
  # # bad
@@ -89,6 +90,20 @@ module RuboCop
89
90
  # # good
90
91
  # {foo:, bar:}
91
92
  #
93
+ # @example EnforcedShorthandSyntax: consistent
94
+ #
95
+ # # bad
96
+ # {foo: , bar: bar}
97
+ #
98
+ # # good
99
+ # {foo:, bar:}
100
+ #
101
+ # # bad
102
+ # {foo: , bar: baz}
103
+ #
104
+ # # good
105
+ # {foo: foo, bar: baz}
106
+ #
92
107
  class HashSyntax < Base
93
108
  include ConfigurableEnforcedStyle
94
109
  include HashShorthandSyntax
@@ -104,6 +119,8 @@ module RuboCop
104
119
 
105
120
  return if pairs.empty?
106
121
 
122
+ on_hash_for_mixed_shorthand(node)
123
+
107
124
  if style == :hash_rockets || force_hash_rockets?(pairs)
108
125
  hash_rockets_check(pairs)
109
126
  elsif style == :ruby19_no_mixed_keys
@@ -96,7 +96,7 @@ module RuboCop
96
96
  return false unless max_line_length
97
97
 
98
98
  range = node.source_range
99
- return false unless range.first_line == range.last_line
99
+ return false unless range.single_line?
100
100
  return false unless line_length_enabled_at_line?(range.first_line)
101
101
 
102
102
  line = range.source_line
@@ -59,18 +59,18 @@ module RuboCop
59
59
  def_node_matcher :inverse_candidate?, <<~PATTERN
60
60
  {
61
61
  (send $(send $(...) $_ $...) :!)
62
- (send (block $(send $(...) $_) $...) :!)
62
+ (send ({block numblock} $(send $(...) $_) $...) :!)
63
63
  (send (begin $(send $(...) $_ $...)) :!)
64
64
  }
65
65
  PATTERN
66
66
 
67
67
  # @!method inverse_block?(node)
68
68
  def_node_matcher :inverse_block?, <<~PATTERN
69
- (block $(send (...) $_) ... { $(send ... :!)
70
- $(send (...) {:!= :!~} ...)
71
- (begin ... $(send ... :!))
72
- (begin ... $(send (...) {:!= :!~} ...))
73
- })
69
+ ({block numblock} $(send (...) $_) ... { $(send ... :!)
70
+ $(send (...) {:!= :!~} ...)
71
+ (begin ... $(send ... :!))
72
+ (begin ... $(send (...) {:!= :!~} ...))
73
+ })
74
74
  PATTERN
75
75
 
76
76
  def on_send(node)
@@ -102,6 +102,8 @@ module RuboCop
102
102
  end
103
103
  end
104
104
 
105
+ alias on_numblock on_block
106
+
105
107
  private
106
108
 
107
109
  def correct_inverse_method(corrector, node)