rubocop 1.10.0 → 1.11.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 (199) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -12
  3. data/assets/output.html.erb +1 -1
  4. data/config/default.yml +13 -0
  5. data/lib/rubocop.rb +1 -0
  6. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  7. data/lib/rubocop/cli/command/suggest_extensions.rb +1 -1
  8. data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -1
  9. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  10. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -0
  11. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -0
  12. data/lib/rubocop/cop/gemspec/date_assignment.rb +1 -0
  13. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -0
  14. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -0
  15. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +2 -0
  16. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +2 -0
  17. data/lib/rubocop/cop/generator.rb +2 -2
  18. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  19. data/lib/rubocop/cop/internal_affairs/example_description.rb +1 -0
  20. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  21. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -0
  22. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +151 -0
  23. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  24. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -0
  25. data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +1 -0
  26. data/lib/rubocop/cop/internal_affairs/redundant_let_rubocop_config_new.rb +1 -0
  27. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  28. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +3 -0
  29. data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +4 -0
  30. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
  31. data/lib/rubocop/cop/layout/block_alignment.rb +1 -0
  32. data/lib/rubocop/cop/layout/class_structure.rb +1 -0
  33. data/lib/rubocop/cop/layout/extra_spacing.rb +2 -2
  34. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
  35. data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
  36. data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -1
  37. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  38. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -0
  39. data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -0
  40. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +2 -0
  41. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -0
  42. data/lib/rubocop/cop/lint/debugger.rb +3 -1
  43. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +1 -0
  44. data/lib/rubocop/cop/lint/duplicate_branch.rb +1 -1
  45. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -0
  46. data/lib/rubocop/cop/lint/duplicate_require.rb +1 -0
  47. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  48. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -0
  49. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +1 -0
  50. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +1 -0
  51. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -0
  52. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -0
  53. data/lib/rubocop/cop/lint/multiple_comparison.rb +1 -0
  54. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -0
  55. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -0
  56. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +7 -0
  57. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -0
  58. data/lib/rubocop/cop/lint/number_conversion.rb +2 -0
  59. data/lib/rubocop/cop/lint/raise_exception.rb +2 -0
  60. data/lib/rubocop/cop/lint/rand_one.rb +1 -0
  61. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  62. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +1 -0
  63. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +2 -0
  64. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -0
  65. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -0
  66. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -0
  67. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -0
  68. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -0
  69. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -0
  70. data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
  71. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -0
  72. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  73. data/lib/rubocop/cop/lint/to_enum_arguments.rb +3 -0
  74. data/lib/rubocop/cop/lint/unified_integer.rb +1 -0
  75. data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +5 -0
  76. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -0
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -0
  78. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -0
  79. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -0
  80. data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -0
  81. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -0
  82. data/lib/rubocop/cop/lint/useless_times.rb +3 -0
  83. data/lib/rubocop/cop/metrics/module_length.rb +1 -0
  84. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -0
  85. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +6 -4
  86. data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +2 -0
  87. data/lib/rubocop/cop/mixin/def_node.rb +1 -0
  88. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +3 -0
  89. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -0
  90. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  91. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -0
  92. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
  93. data/lib/rubocop/cop/mixin/negative_conditional.rb +3 -0
  94. data/lib/rubocop/cop/mixin/preferred_delimiters.rb +1 -1
  95. data/lib/rubocop/cop/mixin/rational_literal.rb +1 -0
  96. data/lib/rubocop/cop/mixin/safe_assignment.rb +5 -0
  97. data/lib/rubocop/cop/mixin/visibility_help.rb +1 -0
  98. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -0
  99. data/lib/rubocop/cop/naming/constant_name.rb +2 -0
  100. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -0
  101. data/lib/rubocop/cop/naming/method_name.rb +3 -0
  102. data/lib/rubocop/cop/naming/predicate_name.rb +1 -0
  103. data/lib/rubocop/cop/security/eval.rb +1 -0
  104. data/lib/rubocop/cop/security/json_load.rb +1 -0
  105. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  106. data/lib/rubocop/cop/security/open.rb +1 -0
  107. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  108. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  109. data/lib/rubocop/cop/style/alias.rb +1 -0
  110. data/lib/rubocop/cop/style/arguments_forwarding.rb +3 -0
  111. data/lib/rubocop/cop/style/array_coercion.rb +2 -0
  112. data/lib/rubocop/cop/style/array_join.rb +1 -0
  113. data/lib/rubocop/cop/style/attr.rb +1 -0
  114. data/lib/rubocop/cop/style/case_equality.rb +2 -1
  115. data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -0
  116. data/lib/rubocop/cop/style/collection_compact.rb +2 -0
  117. data/lib/rubocop/cop/style/colon_method_call.rb +1 -0
  118. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  119. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -0
  120. data/lib/rubocop/cop/style/constant_visibility.rb +1 -0
  121. data/lib/rubocop/cop/style/date_time.rb +3 -0
  122. data/lib/rubocop/cop/style/dir.rb +1 -0
  123. data/lib/rubocop/cop/style/documentation.rb +5 -0
  124. data/lib/rubocop/cop/style/documentation_method.rb +1 -0
  125. data/lib/rubocop/cop/style/double_negation.rb +1 -0
  126. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -0
  127. data/lib/rubocop/cop/style/each_with_object.rb +1 -0
  128. data/lib/rubocop/cop/style/empty_literal.rb +9 -0
  129. data/lib/rubocop/cop/style/endless_method.rb +1 -0
  130. data/lib/rubocop/cop/style/eval_with_location.rb +2 -0
  131. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  132. data/lib/rubocop/cop/style/expand_path_arguments.rb +3 -0
  133. data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -0
  134. data/lib/rubocop/cop/style/float_division.rb +4 -0
  135. data/lib/rubocop/cop/style/format_string.rb +2 -0
  136. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  137. data/lib/rubocop/cop/style/global_std_stream.rb +1 -0
  138. data/lib/rubocop/cop/style/hash_conversion.rb +26 -2
  139. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -0
  140. data/lib/rubocop/cop/style/hash_except.rb +1 -0
  141. data/lib/rubocop/cop/style/hash_like_case.rb +1 -0
  142. data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -0
  143. data/lib/rubocop/cop/style/hash_transform_values.rb +4 -0
  144. data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -0
  145. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  146. data/lib/rubocop/cop/style/inverse_methods.rb +2 -0
  147. data/lib/rubocop/cop/style/min_max.rb +1 -0
  148. data/lib/rubocop/cop/style/mixin_usage.rb +2 -0
  149. data/lib/rubocop/cop/style/module_function.rb +5 -0
  150. data/lib/rubocop/cop/style/multiple_comparison.rb +21 -2
  151. data/lib/rubocop/cop/style/mutable_constant.rb +3 -0
  152. data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -0
  153. data/lib/rubocop/cop/style/nil_comparison.rb +3 -0
  154. data/lib/rubocop/cop/style/nil_lambda.rb +1 -0
  155. data/lib/rubocop/cop/style/non_nil_check.rb +7 -0
  156. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -0
  157. data/lib/rubocop/cop/style/option_hash.rb +1 -0
  158. data/lib/rubocop/cop/style/or_assignment.rb +2 -0
  159. data/lib/rubocop/cop/style/parallel_assignment.rb +6 -0
  160. data/lib/rubocop/cop/style/parentheses_around_condition.rb +1 -0
  161. data/lib/rubocop/cop/style/proc.rb +1 -0
  162. data/lib/rubocop/cop/style/random_with_offset.rb +5 -0
  163. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -0
  164. data/lib/rubocop/cop/style/redundant_begin.rb +7 -1
  165. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -0
  166. data/lib/rubocop/cop/style/redundant_exception.rb +2 -0
  167. data/lib/rubocop/cop/style/redundant_fetch_block.rb +2 -0
  168. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  169. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -0
  170. data/lib/rubocop/cop/style/redundant_parentheses.rb +13 -0
  171. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -0
  172. data/lib/rubocop/cop/style/redundant_sort.rb +1 -0
  173. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -0
  174. data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
  175. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -0
  176. data/lib/rubocop/cop/style/return_nil.rb +6 -0
  177. data/lib/rubocop/cop/style/safe_navigation.rb +2 -0
  178. data/lib/rubocop/cop/style/sample.rb +1 -0
  179. data/lib/rubocop/cop/style/signal_exception.rb +3 -0
  180. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  181. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -0
  182. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  183. data/lib/rubocop/cop/style/string_concatenation.rb +1 -0
  184. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -0
  185. data/lib/rubocop/cop/style/strip.rb +1 -0
  186. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -0
  187. data/lib/rubocop/cop/style/symbol_proc.rb +25 -1
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -0
  189. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +1 -0
  190. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  191. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -0
  192. data/lib/rubocop/cop/style/unless_logical_operators.rb +99 -0
  193. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  194. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  195. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -0
  196. data/lib/rubocop/name_similarity.rb +1 -1
  197. data/lib/rubocop/target_ruby.rb +21 -13
  198. data/lib/rubocop/version.rb +1 -1
  199. metadata +9 -7
@@ -54,6 +54,7 @@ module RuboCop
54
54
 
55
55
  RESTRICT_ON_SEND = %i[expand_path].freeze
56
56
 
57
+ # @!method file_expand_path(node)
57
58
  def_node_matcher :file_expand_path, <<~PATTERN
58
59
  (send
59
60
  (const {nil? cbase} :File) :expand_path
@@ -61,6 +62,7 @@ module RuboCop
61
62
  $_)
62
63
  PATTERN
63
64
 
65
+ # @!method pathname_parent_expand_path(node)
64
66
  def_node_matcher :pathname_parent_expand_path, <<~PATTERN
65
67
  (send
66
68
  (send
@@ -68,6 +70,7 @@ module RuboCop
68
70
  $_) :parent) :expand_path)
69
71
  PATTERN
70
72
 
73
+ # @!method pathname_new_parent_expand_path(node)
71
74
  def_node_matcher :pathname_new_parent_expand_path, <<~PATTERN
72
75
  (send
73
76
  (send
@@ -45,6 +45,7 @@ module RuboCop
45
45
  MSG = 'Consider using explicit block argument in the '\
46
46
  "surrounding method's signature over `yield`."
47
47
 
48
+ # @!method yielding_block?(node)
48
49
  def_node_matcher :yielding_block?, <<~PATTERN
49
50
  (block $_ (args $...) (yield $...))
50
51
  PATTERN
@@ -55,15 +55,19 @@ module RuboCop
55
55
 
56
56
  RESTRICT_ON_SEND = %i[/].freeze
57
57
 
58
+ # @!method right_coerce?(node)
58
59
  def_node_matcher :right_coerce?, <<~PATTERN
59
60
  (send _ :/ (send _ :to_f))
60
61
  PATTERN
62
+ # @!method left_coerce?(node)
61
63
  def_node_matcher :left_coerce?, <<~PATTERN
62
64
  (send (send _ :to_f) :/ _)
63
65
  PATTERN
66
+ # @!method both_coerce?(node)
64
67
  def_node_matcher :both_coerce?, <<~PATTERN
65
68
  (send (send _ :to_f) :/ (send _ :to_f))
66
69
  PATTERN
70
+ # @!method any_coerce?(node)
67
71
  def_node_matcher :any_coerce?, <<~PATTERN
68
72
  {(send _ :/ (send _ :to_f)) (send (send _ :to_f) :/ _)}
69
73
  PATTERN
@@ -42,6 +42,7 @@ module RuboCop
42
42
  MSG = 'Favor `%<prefer>s` over `%<current>s`.'
43
43
  RESTRICT_ON_SEND = %i[format sprintf %].freeze
44
44
 
45
+ # @!method formatter(node)
45
46
  def_node_matcher :formatter, <<~PATTERN
46
47
  {
47
48
  (send nil? ${:sprintf :format} _ _ ...)
@@ -50,6 +51,7 @@ module RuboCop
50
51
  }
51
52
  PATTERN
52
53
 
54
+ # @!method variable_argument?(node)
53
55
  def_node_matcher :variable_argument?, <<~PATTERN
54
56
  (send {str dstr} :% {send_type? lvar_type?})
55
57
  PATTERN
@@ -89,6 +89,7 @@ module RuboCop
89
89
 
90
90
  private
91
91
 
92
+ # @!method format_string_in_typical_context?(node)
92
93
  def_node_matcher :format_string_in_typical_context?, <<~PATTERN
93
94
  {
94
95
  ^(send _ {:format :sprintf :printf} %0 ...)
@@ -34,6 +34,7 @@ module RuboCop
34
34
 
35
35
  STD_STREAMS = %i[STDIN STDOUT STDERR].to_set.freeze
36
36
 
37
+ # @!method const_to_gvar_assignment?(node, name)
37
38
  def_node_matcher :const_to_gvar_assignment?, <<~PATTERN
38
39
  (gvasgn %1 (const nil? _))
39
40
  PATTERN
@@ -6,6 +6,10 @@ module RuboCop
6
6
  # This cop checks the usage of pre-2.1 `Hash[args]` method of converting enumerables and
7
7
  # sequences of values to hashes.
8
8
  #
9
+ # Correction code from splat argument (`Hash[*ary]`) is not simply determined. For example,
10
+ # `Hash[*ary]` can be replaced with `ary.each_slice(2).to_h` but it will be complicated.
11
+ # So, `AllowSplatArgument` option is true by default to allow splat argument for simple code.
12
+ #
9
13
  # @example
10
14
  # # bad
11
15
  # Hash[ary]
@@ -18,6 +22,15 @@ module RuboCop
18
22
  #
19
23
  # # good
20
24
  # {key1 => value1, key2 => value2}
25
+ #
26
+ # @example AllowSplatArgument: true (default)
27
+ # # good
28
+ # Hash[*ary]
29
+ #
30
+ # @example AllowSplatArgument: false
31
+ # # bad
32
+ # Hash[*ary]
33
+ #
21
34
  class HashConversion < Base
22
35
  extend AutoCorrector
23
36
 
@@ -27,6 +40,7 @@ module RuboCop
27
40
  MSG_SPLAT = 'Prefer array_of_pairs.to_h to Hash[*array].'
28
41
  RESTRICT_ON_SEND = %i[[]].freeze
29
42
 
43
+ # @!method hash_from_array?(node)
30
44
  def_node_matcher :hash_from_array?, '(send (const {nil? cbase} :Hash) :[] ...)'
31
45
 
32
46
  def on_send(node)
@@ -51,14 +65,20 @@ module RuboCop
51
65
  corrector.replace(node, "{#{first_argument.source}}")
52
66
  end
53
67
  elsif first_argument.splat_type?
54
- add_offense(node, message: MSG_SPLAT)
68
+ add_offense(node, message: MSG_SPLAT) unless allowed_splat_argument?
55
69
  else
56
70
  add_offense(node, message: MSG_TO_H) do |corrector|
57
- corrector.replace(node, "#{first_argument.source}.to_h")
71
+ replacement = first_argument.source
72
+ replacement = "(#{replacement})" if requires_parens?(first_argument)
73
+ corrector.replace(node, "#{replacement}.to_h")
58
74
  end
59
75
  end
60
76
  end
61
77
 
78
+ def requires_parens?(node)
79
+ node.call_type? && node.arguments.any? && !node.parenthesized?
80
+ end
81
+
62
82
  def multi_argument(node)
63
83
  if node.arguments.count.odd?
64
84
  add_offense(node, message: MSG_LITERAL_MULTI_ARG)
@@ -75,6 +95,10 @@ module RuboCop
75
95
  .join(', ')
76
96
  "{#{content}}"
77
97
  end
98
+
99
+ def allowed_splat_argument?
100
+ cop_config.fetch('AllowSplatArgument', true)
101
+ end
78
102
  end
79
103
  end
80
104
  end
@@ -23,6 +23,7 @@ module RuboCop
23
23
 
24
24
  MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
25
25
 
26
+ # @!method kv_each(node)
26
27
  def_node_matcher :kv_each, <<~PATTERN
27
28
  (block $(send (send _ ${:keys :values}) :each) ...)
28
29
  PATTERN
@@ -33,6 +33,7 @@ module RuboCop
33
33
  MSG = 'Use `%<prefer>s` instead.'
34
34
  RESTRICT_ON_SEND = %i[reject select filter].freeze
35
35
 
36
+ # @!method bad_method?(node)
36
37
  def_node_matcher :bad_method?, <<~PATTERN
37
38
  (block
38
39
  (send _ _)
@@ -39,6 +39,7 @@ module RuboCop
39
39
  class HashLikeCase < Base
40
40
  MSG = 'Consider replacing `case-when` with a hash lookup.'
41
41
 
42
+ # @!method hash_like_case?(node)
42
43
  def_node_matcher :hash_like_case?, <<~PATTERN
43
44
  (case
44
45
  _
@@ -32,6 +32,7 @@ module RuboCop
32
32
 
33
33
  minimum_target_ruby_version 2.5
34
34
 
35
+ # @!method on_bad_each_with_object(node)
35
36
  def_node_matcher :on_bad_each_with_object, <<~PATTERN
36
37
  (block
37
38
  ({send csend} !#array_receiver? :each_with_object (hash))
@@ -43,6 +44,7 @@ module RuboCop
43
44
  ({send csend} (lvar _memo) :[]= $!`_memo $(lvar _val)))
44
45
  PATTERN
45
46
 
47
+ # @!method on_bad_hash_brackets_map(node)
46
48
  def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
47
49
  (send
48
50
  (const _ :Hash)
@@ -55,6 +57,7 @@ module RuboCop
55
57
  (array $_ $(lvar _val))))
56
58
  PATTERN
57
59
 
60
+ # @!method on_bad_map_to_h(node)
58
61
  def_node_matcher :on_bad_map_to_h, <<~PATTERN
59
62
  ({send csend}
60
63
  (block
@@ -66,6 +69,7 @@ module RuboCop
66
69
  :to_h)
67
70
  PATTERN
68
71
 
72
+ # @!method on_bad_to_h(node)
69
73
  def_node_matcher :on_bad_to_h, <<~PATTERN
70
74
  (block
71
75
  ({send csend} !#array_receiver? :to_h)
@@ -29,6 +29,7 @@ module RuboCop
29
29
  include HashTransformMethod
30
30
  extend AutoCorrector
31
31
 
32
+ # @!method on_bad_each_with_object(node)
32
33
  def_node_matcher :on_bad_each_with_object, <<~PATTERN
33
34
  (block
34
35
  ({send csend} !#array_receiver? :each_with_object (hash))
@@ -40,6 +41,7 @@ module RuboCop
40
41
  ({send csend} (lvar _memo) :[]= $(lvar _key) $!`_memo))
41
42
  PATTERN
42
43
 
44
+ # @!method on_bad_hash_brackets_map(node)
43
45
  def_node_matcher :on_bad_hash_brackets_map, <<~PATTERN
44
46
  (send
45
47
  (const _ :Hash)
@@ -52,6 +54,7 @@ module RuboCop
52
54
  (array $(lvar _key) $_)))
53
55
  PATTERN
54
56
 
57
+ # @!method on_bad_map_to_h(node)
55
58
  def_node_matcher :on_bad_map_to_h, <<~PATTERN
56
59
  ({send csend}
57
60
  (block
@@ -63,6 +66,7 @@ module RuboCop
63
66
  :to_h)
64
67
  PATTERN
65
68
 
69
+ # @!method on_bad_to_h(node)
66
70
  def_node_matcher :on_bad_to_h, <<~PATTERN
67
71
  (block
68
72
  ({send csend} !#array_receiver? :to_h)
@@ -34,9 +34,11 @@ module RuboCop
34
34
  MSG = 'Remove redundant %<keyword>s with boolean literal branches.'
35
35
  MSG_FOR_ELSIF = 'Use `else` instead of redundant `elsif` with boolean literal branches.'
36
36
 
37
+ # @!method if_with_boolean_literal_branches?(node)
37
38
  def_node_matcher :if_with_boolean_literal_branches?, <<~PATTERN
38
39
  (if #return_boolean_value? {(true) (false) | (false) (true)})
39
40
  PATTERN
41
+ # @!method double_negative?(node)
40
42
  def_node_matcher :double_negative?, '(send (send _ :!) :!)'
41
43
 
42
44
  def on_if(node)
@@ -19,6 +19,7 @@ module RuboCop
19
19
  ' rather than just a message.'
20
20
  RESTRICT_ON_SEND = %i[raise fail].freeze
21
21
 
22
+ # @!method implicit_runtime_error_raise_or_fail(node)
22
23
  def_node_matcher :implicit_runtime_error_raise_or_fail,
23
24
  '(send nil? ${:raise :fail} {str dstr})'
24
25
 
@@ -48,6 +48,7 @@ module RuboCop
48
48
  [Style::Not, Style::SymbolProc]
49
49
  end
50
50
 
51
+ # @!method inverse_candidate?(node)
51
52
  def_node_matcher :inverse_candidate?, <<~PATTERN
52
53
  {
53
54
  (send $(send $(...) $_ $...) :!)
@@ -56,6 +57,7 @@ module RuboCop
56
57
  }
57
58
  PATTERN
58
59
 
60
+ # @!method inverse_block?(node)
59
61
  def_node_matcher :inverse_block?, <<~PATTERN
60
62
  (block $(send (...) $_) ... { $(send ... :!)
61
63
  $(send (...) {:!= :!~} ...)
@@ -34,6 +34,7 @@ module RuboCop
34
34
 
35
35
  private
36
36
 
37
+ # @!method min_max_candidate(node)
37
38
  def_node_matcher :min_max_candidate, <<~PATTERN
38
39
  ({array return} (send [$_receiver !nil?] :min) (send [$_receiver !nil?] :max))
39
40
  PATTERN
@@ -45,11 +45,13 @@ module RuboCop
45
45
  'or `module`.'
46
46
  RESTRICT_ON_SEND = %i[include extend prepend].freeze
47
47
 
48
+ # @!method include_statement(node)
48
49
  def_node_matcher :include_statement, <<~PATTERN
49
50
  (send nil? ${:include :extend :prepend}
50
51
  const)
51
52
  PATTERN
52
53
 
54
+ # @!method in_top_level_scope?(node)
53
55
  def_node_matcher :in_top_level_scope?, <<~PATTERN
54
56
  {
55
57
  root? # either at the top level
@@ -82,8 +82,13 @@ module RuboCop
82
82
  FORBIDDEN_MSG =
83
83
  'Do not use `module_function` or `extend self`.'
84
84
 
85
+ # @!method module_function_node?(node)
85
86
  def_node_matcher :module_function_node?, '(send nil? :module_function)'
87
+
88
+ # @!method extend_self_node?(node)
86
89
  def_node_matcher :extend_self_node?, '(send nil? :extend self)'
90
+
91
+ # @!method private_directive?(node)
87
92
  def_node_matcher :private_directive?, '(send nil? :private ...)'
88
93
 
89
94
  def on_module(node)
@@ -47,11 +47,12 @@ module RuboCop
47
47
  'in a conditional, use `Array#include?` instead.'
48
48
 
49
49
  def on_new_investigation
50
- @compared_elements = []
51
- @allowed_method_comparison = false
50
+ @last_comparison = nil
52
51
  end
53
52
 
54
53
  def on_or(node)
54
+ reset_comparison if switch_comparison?(node)
55
+
55
56
  root_of_or_node = root_of_or_node(node)
56
57
 
57
58
  return unless node == root_of_or_node
@@ -64,14 +65,21 @@ module RuboCop
64
65
 
65
66
  corrector.replace(node, prefer_method)
66
67
  end
68
+
69
+ @last_comparison = node
67
70
  end
68
71
 
69
72
  private
70
73
 
74
+ # @!method simple_double_comparison?(node)
71
75
  def_node_matcher :simple_double_comparison?, '(send $lvar :== $lvar)'
76
+
77
+ # @!method simple_comparison_lhs?(node)
72
78
  def_node_matcher :simple_comparison_lhs?, <<~PATTERN
73
79
  (send $lvar :== $_)
74
80
  PATTERN
81
+
82
+ # @!method simple_comparison_rhs?(node)
75
83
  def_node_matcher :simple_comparison_rhs?, <<~PATTERN
76
84
  (send $_ :== $lvar)
77
85
  PATTERN
@@ -131,6 +139,17 @@ module RuboCop
131
139
  end
132
140
  end
133
141
 
142
+ def switch_comparison?(node)
143
+ return true if @last_comparison.nil?
144
+
145
+ @last_comparison.descendants.none? { |descendant| descendant == node }
146
+ end
147
+
148
+ def reset_comparison
149
+ @compared_elements = []
150
+ @allowed_method_comparison = false
151
+ end
152
+
134
153
  def allow_method_comparison?
135
154
  cop_config.fetch('AllowMethodComparison', true)
136
155
  end
@@ -154,12 +154,14 @@ module RuboCop
154
154
  end
155
155
  end
156
156
 
157
+ # @!method splat_value(node)
157
158
  def_node_matcher :splat_value, <<~PATTERN
158
159
  (array (splat $_))
159
160
  PATTERN
160
161
 
161
162
  # Some of these patterns may not actually return an immutable object,
162
163
  # but we want to consider them immutable for this cop.
164
+ # @!method operation_produces_immutable_object?(node)
163
165
  def_node_matcher :operation_produces_immutable_object?, <<~PATTERN
164
166
  {
165
167
  (const _ _)
@@ -176,6 +178,7 @@ module RuboCop
176
178
  }
177
179
  PATTERN
178
180
 
181
+ # @!method range_enclosed_in_parentheses?(node)
179
182
  def_node_matcher :range_enclosed_in_parentheses?, <<~PATTERN
180
183
  (begin ({irange erange} _ _))
181
184
  PATTERN
@@ -35,6 +35,7 @@ module RuboCop
35
35
 
36
36
  NEGATED_EQUALITY_METHODS = %i[!= !~].freeze
37
37
 
38
+ # @!method double_negation?(node)
38
39
  def_node_matcher :double_negation?, '(send (send _ :!) :!)'
39
40
 
40
41
  def self.autocorrect_incompatible_with
@@ -37,7 +37,10 @@ module RuboCop
37
37
 
38
38
  RESTRICT_ON_SEND = %i[== === nil?].freeze
39
39
 
40
+ # @!method nil_comparison?(node)
40
41
  def_node_matcher :nil_comparison?, '(send _ {:== :===} nil)'
42
+
43
+ # @!method nil_check?(node)
41
44
  def_node_matcher :nil_check?, '(send _ :nil?)'
42
45
 
43
46
  def on_send(node)
@@ -28,6 +28,7 @@ module RuboCop
28
28
 
29
29
  MSG = 'Use an empty lambda instead of always returning nil.'
30
30
 
31
+ # @!method nil_return?(node)
31
32
  def_node_matcher :nil_return?, <<~PATTERN
32
33
  { ({return next break} nil) (nil) }
33
34
  PATTERN
@@ -49,9 +49,16 @@ module RuboCop
49
49
 
50
50
  RESTRICT_ON_SEND = %i[!= nil? !].freeze
51
51
 
52
+ # @!method not_equal_to_nil?(node)
52
53
  def_node_matcher :not_equal_to_nil?, '(send _ :!= nil)'
54
+
55
+ # @!method unless_check?(node)
53
56
  def_node_matcher :unless_check?, '(if (send _ :nil?) ...)'
57
+
58
+ # @!method nil_check?(node)
54
59
  def_node_matcher :nil_check?, '(send _ :nil?)'
60
+
61
+ # @!method not_and_nil_check?(node)
55
62
  def_node_matcher :not_and_nil_check?, '(send (send _ :nil?) :!)'
56
63
 
57
64
  def on_send(node)