rubocop 1.32.0 → 1.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +73 -16
  4. data/config/obsoletion.yml +23 -1
  5. data/lib/rubocop/cache_config.rb +29 -0
  6. data/lib/rubocop/cli/command/{auto_genenerate_config.rb → auto_generate_config.rb} +2 -2
  7. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  8. data/lib/rubocop/cli/command/suggest_extensions.rb +53 -15
  9. data/lib/rubocop/config.rb +1 -1
  10. data/lib/rubocop/config_finder.rb +68 -0
  11. data/lib/rubocop/config_loader.rb +12 -40
  12. data/lib/rubocop/config_loader_resolver.rb +1 -5
  13. data/lib/rubocop/config_obsoletion/changed_parameter.rb +5 -0
  14. data/lib/rubocop/config_obsoletion/parameter_rule.rb +4 -0
  15. data/lib/rubocop/config_obsoletion.rb +7 -2
  16. data/lib/rubocop/cop/cop.rb +1 -1
  17. data/lib/rubocop/cop/correctors/parentheses_corrector.rb +58 -0
  18. data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
  19. data/lib/rubocop/cop/generator/require_file_injector.rb +2 -2
  20. data/lib/rubocop/cop/internal_affairs/numblock_handler.rb +69 -0
  21. data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +62 -0
  22. data/lib/rubocop/cop/internal_affairs.rb +2 -0
  23. data/lib/rubocop/cop/layout/block_alignment.rb +2 -0
  24. data/lib/rubocop/cop/layout/block_end_newline.rb +35 -5
  25. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +5 -2
  26. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +2 -0
  27. data/lib/rubocop/cop/layout/end_of_line.rb +4 -4
  28. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -1
  29. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -2
  30. data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -2
  31. data/lib/rubocop/cop/layout/indentation_width.rb +2 -0
  32. data/lib/rubocop/cop/layout/line_length.rb +4 -1
  33. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  34. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  35. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  36. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
  37. data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
  38. data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
  39. data/lib/rubocop/cop/legacy/corrections_proxy.rb +1 -1
  40. data/lib/rubocop/cop/legacy/corrector.rb +1 -1
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +21 -8
  42. data/lib/rubocop/cop/lint/debugger.rb +26 -16
  43. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  44. data/lib/rubocop/cop/lint/empty_block.rb +1 -1
  45. data/lib/rubocop/cop/lint/empty_conditional_body.rb +65 -1
  46. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -9
  47. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +4 -0
  48. data/lib/rubocop/cop/lint/next_without_accumulator.rb +25 -6
  49. data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +6 -6
  50. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +12 -0
  51. data/lib/rubocop/cop/lint/number_conversion.rb +24 -8
  52. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +9 -3
  53. data/lib/rubocop/cop/lint/redundant_with_index.rb +13 -10
  54. data/lib/rubocop/cop/lint/redundant_with_object.rb +12 -11
  55. data/lib/rubocop/cop/lint/shadowed_exception.rb +15 -0
  56. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +10 -1
  57. data/lib/rubocop/cop/lint/unreachable_loop.rb +7 -1
  58. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -4
  59. data/lib/rubocop/cop/lint/void.rb +2 -0
  60. data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
  61. data/lib/rubocop/cop/metrics/block_length.rb +6 -7
  62. data/lib/rubocop/cop/metrics/method_length.rb +8 -8
  63. data/lib/rubocop/cop/mixin/allowed_methods.rb +15 -1
  64. data/lib/rubocop/cop/mixin/allowed_pattern.rb +9 -1
  65. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  66. data/lib/rubocop/cop/mixin/comments_help.rb +5 -1
  67. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -1
  68. data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +76 -1
  69. data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
  70. data/lib/rubocop/cop/mixin/method_complexity.rb +8 -13
  71. data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
  72. data/lib/rubocop/cop/mixin/range_help.rb +4 -5
  73. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  74. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  75. data/lib/rubocop/cop/naming/predicate_name.rb +24 -3
  76. data/lib/rubocop/cop/style/arguments_forwarding.rb +2 -2
  77. data/lib/rubocop/cop/style/block_delimiters.rb +26 -7
  78. data/lib/rubocop/cop/style/class_and_module_children.rb +4 -4
  79. data/lib/rubocop/cop/style/class_equality_comparison.rb +32 -7
  80. data/lib/rubocop/cop/style/class_methods_definitions.rb +2 -1
  81. data/lib/rubocop/cop/style/collection_methods.rb +2 -0
  82. data/lib/rubocop/cop/style/combinable_loops.rb +3 -1
  83. data/lib/rubocop/cop/style/double_negation.rb +2 -0
  84. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  85. data/lib/rubocop/cop/style/each_with_object.rb +39 -8
  86. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
  87. data/lib/rubocop/cop/style/empty_heredoc.rb +15 -1
  88. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
  89. data/lib/rubocop/cop/style/for.rb +2 -0
  90. data/lib/rubocop/cop/style/format_string_token.rb +21 -8
  91. data/lib/rubocop/cop/style/guard_clause.rb +27 -16
  92. data/lib/rubocop/cop/style/hash_each_methods.rb +3 -1
  93. data/lib/rubocop/cop/style/hash_except.rb +0 -4
  94. data/lib/rubocop/cop/style/hash_syntax.rb +17 -0
  95. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  96. data/lib/rubocop/cop/style/inverse_methods.rb +8 -6
  97. data/lib/rubocop/cop/style/magic_comment_format.rb +307 -0
  98. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  99. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +5 -1
  100. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -7
  101. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +11 -6
  102. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +4 -1
  103. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -1
  104. data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +1 -1
  105. data/lib/rubocop/cop/style/next.rb +3 -5
  106. data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
  107. data/lib/rubocop/cop/style/numeric_literals.rb +16 -1
  108. data/lib/rubocop/cop/style/numeric_predicate.rb +28 -8
  109. data/lib/rubocop/cop/style/object_then.rb +2 -0
  110. data/lib/rubocop/cop/style/proc.rb +4 -1
  111. data/lib/rubocop/cop/style/redundant_begin.rb +2 -0
  112. data/lib/rubocop/cop/style/redundant_condition.rb +19 -4
  113. data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
  114. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -22
  115. data/lib/rubocop/cop/style/redundant_self.rb +2 -0
  116. data/lib/rubocop/cop/style/redundant_sort.rb +21 -6
  117. data/lib/rubocop/cop/style/redundant_sort_by.rb +24 -8
  118. data/lib/rubocop/cop/style/safe_navigation.rb +4 -2
  119. data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
  120. data/lib/rubocop/cop/style/sole_nested_conditional.rb +14 -5
  121. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  122. data/lib/rubocop/cop/style/symbol_proc.rb +34 -9
  123. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -13
  124. data/lib/rubocop/cop/style/top_level_method_definition.rb +3 -1
  125. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
  126. data/lib/rubocop/cop/style/word_array.rb +1 -1
  127. data/lib/rubocop/cop/util.rb +1 -1
  128. data/lib/rubocop/ext/range.rb +15 -0
  129. data/lib/rubocop/feature_loader.rb +94 -0
  130. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -1
  131. data/lib/rubocop/formatter/disabled_config_formatter.rb +1 -1
  132. data/lib/rubocop/formatter/html_formatter.rb +3 -3
  133. data/lib/rubocop/formatter/markdown_formatter.rb +1 -1
  134. data/lib/rubocop/formatter/tap_formatter.rb +1 -1
  135. data/lib/rubocop/result_cache.rb +22 -20
  136. data/lib/rubocop/server/cache.rb +36 -1
  137. data/lib/rubocop/server/cli.rb +19 -2
  138. data/lib/rubocop/version.rb +1 -1
  139. data/lib/rubocop.rb +5 -3
  140. metadata +15 -9
  141. data/lib/rubocop/cop/mixin/ignored_methods.rb +0 -52
@@ -14,8 +14,8 @@ module RuboCop
14
14
  #
15
15
  #
16
16
  # NOTE: The `ExcludedMethods` configuration is deprecated and only kept
17
- # for backwards compatibility. Please use `IgnoredMethods` instead.
18
- # By default, there are no methods to ignored.
17
+ # for backwards compatibility. Please use `AllowedMethods` and `AllowedPatterns`
18
+ # instead. By default, there are no methods to allowed.
19
19
  #
20
20
  # @example CountAsOne: ['array', 'heredoc']
21
21
  #
@@ -38,14 +38,13 @@ module RuboCop
38
38
  # NOTE: This cop does not apply for `Struct` definitions.
39
39
  class BlockLength < Base
40
40
  include CodeLength
41
- include IgnoredMethods
42
-
43
- ignored_methods deprecated_key: 'ExcludedMethods'
41
+ include AllowedMethods
42
+ include AllowedPattern
44
43
 
45
44
  LABEL = 'Block'
46
45
 
47
46
  def on_block(node)
48
- return if ignored_method?(node.method_name)
47
+ return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
49
48
  return if method_receiver_excluded?(node)
50
49
  return if node.class_constructor? || node.struct_constructor?
51
50
 
@@ -59,7 +58,7 @@ module RuboCop
59
58
  node_receiver = node.receiver&.source&.gsub(/\s+/, '')
60
59
  node_method = String(node.method_name)
61
60
 
62
- ignored_methods.any? do |config|
61
+ allowed_methods.any? do |config|
63
62
  next unless config.is_a?(String)
64
63
 
65
64
  receiver, method = config.split('.')
@@ -4,16 +4,17 @@ module RuboCop
4
4
  module Cop
5
5
  module Metrics
6
6
  # Checks if the length of a method exceeds some maximum value.
7
- # Comment lines can optionally be ignored.
7
+ # Comment lines can optionally be allowed.
8
8
  # The maximum allowed length is configurable.
9
9
  #
10
10
  # You can set literals you want to fold with `CountAsOne`.
11
11
  # Available are: 'array', 'hash', and 'heredoc'. Each literal
12
12
  # will be counted as one line regardless of its actual size.
13
13
  #
14
- # NOTE: The `ExcludedMethods` configuration is deprecated and only kept
15
- # for backwards compatibility. Please use `IgnoredMethods` instead.
16
- # By default, there are no methods to ignored.
14
+ # NOTE: The `ExcludedMethods` and `IgnoredMethods` configuration is
15
+ # deprecated and only kept for backwards compatibility.
16
+ # Please use `AllowedMethods` and `AllowedPatterns` instead.
17
+ # By default, there are no methods to allowed.
17
18
  #
18
19
  # @example CountAsOne: ['array', 'heredoc']
19
20
  #
@@ -35,14 +36,13 @@ module RuboCop
35
36
  #
36
37
  class MethodLength < Base
37
38
  include CodeLength
38
- include IgnoredMethods
39
-
40
- ignored_methods deprecated_key: 'ExcludedMethods'
39
+ include AllowedMethods
40
+ include AllowedPattern
41
41
 
42
42
  LABEL = 'Method'
43
43
 
44
44
  def on_def(node)
45
- return if ignored_method?(node.method_name)
45
+ return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
46
46
 
47
47
  check_code_length(node)
48
48
  end
@@ -12,10 +12,24 @@ module RuboCop
12
12
  allowed_methods.include?(name.to_s)
13
13
  end
14
14
 
15
+ # @deprecated Use allowed_method? instead
16
+ alias ignored_method? allowed_method?
17
+
15
18
  # @api public
16
19
  def allowed_methods
17
- cop_config.fetch('AllowedMethods', [])
20
+ deprecated_values = cop_config_deprecated_values
21
+ if deprecated_values.any?(Regexp)
22
+ cop_config.fetch('AllowedMethods', [])
23
+ else
24
+ Array(cop_config['AllowedMethods']).concat(deprecated_values)
25
+ end
26
+ end
27
+
28
+ def cop_config_deprecated_values
29
+ Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods']))
18
30
  end
19
31
  end
32
+ # @deprecated IgnoredMethods class has been replaced with AllowedMethods.
33
+ IgnoredMethods = AllowedMethods
20
34
  end
21
35
  end
@@ -30,7 +30,15 @@ module RuboCop
30
30
  def allowed_patterns
31
31
  # Since there could be a pattern specified in the default config, merge the two
32
32
  # arrays together.
33
- Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns']))
33
+ patterns = Array(cop_config['AllowedPatterns']).concat(Array(cop_config['IgnoredPatterns']))
34
+ deprecated_values = cop_config_deprecated_methods_values
35
+ return patterns unless deprecated_values.any?(Regexp)
36
+
37
+ Array(patterns.concat(deprecated_values))
38
+ end
39
+
40
+ def cop_config_deprecated_methods_values
41
+ Array(cop_config['IgnoredMethods']).concat(Array(cop_config['ExcludedMethods']))
34
42
  end
35
43
  end
36
44
 
@@ -220,7 +220,7 @@ module RuboCop
220
220
  def already_on_multiple_lines?(node)
221
221
  return node.first_line != node.arguments.last.last_line if node.def_type?
222
222
 
223
- node.first_line != node.last_line
223
+ !node.single_line?
224
224
  end
225
225
  end
226
226
  end
@@ -12,10 +12,14 @@ module RuboCop
12
12
  end
13
13
 
14
14
  def contains_comments?(node)
15
+ comments_in_range(node).any?
16
+ end
17
+
18
+ def comments_in_range(node)
15
19
  start_line = node.source_range.line
16
20
  end_line = find_end_line(node)
17
21
 
18
- processed_source.each_comment_in_lines(start_line...end_line).any?
22
+ processed_source.each_comment_in_lines(start_line...end_line)
19
23
  end
20
24
 
21
25
  private
@@ -6,7 +6,8 @@ module RuboCop
6
6
  #
7
7
  # IMPORTANT: RuboCop core depended on this module when it supported Rails department.
8
8
  # Rails department has been extracted to RuboCop Rails gem.
9
- # This module is deprecated and will be removed by RuboCop 2.0.
9
+ #
10
+ # @deprecated This module is deprecated and will be removed by RuboCop 2.0.
10
11
  # It will not be updated to `RuboCop::Cop::Base` v1 API to maintain compatibility
11
12
  # with existing RuboCop Rails 2.8 or lower.
12
13
  #
@@ -5,7 +5,22 @@ module RuboCop
5
5
  # This module checks for Ruby 3.1's hash value omission syntax.
6
6
  module HashShorthandSyntax
7
7
  OMIT_HASH_VALUE_MSG = 'Omit the hash value.'
8
- EXPLICIT_HASH_VALUE_MSG = 'Explicit the hash value.'
8
+ EXPLICIT_HASH_VALUE_MSG = 'Include the hash value.'
9
+ DO_NOT_MIX_MSG_PREFIX = 'Do not mix explicit and implicit hash values.'
10
+ DO_NOT_MIX_OMIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{OMIT_HASH_VALUE_MSG}"
11
+ DO_NOT_MIX_EXPLICIT_VALUE_MSG = "#{DO_NOT_MIX_MSG_PREFIX} #{EXPLICIT_HASH_VALUE_MSG}"
12
+
13
+ def on_hash_for_mixed_shorthand(hash_node)
14
+ return if ignore_mixed_hash_shorthand_syntax?(hash_node)
15
+
16
+ hash_value_type_breakdown = breakdown_value_types_of_hash(hash_node)
17
+
18
+ if hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
19
+ mixed_shorthand_syntax_check(hash_value_type_breakdown)
20
+ else
21
+ no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
22
+ end
23
+ end
9
24
 
10
25
  def on_pair(node)
11
26
  return if ignore_hash_shorthand_syntax?(node)
@@ -36,8 +51,14 @@ module RuboCop
36
51
  end
37
52
  end
38
53
 
54
+ def ignore_mixed_hash_shorthand_syntax?(hash_node)
55
+ target_ruby_version <= 3.0 || enforced_shorthand_syntax != 'consistent' ||
56
+ !hash_node.hash_type?
57
+ end
58
+
39
59
  def ignore_hash_shorthand_syntax?(pair_node)
40
60
  target_ruby_version <= 3.0 || enforced_shorthand_syntax == 'either' ||
61
+ enforced_shorthand_syntax == 'consistent' ||
41
62
  !pair_node.parent.hash_type?
42
63
  end
43
64
 
@@ -81,6 +102,60 @@ module RuboCop
81
102
 
82
103
  ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized? && !!right_sibling
83
104
  end
105
+
106
+ def breakdown_value_types_of_hash(hash_node)
107
+ hash_node.pairs.group_by do |pair_node|
108
+ if pair_node.value_omission?
109
+ :value_omitted
110
+ elsif require_hash_value?(pair_node.key.source, pair_node)
111
+ :value_needed
112
+ else
113
+ :value_omittable
114
+ end
115
+ end
116
+ end
117
+
118
+ def hash_with_mixed_shorthand_syntax?(hash_value_type_breakdown)
119
+ hash_value_type_breakdown.keys.size > 1
120
+ end
121
+
122
+ def hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
123
+ hash_value_type_breakdown[:value_needed]&.any?
124
+ end
125
+
126
+ def each_omitted_value_pair(hash_value_type_breakdown, &block)
127
+ hash_value_type_breakdown[:value_omitted]&.each(&block)
128
+ end
129
+
130
+ def each_omittable_value_pair(hash_value_type_breakdown, &block)
131
+ hash_value_type_breakdown[:value_omittable]&.each(&block)
132
+ end
133
+
134
+ def mixed_shorthand_syntax_check(hash_value_type_breakdown)
135
+ if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
136
+ each_omitted_value_pair(hash_value_type_breakdown) do |pair_node|
137
+ hash_key_source = pair_node.key.source
138
+ replacement = "#{hash_key_source}: #{hash_key_source}"
139
+ register_offense(pair_node, DO_NOT_MIX_EXPLICIT_VALUE_MSG, replacement)
140
+ end
141
+ else
142
+ each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
143
+ hash_key_source = pair_node.key.source
144
+ replacement = "#{hash_key_source}:"
145
+ register_offense(pair_node, DO_NOT_MIX_OMIT_VALUE_MSG, replacement)
146
+ end
147
+ end
148
+ end
149
+
150
+ def no_mixed_shorthand_syntax_check(hash_value_type_breakdown)
151
+ return if hash_with_values_that_cant_be_omitted?(hash_value_type_breakdown)
152
+
153
+ each_omittable_value_pair(hash_value_type_breakdown) do |pair_node|
154
+ hash_key_source = pair_node.key.source
155
+ replacement = "#{hash_key_source}:"
156
+ register_offense(pair_node, OMIT_HASH_VALUE_MSG, replacement)
157
+ end
158
+ end
84
159
  end
85
160
  end
86
161
  end
@@ -14,7 +14,7 @@ module RuboCop
14
14
  {(array ...) (send _ :each_with_index) (send _ :with_index _ ?) (send _ :zip ...)}
15
15
  PATTERN
16
16
 
17
- def on_block(node)
17
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
18
18
  on_bad_each_with_object(node) do |*match|
19
19
  handle_possible_offense(node, match, 'each_with_object')
20
20
  end
@@ -6,21 +6,16 @@ module RuboCop
6
6
  #
7
7
  # This module handles measurement and reporting of complexity in methods.
8
8
  module MethodComplexity
9
- include IgnoredMethods
9
+ include AllowedMethods
10
+ include AllowedPattern
10
11
  include Metrics::Utils::RepeatedCsendDiscount
11
12
  extend NodePattern::Macros
12
13
  extend ExcludeLimit
13
14
 
14
15
  exclude_limit 'Max'
15
16
 
16
- # Ensure cops that include `MethodComplexity` have the config
17
- # `attr_accessor`s that `ignored_method?` needs.
18
- def self.included(base)
19
- base.extend(IgnoredMethods::Config)
20
- end
21
-
22
17
  def on_def(node)
23
- return if ignored_method?(node.method_name)
18
+ return if allowed_method?(node.method_name) || matches_allowed_pattern?(node.method_name)
24
19
 
25
20
  check_complexity(node, node.method_name)
26
21
  end
@@ -28,20 +23,20 @@ module RuboCop
28
23
 
29
24
  def on_block(node)
30
25
  define_method?(node) do |name|
31
- return if ignored_method?(name)
26
+ return if allowed_method?(name) || matches_allowed_pattern?(name)
32
27
 
33
28
  check_complexity(node, name)
34
29
  end
35
30
  end
36
31
 
32
+ alias on_numblock on_block
33
+
37
34
  private
38
35
 
39
36
  # @!method define_method?(node)
40
37
  def_node_matcher :define_method?, <<~PATTERN
41
- (block
42
- (send nil? :define_method ({sym str} $_))
43
- args
44
- _)
38
+ ({block numblock}
39
+ (send nil? :define_method ({sym str} $_)) _ _)
45
40
  PATTERN
46
41
 
47
42
  def check_complexity(node, method_name)
@@ -57,7 +57,7 @@ module RuboCop
57
57
  end
58
58
 
59
59
  if left_parenthesis && style == :special_inside_parentheses
60
- return [left_parenthesis.column + 1, :first_colmn_after_left_parenthesis]
60
+ return [left_parenthesis.column + 1, :first_column_after_left_parenthesis]
61
61
  end
62
62
 
63
63
  [left_brace.source_line =~ /\S/, :start_of_line]
@@ -54,11 +54,11 @@ module RuboCop
54
54
  NOT_GIVEN = Module.new
55
55
  def range_with_surrounding_space(range_positional = NOT_GIVEN, # rubocop:disable Metrics/ParameterLists
56
56
  range: NOT_GIVEN, side: :both, newlines: true,
57
- whitespace: false, continuations: false)
57
+ whitespace: false, continuations: false,
58
+ buffer: @processed_source.buffer)
58
59
 
59
60
  range = range_positional unless range_positional == NOT_GIVEN
60
61
 
61
- buffer = @processed_source.buffer
62
62
  src = buffer.source
63
63
 
64
64
  go_left, go_right = directions(side)
@@ -70,9 +70,8 @@ module RuboCop
70
70
  Parser::Source::Range.new(buffer, begin_pos, end_pos)
71
71
  end
72
72
 
73
- def range_by_whole_lines(range, include_final_newline: false)
74
- buffer = @processed_source.buffer
75
-
73
+ def range_by_whole_lines(range, include_final_newline: false,
74
+ buffer: @processed_source.buffer)
76
75
  last_line = buffer.source_line(range.last_line)
77
76
  end_offset = last_line.length - range.last_column
78
77
  end_offset += 1 if include_final_newline
@@ -38,7 +38,7 @@ module RuboCop
38
38
  class BlockParameterName < Base
39
39
  include UncommunicativeName
40
40
 
41
- def on_block(node)
41
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
42
42
  return unless node.arguments?
43
43
 
44
44
  check(node, node.arguments)
@@ -72,10 +72,10 @@ module RuboCop
72
72
  PATTERN
73
73
 
74
74
  def allowed_conditional_expression_on_rhs?(node)
75
- node&.if_type? && contains_contant?(node)
75
+ node&.if_type? && contains_constant?(node)
76
76
  end
77
77
 
78
- def contains_contant?(node)
78
+ def contains_constant?(node)
79
79
  node.branches.any?(&:const_type?)
80
80
  end
81
81
  end
@@ -3,9 +3,30 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Naming
6
- # Makes sure that predicates are named properly.
7
- # `is_a?` method is allowed by default.
8
- # These are customizable with `AllowedMethods` option.
6
+ # Checks that predicate methods names end with a question mark and
7
+ # do not start with a forbidden prefix.
8
+ #
9
+ # A method is determined to be a predicate method if its name starts
10
+ # with one of the prefixes defined in the `NamePrefix` configuration.
11
+ # You can change what prefixes are considered by changing this option.
12
+ # Any method name that starts with one of these prefixes is required by
13
+ # the cop to end with a `?`. Other methods can be allowed by adding to
14
+ # the `AllowedMethods` configuration.
15
+ #
16
+ # NOTE: The `is_a?` method is allowed by default.
17
+ #
18
+ # If `ForbiddenPrefixes` is set, methods that start with the configured
19
+ # prefixes will not be allowed and will be removed by autocorrection.
20
+ #
21
+ # In other words, if `ForbiddenPrefixes` is empty, a method named `is_foo`
22
+ # will register an offense only due to the lack of question mark (and will be
23
+ # autocorrected to `is_foo?`). If `ForbiddenPrefixes` contains `is_`,
24
+ # `is_foo` will register an offense both because the ? is missing and because of
25
+ # the `is_` prefix, and will be corrected to `foo?`.
26
+ #
27
+ # NOTE: `ForbiddenPrefixes` is only applied to prefixes in `NamePrefix`;
28
+ # a prefix in the former but not the latter will not be considered by
29
+ # this cop.
9
30
  #
10
31
  # @example
11
32
  # # bad
@@ -73,11 +73,11 @@ module RuboCop
73
73
  {
74
74
  (send _ _
75
75
  (splat (lvar %1))
76
- (block-pass (lvar %2)))
76
+ (block-pass {(lvar %2) nil?}))
77
77
  (send _ _
78
78
  (splat (lvar %1))
79
79
  (hash (kwsplat (lvar %3)))
80
- (block-pass (lvar %2)))
80
+ (block-pass {(lvar %2) nil?}))
81
81
  }
82
82
  PATTERN
83
83
 
@@ -10,7 +10,7 @@ module RuboCop
10
10
  # Methods that can be either procedural or functional and cannot be
11
11
  # categorised from their usage alone is ignored.
12
12
  # `lambda`, `proc`, and `it` are their defaults.
13
- # Additional methods can be added to the `IgnoredMethods`.
13
+ # Additional methods can be added to the `AllowedMethods`.
14
14
  #
15
15
  # @example EnforcedStyle: line_count_based (default)
16
16
  # # bad - single line block
@@ -66,7 +66,7 @@ module RuboCop
66
66
  # x
67
67
  # }.inspect
68
68
  #
69
- # # The AllowBracesOnProceduralOneLiners option is ignored unless the
69
+ # # The AllowBracesOnProceduralOneLiners option is allowed unless the
70
70
  # # EnforcedStyle is set to `semantic`. If so:
71
71
  #
72
72
  # # If the AllowBracesOnProceduralOneLiners option is unspecified, or
@@ -116,7 +116,7 @@ module RuboCop
116
116
  #
117
117
  # # Methods listed in the BracesRequiredMethods list, such as 'sig'
118
118
  # # in this example, will require `{...}` braces. This option takes
119
- # # precedence over all other configurations except IgnoredMethods.
119
+ # # precedence over all other configurations except AllowedMethods.
120
120
  #
121
121
  # # bad
122
122
  # sig do
@@ -138,7 +138,7 @@ module RuboCop
138
138
  # puts foo
139
139
  # end
140
140
  #
141
- # @example IgnoredMethods: ['lambda', 'proc', 'it' ] (default)
141
+ # @example AllowedMethods: ['lambda', 'proc', 'it' ] (default)
142
142
  #
143
143
  # # good
144
144
  # foo = lambda do |x|
@@ -149,9 +149,26 @@ module RuboCop
149
149
  # x * 100
150
150
  # end
151
151
  #
152
+ # @example AllowedPatterns: [] (default)
153
+ #
154
+ # # bad
155
+ # things.map { |thing|
156
+ # something = thing.some_method
157
+ # process(something)
158
+ # }
159
+ #
160
+ # @example AllowedPatterns: [/map/]
161
+ #
162
+ # # good
163
+ # things.map { |thing|
164
+ # something = thing.some_method
165
+ # process(something)
166
+ # }
167
+ #
152
168
  class BlockDelimiters < Base
153
169
  include ConfigurableEnforcedStyle
154
- include IgnoredMethods
170
+ include AllowedMethods
171
+ include AllowedPattern
155
172
  include RangeHelp
156
173
  extend AutoCorrector
157
174
 
@@ -330,12 +347,14 @@ module RuboCop
330
347
  end
331
348
 
332
349
  def special_method?(method_name)
333
- ignored_method?(method_name) || braces_required_method?(method_name)
350
+ allowed_method?(method_name) ||
351
+ matches_allowed_pattern?(method_name) ||
352
+ braces_required_method?(method_name)
334
353
  end
335
354
 
336
355
  def special_method_proper_block_style?(node)
337
356
  method_name = node.method_name
338
- return true if ignored_method?(method_name)
357
+ return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
339
358
  return node.braces? if braces_required_method?(method_name)
340
359
  end
341
360
 
@@ -117,10 +117,10 @@ module RuboCop
117
117
  end
118
118
 
119
119
  def remove_end(corrector, body)
120
- range = range_between(
121
- body.loc.end.begin_pos - leading_spaces(body).size,
122
- body.loc.end.end_pos + 1
123
- )
120
+ remove_begin_pos = body.loc.end.begin_pos - leading_spaces(body).size
121
+ adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
122
+ range = range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
123
+
124
124
  corrector.remove(range)
125
125
  end
126
126
 
@@ -5,8 +5,8 @@ module RuboCop
5
5
  module Style
6
6
  # Enforces the use of `Object#instance_of?` instead of class comparison
7
7
  # for equality.
8
- # `==`, `equal?`, and `eql?` methods are ignored by default.
9
- # These are customizable with `IgnoredMethods` option.
8
+ # `==`, `equal?`, and `eql?` methods are allowed by default.
9
+ # These are customizable with `AllowedMethods` option.
10
10
  #
11
11
  # @example
12
12
  # # bad
@@ -18,7 +18,7 @@ module RuboCop
18
18
  # # good
19
19
  # var.instance_of?(Date)
20
20
  #
21
- # @example IgnoreMethods: [] (default)
21
+ # @example AllowedMethods: [] (default)
22
22
  # # good
23
23
  # var.instance_of?(Date)
24
24
  #
@@ -28,7 +28,7 @@ module RuboCop
28
28
  # var.class.eql?(Date)
29
29
  # var.class.name == 'Date'
30
30
  #
31
- # @example IgnoreMethods: [`==`]
31
+ # @example AllowedMethods: [`==`]
32
32
  # # good
33
33
  # var.instance_of?(Date)
34
34
  # var.class == Date
@@ -38,9 +38,30 @@ module RuboCop
38
38
  # var.class.equal?(Date)
39
39
  # var.class.eql?(Date)
40
40
  #
41
+ # @example AllowedPatterns: [] (default)
42
+ # # good
43
+ # var.instance_of?(Date)
44
+ #
45
+ # # bad
46
+ # var.class == Date
47
+ # var.class.equal?(Date)
48
+ # var.class.eql?(Date)
49
+ # var.class.name == 'Date'
50
+ #
51
+ # @example AllowedPatterns: [`/eq/`]
52
+ # # good
53
+ # var.instance_of?(Date)
54
+ # var.class.equal?(Date)
55
+ # var.class.eql?(Date)
56
+ #
57
+ # # bad
58
+ # var.class == Date
59
+ # var.class.name == 'Date'
60
+ #
41
61
  class ClassEqualityComparison < Base
42
62
  include RangeHelp
43
- include IgnoredMethods
63
+ include AllowedMethods
64
+ include AllowedPattern
44
65
  extend AutoCorrector
45
66
 
46
67
  MSG = 'Use `instance_of?(%<class_name>s)` instead of comparing classes.'
@@ -56,7 +77,9 @@ module RuboCop
56
77
 
57
78
  def on_send(node)
58
79
  def_node = node.each_ancestor(:def, :defs).first
59
- return if def_node && ignored_method?(def_node.method_name)
80
+ return if def_node &&
81
+ (allowed_method?(def_node.method_name) ||
82
+ matches_allowed_pattern?(def_node.method_name))
60
83
 
61
84
  class_comparison_candidate?(node) do |receiver_node, class_node|
62
85
  range = offense_range(receiver_node, node)
@@ -74,7 +97,9 @@ module RuboCop
74
97
  if node.children.first.method?(:name)
75
98
  return class_node.receiver.source if class_node.receiver
76
99
 
77
- class_node.source.delete('"').delete("'")
100
+ value = class_node.source.delete('"').delete("'")
101
+ value.prepend('::') if class_node.each_ancestor(:class, :module).any?
102
+ value
78
103
  else
79
104
  class_node.source
80
105
  end
@@ -70,7 +70,7 @@ module RuboCop
70
70
 
71
71
  def on_sclass(node)
72
72
  return unless def_self_style?
73
- return unless node.identifier.source == 'self'
73
+ return unless node.identifier.self_type?
74
74
  return unless all_methods_public?(node)
75
75
 
76
76
  add_offense(node, message: MSG_SCLASS) do |corrector|
@@ -80,6 +80,7 @@ module RuboCop
80
80
 
81
81
  def on_defs(node)
82
82
  return if def_self_style?
83
+ return unless node.receiver.self_type?
83
84
 
84
85
  message = format(MSG, preferred: 'class << self')
85
86
  add_offense(node, message: message)
@@ -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