rubocop 0.90.0 → 0.93.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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/config/default.yml +79 -3
  4. data/lib/rubocop.rb +20 -5
  5. data/lib/rubocop/cached_data.rb +2 -1
  6. data/lib/rubocop/cli/command/execute_runner.rb +8 -0
  7. data/lib/rubocop/comment_config.rb +9 -5
  8. data/lib/rubocop/config_loader.rb +3 -3
  9. data/lib/rubocop/config_regeneration.rb +33 -0
  10. data/lib/rubocop/config_store.rb +3 -3
  11. data/lib/rubocop/cop/bundler/duplicated_gem.rb +5 -1
  12. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -0
  13. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -0
  14. data/lib/rubocop/cop/correctors/line_break_corrector.rb +2 -2
  15. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -10
  16. data/lib/rubocop/cop/generator.rb +1 -1
  17. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +1 -0
  18. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -0
  19. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +1 -0
  20. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -0
  21. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +1 -0
  22. data/lib/rubocop/cop/layout/array_alignment.rb +1 -0
  23. data/lib/rubocop/cop/layout/begin_end_alignment.rb +77 -0
  24. data/lib/rubocop/cop/layout/case_indentation.rb +4 -7
  25. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  26. data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
  27. data/lib/rubocop/cop/layout/dot_position.rb +6 -9
  28. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
  29. data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +4 -12
  30. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +13 -8
  31. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +2 -2
  32. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -2
  33. data/lib/rubocop/cop/layout/end_alignment.rb +5 -10
  34. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +26 -4
  35. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +4 -13
  36. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -7
  37. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +0 -4
  38. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +6 -21
  39. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +3 -8
  40. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +2 -2
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -0
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -0
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +18 -1
  44. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -2
  45. data/lib/rubocop/cop/lint/boolean_symbol.rb +3 -0
  46. data/lib/rubocop/cop/lint/constant_definition_in_block.rb +74 -0
  47. data/lib/rubocop/cop/lint/debugger.rb +2 -3
  48. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -3
  49. data/lib/rubocop/cop/lint/duplicate_methods.rb +2 -4
  50. data/lib/rubocop/cop/lint/duplicate_require.rb +7 -2
  51. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +2 -4
  52. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -0
  53. data/lib/rubocop/cop/lint/empty_file.rb +1 -4
  54. data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -0
  55. data/lib/rubocop/cop/lint/float_comparison.rb +2 -2
  56. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
  57. data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +37 -0
  58. data/lib/rubocop/cop/lint/identity_comparison.rb +51 -0
  59. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +2 -5
  60. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  61. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -0
  62. data/lib/rubocop/cop/lint/multiple_comparison.rb +3 -1
  63. data/lib/rubocop/cop/lint/number_conversion.rb +1 -0
  64. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +1 -2
  65. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -1
  66. data/lib/rubocop/cop/lint/raise_exception.rb +1 -0
  67. data/lib/rubocop/cop/lint/rand_one.rb +2 -1
  68. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +22 -12
  69. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +14 -4
  70. data/lib/rubocop/cop/lint/redundant_require_statement.rb +1 -0
  71. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +78 -0
  72. data/lib/rubocop/cop/lint/rescue_type.rb +0 -1
  73. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +3 -1
  74. data/lib/rubocop/cop/lint/shadowed_exception.rb +6 -6
  75. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -0
  76. data/lib/rubocop/cop/lint/to_json.rb +16 -5
  77. data/lib/rubocop/cop/lint/unreachable_loop.rb +3 -6
  78. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +3 -1
  79. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -1
  80. data/lib/rubocop/cop/lint/useless_access_modifier.rb +3 -9
  81. data/lib/rubocop/cop/lint/useless_method_definition.rb +20 -27
  82. data/lib/rubocop/cop/lint/useless_times.rb +106 -0
  83. data/lib/rubocop/cop/metrics/block_length.rb +3 -1
  84. data/lib/rubocop/cop/metrics/class_length.rb +14 -6
  85. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +25 -16
  86. data/lib/rubocop/cop/mixin/comments_help.rb +3 -9
  87. data/lib/rubocop/cop/mixin/configurable_naming.rb +2 -2
  88. data/lib/rubocop/cop/mixin/configurable_numbering.rb +3 -3
  89. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +9 -0
  90. data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -2
  91. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -0
  92. data/lib/rubocop/cop/mixin/statement_modifier.rb +9 -3
  93. data/lib/rubocop/cop/mixin/visibility_help.rb +4 -16
  94. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  95. data/lib/rubocop/cop/naming/file_name.rb +1 -1
  96. data/lib/rubocop/cop/offense.rb +15 -2
  97. data/lib/rubocop/cop/security/eval.rb +1 -0
  98. data/lib/rubocop/cop/security/json_load.rb +1 -0
  99. data/lib/rubocop/cop/security/marshal_load.rb +1 -0
  100. data/lib/rubocop/cop/security/open.rb +1 -0
  101. data/lib/rubocop/cop/security/yaml_load.rb +1 -0
  102. data/lib/rubocop/cop/style/access_modifier_declarations.rb +7 -11
  103. data/lib/rubocop/cop/style/accessor_grouping.rb +3 -0
  104. data/lib/rubocop/cop/style/alias.rb +2 -0
  105. data/lib/rubocop/cop/style/array_coercion.rb +4 -0
  106. data/lib/rubocop/cop/style/array_join.rb +1 -0
  107. data/lib/rubocop/cop/style/attr.rb +1 -0
  108. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +2 -0
  109. data/lib/rubocop/cop/style/case_equality.rb +3 -0
  110. data/lib/rubocop/cop/style/case_like_if.rb +20 -4
  111. data/lib/rubocop/cop/style/class_and_module_children.rb +2 -0
  112. data/lib/rubocop/cop/style/class_check.rb +6 -9
  113. data/lib/rubocop/cop/style/class_equality_comparison.rb +64 -0
  114. data/lib/rubocop/cop/style/class_methods_definitions.rb +42 -16
  115. data/lib/rubocop/cop/style/class_vars.rb +1 -2
  116. data/lib/rubocop/cop/style/combinable_loops.rb +13 -11
  117. data/lib/rubocop/cop/style/comment_annotation.rb +6 -0
  118. data/lib/rubocop/cop/style/commented_keyword.rb +7 -8
  119. data/lib/rubocop/cop/style/conditional_assignment.rb +49 -60
  120. data/lib/rubocop/cop/style/date_time.rb +12 -1
  121. data/lib/rubocop/cop/style/dir.rb +1 -0
  122. data/lib/rubocop/cop/style/double_negation.rb +1 -0
  123. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  124. data/lib/rubocop/cop/style/eval_with_location.rb +1 -3
  125. data/lib/rubocop/cop/style/even_odd.rb +1 -0
  126. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  127. data/lib/rubocop/cop/style/explicit_block_argument.rb +7 -3
  128. data/lib/rubocop/cop/style/float_division.rb +2 -0
  129. data/lib/rubocop/cop/style/for.rb +0 -4
  130. data/lib/rubocop/cop/style/format_string.rb +1 -4
  131. data/lib/rubocop/cop/style/format_string_token.rb +1 -1
  132. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +24 -5
  133. data/lib/rubocop/cop/style/hash_transform_keys.rb +5 -11
  134. data/lib/rubocop/cop/style/hash_transform_values.rb +5 -11
  135. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -4
  136. data/lib/rubocop/cop/style/implicit_runtime_error.rb +1 -0
  137. data/lib/rubocop/cop/style/keyword_parameters_order.rb +1 -6
  138. data/lib/rubocop/cop/style/lambda_call.rb +3 -1
  139. data/lib/rubocop/cop/style/method_def_parentheses.rb +0 -4
  140. data/lib/rubocop/cop/style/mixin_usage.rb +8 -27
  141. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
  142. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +14 -1
  143. data/lib/rubocop/cop/style/multiline_when_then.rb +1 -0
  144. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -0
  145. data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
  146. data/lib/rubocop/cop/style/non_nil_check.rb +2 -0
  147. data/lib/rubocop/cop/style/not.rb +1 -0
  148. data/lib/rubocop/cop/style/numeric_predicate.rb +1 -3
  149. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -1
  150. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +12 -1
  151. data/lib/rubocop/cop/style/preferred_hash_methods.rb +2 -0
  152. data/lib/rubocop/cop/style/raise_args.rb +2 -3
  153. data/lib/rubocop/cop/style/random_with_offset.rb +4 -3
  154. data/lib/rubocop/cop/style/redundant_assignment.rb +1 -9
  155. data/lib/rubocop/cop/style/redundant_begin.rb +36 -8
  156. data/lib/rubocop/cop/style/redundant_condition.rb +5 -1
  157. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -5
  158. data/lib/rubocop/cop/style/redundant_exception.rb +1 -3
  159. data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -0
  160. data/lib/rubocop/cop/style/redundant_freeze.rb +2 -1
  161. data/lib/rubocop/cop/style/redundant_interpolation.rb +6 -1
  162. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -6
  163. data/lib/rubocop/cop/style/redundant_percent_q.rb +9 -11
  164. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +39 -24
  165. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -15
  166. data/lib/rubocop/cop/style/redundant_return.rb +17 -17
  167. data/lib/rubocop/cop/style/redundant_self.rb +7 -9
  168. data/lib/rubocop/cop/style/redundant_self_assignment.rb +2 -2
  169. data/lib/rubocop/cop/style/redundant_sort.rb +12 -29
  170. data/lib/rubocop/cop/style/redundant_sort_by.rb +5 -9
  171. data/lib/rubocop/cop/style/rescue_standard_error.rb +20 -16
  172. data/lib/rubocop/cop/style/safe_navigation.rb +5 -0
  173. data/lib/rubocop/cop/style/sample.rb +2 -1
  174. data/lib/rubocop/cop/style/send.rb +2 -3
  175. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  176. data/lib/rubocop/cop/style/single_argument_dig.rb +1 -0
  177. data/lib/rubocop/cop/style/slicing_with_range.rb +2 -1
  178. data/lib/rubocop/cop/style/stderr_puts.rb +1 -0
  179. data/lib/rubocop/cop/style/string_concatenation.rb +17 -3
  180. data/lib/rubocop/cop/style/strip.rb +1 -0
  181. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -3
  182. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +4 -3
  183. data/lib/rubocop/cop/style/unpack_first.rb +1 -0
  184. data/lib/rubocop/cop/style/zero_length_predicate.rb +1 -5
  185. data/lib/rubocop/cop/util.rb +0 -1
  186. data/lib/rubocop/cop/variable_force/branch.rb +0 -4
  187. data/lib/rubocop/core_ext/string.rb +1 -1
  188. data/lib/rubocop/directive_comment.rb +32 -0
  189. data/lib/rubocop/ext/regexp_node.rb +23 -7
  190. data/lib/rubocop/formatter/disabled_config_formatter.rb +12 -5
  191. data/lib/rubocop/options.rb +37 -17
  192. data/lib/rubocop/result_cache.rb +38 -15
  193. data/lib/rubocop/rspec/cop_helper.rb +1 -1
  194. data/lib/rubocop/rspec/expect_offense.rb +5 -5
  195. data/lib/rubocop/runner.rb +37 -18
  196. data/lib/rubocop/target_finder.rb +27 -26
  197. data/lib/rubocop/target_ruby.rb +1 -1
  198. data/lib/rubocop/version.rb +6 -1
  199. metadata +19 -18
  200. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +0 -43
  201. data/lib/rubocop/cop/tokens_util.rb +0 -84
@@ -49,6 +49,10 @@ module RuboCop
49
49
  # foo && foo < bar
50
50
  # foo < bar if foo
51
51
  #
52
+ # # When checking `foo&.empty?` in a conditional, `foo` being `nil` will actually
53
+ # # do the opposite of what the author intends.
54
+ # foo && foo.empty?
55
+ #
52
56
  # # This could start returning `nil` as well as the return of the method
53
57
  # foo.nil? || foo.bar
54
58
  # !foo || foo.bar
@@ -104,6 +108,7 @@ module RuboCop
104
108
  # chain greater than 2
105
109
  return if chain_size(method_chain, method) > 1
106
110
  return if unsafe_method_used?(method_chain, method)
111
+ return if method_chain.method?(:empty?)
107
112
 
108
113
  add_offense(node) do |corrector|
109
114
  autocorrect(corrector, node)
@@ -31,9 +31,10 @@ module RuboCop
31
31
  extend AutoCorrector
32
32
 
33
33
  MSG = 'Use `%<correct>s` instead of `%<incorrect>s`.'
34
+ RESTRICT_ON_SEND = %i[first last [] at slice].freeze
34
35
 
35
36
  def_node_matcher :sample_candidate?, <<~PATTERN
36
- (send $(send _ :shuffle $...) ${:first :last :[] :at :slice} $...)
37
+ (send $(send _ :shuffle $...) ${:#{RESTRICT_ON_SEND.join(' :')}} $...)
37
38
  PATTERN
38
39
 
39
40
  def on_send(node)
@@ -16,11 +16,10 @@ module RuboCop
16
16
  class Send < Base
17
17
  MSG = 'Prefer `Object#__send__` or `Object#public_send` to ' \
18
18
  '`send`.'
19
-
20
- def_node_matcher :sending?, '({send csend} _ :send ...)'
19
+ RESTRICT_ON_SEND = %i[send].freeze
21
20
 
22
21
  def on_send(node)
23
- return unless sending?(node) && node.arguments?
22
+ return unless node.arguments?
24
23
 
25
24
  add_offense(node.loc.selector)
26
25
  end
@@ -112,6 +112,8 @@ module RuboCop
112
112
  RAISE_MSG = 'Use `raise` instead of `fail` to ' \
113
113
  'rethrow exceptions.'
114
114
 
115
+ RESTRICT_ON_SEND = %i[raise fail].freeze
116
+
115
117
  def_node_matcher :kernel_call?, '(send (const {nil? cbase} :Kernel) %1 ...)'
116
118
  def_node_search :custom_fail_methods,
117
119
  '{(def :fail ...) (defs _ :fail ...)}'
@@ -27,6 +27,7 @@ module RuboCop
27
27
  extend AutoCorrector
28
28
 
29
29
  MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
30
+ RESTRICT_ON_SEND = %i[dig].freeze
30
31
 
31
32
  def_node_matcher :single_argument_dig?, <<~PATTERN
32
33
  (send _ :dig $!splat)
@@ -19,11 +19,12 @@ module RuboCop
19
19
  minimum_target_ruby_version 2.6
20
20
 
21
21
  MSG = 'Prefer ary[n..] over ary[n..-1].'
22
+ RESTRICT_ON_SEND = %i[[]].freeze
22
23
 
23
24
  def_node_matcher :range_till_minus_one?, '(irange !nil? (int -1))'
24
25
 
25
26
  def on_send(node)
26
- return unless node.method?(:[]) && node.arguments.count == 1
27
+ return unless node.arguments.count == 1
27
28
  return unless range_till_minus_one?(node.arguments.first)
28
29
 
29
30
  add_offense(node.first_argument) do |corrector|
@@ -20,6 +20,7 @@ module RuboCop
20
20
 
21
21
  MSG =
22
22
  'Use `warn` instead of `%<bad>s` to allow such output to be disabled.'
23
+ RESTRICT_ON_SEND = %i[puts].freeze
23
24
 
24
25
  def_node_matcher :stderr_puts?, <<~PATTERN
25
26
  (send
@@ -6,6 +6,11 @@ module RuboCop
6
6
  # This cop checks for places where string concatenation
7
7
  # can be replaced with string interpolation.
8
8
  #
9
+ # The cop can autocorrect simple cases but will skip autocorrecting
10
+ # more complex cases where the resulting code would be harder to read.
11
+ # In those cases, it might be useful to extract statements to local
12
+ # variables or methods which you can then interpolate in a string.
13
+ #
9
14
  # @example
10
15
  # # bad
11
16
  # email_with_name = user.name + ' <' + user.email + '>'
@@ -19,6 +24,7 @@ module RuboCop
19
24
  extend AutoCorrector
20
25
 
21
26
  MSG = 'Prefer string interpolation to string concatenation.'
27
+ RESTRICT_ON_SEND = %i[+].freeze
22
28
 
23
29
  def_node_matcher :string_concatenation?, <<~PATTERN
24
30
  {
@@ -28,7 +34,6 @@ module RuboCop
28
34
  PATTERN
29
35
 
30
36
  def on_send(node)
31
- return unless node.method?(:+)
32
37
  return unless string_concatenation?(node)
33
38
 
34
39
  topmost_plus_node = find_topmost_plus_node(node)
@@ -37,7 +42,9 @@ module RuboCop
37
42
  collect_parts(topmost_plus_node, parts)
38
43
 
39
44
  add_offense(topmost_plus_node) do |corrector|
40
- corrector.replace(topmost_plus_node, replacement(parts))
45
+ if parts.none? { |part| uncorrectable?(part) }
46
+ corrector.replace(topmost_plus_node, replacement(parts))
47
+ end
41
48
  end
42
49
  end
43
50
 
@@ -66,6 +73,13 @@ module RuboCop
66
73
  node.send_type? && node.method?(:+)
67
74
  end
68
75
 
76
+ def uncorrectable?(part)
77
+ part.multiline? ||
78
+ part.dstr_type? ||
79
+ (part.str_type? && part.heredoc?) ||
80
+ part.each_descendant(:block).any?
81
+ end
82
+
69
83
  def replacement(parts)
70
84
  interpolated_parts =
71
85
  parts.map do |part|
@@ -73,7 +87,7 @@ module RuboCop
73
87
  if single_quoted?(part)
74
88
  part.value.gsub('\\') { '\\\\' }
75
89
  else
76
- escape_string(part.value)
90
+ part.value.inspect[1..-2]
77
91
  end
78
92
  else
79
93
  "\#{#{part.source}}"
@@ -18,6 +18,7 @@ module RuboCop
18
18
  extend AutoCorrector
19
19
 
20
20
  MSG = 'Use `strip` instead of `%<methods>s`.'
21
+ RESTRICT_ON_SEND = %i[lstrip rstrip].freeze
21
22
 
22
23
  def_node_matcher :lstrip_rstrip, <<~PATTERN
23
24
  {(send $(send _ $:rstrip) $:lstrip)
@@ -192,7 +192,7 @@ module RuboCop
192
192
  end
193
193
 
194
194
  def_node_matcher :method_name, <<~PATTERN
195
- {($:defined? (send nil? _) ...)
195
+ {($:defined? _ ...)
196
196
  (send {_ nil?} $_ _ ...)}
197
197
  PATTERN
198
198
 
@@ -211,8 +211,7 @@ module RuboCop
211
211
  end
212
212
 
213
213
  def whitespace_after?(node)
214
- index = index_of_last_token(node)
215
- last_token = processed_source.tokens[index]
214
+ last_token = processed_source.last_token_of(node)
216
215
  last_token.space_after?
217
216
  end
218
217
  end
@@ -76,12 +76,13 @@ module RuboCop
76
76
  end
77
77
 
78
78
  def argument_tokens(node)
79
- pipes = tokens(node).select { |token| token.type == :tPIPE }
79
+ tokens = processed_source.tokens_within(node)
80
+ pipes = tokens.select { |token| token.type == :tPIPE }
80
81
  begin_pos, end_pos = pipes.map do |pipe|
81
- tokens(node).index(pipe)
82
+ tokens.index(pipe)
82
83
  end
83
84
 
84
- tokens(node)[begin_pos + 1..end_pos - 1]
85
+ tokens[begin_pos + 1..end_pos - 1]
85
86
  end
86
87
  end
87
88
  end
@@ -22,6 +22,7 @@ module RuboCop
22
22
 
23
23
  MSG = 'Use `%<receiver>s.unpack1(%<format>s)` instead of '\
24
24
  '`%<receiver>s.unpack(%<format>s)%<method>s`.'
25
+ RESTRICT_ON_SEND = %i[first [] slice at].freeze
25
26
 
26
27
  def_node_matcher :unpack_and_first_element?, <<~PATTERN
27
28
  {
@@ -32,7 +32,7 @@ module RuboCop
32
32
  NONZERO_MSG = 'Use `!empty?` instead of ' \
33
33
  '`%<lhs>s %<opr>s %<rhs>s`.'
34
34
 
35
- LENGTH_METHODS = %i[size length].freeze
35
+ RESTRICT_ON_SEND = %i[size length].freeze
36
36
 
37
37
  def on_send(node)
38
38
  check_zero_length_predicate(node)
@@ -42,8 +42,6 @@ module RuboCop
42
42
  private
43
43
 
44
44
  def check_zero_length_predicate(node)
45
- return unless LENGTH_METHODS.include?(node.method_name)
46
-
47
45
  zero_length_predicate = zero_length_predicate(node.parent)
48
46
  return unless zero_length_predicate
49
47
 
@@ -59,8 +57,6 @@ module RuboCop
59
57
  end
60
58
 
61
59
  def check_nonzero_length_predicate(node)
62
- return unless LENGTH_METHODS.include?(node.method_name)
63
-
64
60
  nonzero_length_predicate = nonzero_length_predicate(node.parent)
65
61
  return unless nonzero_length_predicate
66
62
 
@@ -5,7 +5,6 @@ module RuboCop
5
5
  # This module contains a collection of useful utility methods.
6
6
  module Util
7
7
  include PathUtil
8
- include TokensUtil
9
8
 
10
9
  # Match literal regex characters, not including anchors, character
11
10
  # classes, alternatives, groups, repetitions, references, etc
@@ -20,8 +20,6 @@ module RuboCop
20
20
  nil
21
21
  end
22
22
 
23
- # rubocop:disable Metrics/BlockLength
24
-
25
23
  # Abstract base class for branch classes.
26
24
  # A branch represents a conditional branch in a scope.
27
25
  #
@@ -42,8 +40,6 @@ module RuboCop
42
40
  # do_something # no branch
43
41
  # end
44
42
  Base = Struct.new(:child_node, :scope) do
45
- # rubocop:enable Metrics/BlockLength
46
-
47
43
  def self.classes
48
44
  @classes ||= []
49
45
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Extensions to the core String class
4
4
  class String
5
- unless method_defined? :blank?
5
+ unless method_defined?(:blank?) && ' '.blank?
6
6
  # Checks whether a string is blank. A string is considered blank if it
7
7
  # is either empty or contains only whitespace characters.
8
8
  #
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ # This class wraps the `Parser::Source::Comment` object that represents a
5
+ # special `rubocop:disable` and `rubocop:enable` comment and exposes what
6
+ # cops it contains.
7
+ class DirectiveComment
8
+ attr_reader :comment
9
+
10
+ def initialize(comment)
11
+ @comment = comment
12
+ end
13
+
14
+ # Return all the cops specified in the directive
15
+ def cops
16
+ match = comment.text.match(CommentConfig::COMMENT_DIRECTIVE_REGEXP)
17
+ return unless match
18
+
19
+ cops_string = match.captures[1]
20
+ cops_string.split(/,\s*/).uniq.sort
21
+ end
22
+
23
+ # Checks if this directive contains all the given cop names
24
+ def match?(cop_names)
25
+ cops == cop_names.uniq.sort
26
+ end
27
+
28
+ def range
29
+ comment.location.expression
30
+ end
31
+ end
32
+ end
@@ -17,14 +17,12 @@ module RuboCop
17
17
 
18
18
  # @return [Regexp::Expression::Root, nil]
19
19
  def parsed_tree
20
- return if interpolation?
21
-
22
- str = content
20
+ str = with_interpolations_blanked
23
21
  Ext::RegexpNode.parsed_cache[str] ||= begin
24
- Regexp::Parser.parse(str)
25
- rescue StandardError
26
- nil
27
- end
22
+ Regexp::Parser.parse(str, options: options)
23
+ rescue StandardError
24
+ nil
25
+ end
28
26
  end
29
27
 
30
28
  def each_capture(named: ANY)
@@ -40,6 +38,24 @@ module RuboCop
40
38
  self
41
39
  end
42
40
 
41
+ private
42
+
43
+ def with_interpolations_blanked
44
+ # Ignore the trailing regopt node
45
+ children[0...-1].map do |child|
46
+ source = child.source
47
+
48
+ # We don't want to consider the contents of interpolations as part of the pattern source,
49
+ # but need to preserve their width, to allow offsets to correctly line up with the
50
+ # original source: spaces have no effect, and preserve width.
51
+ if child.begin_type?
52
+ ' ' * source.length
53
+ else
54
+ source
55
+ end
56
+ end.join
57
+ end
58
+
43
59
  AST::RegexpNode.include self
44
60
  end
45
61
  end
@@ -32,7 +32,6 @@ module RuboCop
32
32
  @exclude_limit_option = @options[:exclude_limit]
33
33
  @exclude_limit = Integer(@exclude_limit_option ||
34
34
  RuboCop::Options::DEFAULT_MAXIMUM_EXCLUSION_ITEMS)
35
- @show_offense_counts = !@options[:no_offense_counts]
36
35
  end
37
36
 
38
37
  def file_finished(file, offenses)
@@ -56,6 +55,14 @@ module RuboCop
56
55
 
57
56
  private
58
57
 
58
+ def show_timestamp?
59
+ @options.fetch(:auto_gen_timestamp, true)
60
+ end
61
+
62
+ def show_offense_counts?
63
+ @options.fetch(:offense_counts, true)
64
+ end
65
+
59
66
  def command
60
67
  command = 'rubocop --auto-gen-config'
61
68
 
@@ -66,15 +73,15 @@ module RuboCop
66
73
  format(' --exclude-limit %<limit>d',
67
74
  limit: Integer(@exclude_limit_option))
68
75
  end
69
- command += ' --no-offense-counts' if @options[:no_offense_counts]
76
+ command += ' --no-offense-counts' unless show_offense_counts?
70
77
 
71
- command += ' --no-auto-gen-timestamp' if @options[:no_auto_gen_timestamp]
78
+ command += ' --no-auto-gen-timestamp' unless show_timestamp?
72
79
 
73
80
  command
74
81
  end
75
82
 
76
83
  def timestamp
77
- @options[:no_auto_gen_timestamp] ? '' : "on #{Time.now.utc} "
84
+ show_timestamp? ? "on #{Time.now.utc} " : ''
78
85
  end
79
86
 
80
87
  def output_offenses
@@ -112,7 +119,7 @@ module RuboCop
112
119
  end
113
120
 
114
121
  def output_cop_comments(output_buffer, cfg, cop_name, offense_count)
115
- output_buffer.puts "# Offense count: #{offense_count}" if @show_offense_counts
122
+ output_buffer.puts "# Offense count: #{offense_count}" if show_offense_counts?
116
123
 
117
124
  cop_class = Cop::Registry.global.find_by_cop_name(cop_name)
118
125
  output_buffer.puts '# Cop supports --auto-correct.' if cop_class&.support_autocorrect?
@@ -69,6 +69,7 @@ module RuboCop
69
69
 
70
70
  add_severity_option(opts)
71
71
  add_flags_with_optional_args(opts)
72
+ add_cache_options(opts)
72
73
  add_boolean_flags(opts)
73
74
  add_aliases(opts)
74
75
 
@@ -113,20 +114,19 @@ module RuboCop
113
114
  def add_auto_gen_options(opts)
114
115
  option(opts, '--auto-gen-config')
115
116
 
117
+ option(opts, '--regenerate-todo') do
118
+ @options.replace(ConfigRegeneration.new.options.merge(@options))
119
+ end
120
+
116
121
  option(opts, '--exclude-limit COUNT') do
117
122
  @validator.validate_exclude_limit_option
118
123
  end
119
124
 
120
125
  option(opts, '--disable-uncorrectable')
121
126
 
122
- option(opts, '--no-offense-counts') do
123
- @options[:no_offense_counts] = true
124
- end
125
-
126
- option(opts, '--auto-gen-only-exclude')
127
- option(opts, '--no-auto-gen-timestamp') do
128
- @options[:no_auto_gen_timestamp] = true
129
- end
127
+ option(opts, '--[no-]offense-counts')
128
+ option(opts, '--[no-]auto-gen-only-exclude')
129
+ option(opts, '--[no-]auto-gen-timestamp')
130
130
 
131
131
  option(opts, '--init')
132
132
  end
@@ -164,10 +164,16 @@ module RuboCop
164
164
  end
165
165
  end
166
166
 
167
+ def add_cache_options(opts)
168
+ option(opts, '-C', '--cache FLAG')
169
+ option(opts, '--cache-root DIR') do
170
+ @validator.validate_cache_enabled_for_cache_root
171
+ end
172
+ end
173
+
167
174
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
168
175
  def add_boolean_flags(opts)
169
176
  option(opts, '-F', '--fail-fast')
170
- option(opts, '-C', '--cache FLAG')
171
177
  option(opts, '-d', '--debug')
172
178
  option(opts, '-D', '--[no-]display-cop-names')
173
179
  option(opts, '-E', '--extra-details')
@@ -311,7 +317,7 @@ module RuboCop
311
317
 
312
318
  message = '--%<flag>s can only be used together with --auto-gen-config.'
313
319
 
314
- %i[exclude_limit no_offense_counts no_auto_gen_timestamp
320
+ %i[exclude_limit offense_counts auto_gen_timestamp
315
321
  auto_gen_only_exclude].each do |option|
316
322
  if @options.key?(option)
317
323
  raise OptionArgumentError,
@@ -392,6 +398,13 @@ module RuboCop
392
398
  # of option order.
393
399
  raise OptionParser::MissingArgument
394
400
  end
401
+
402
+ def validate_cache_enabled_for_cache_root
403
+ return unless @options[:cache] == 'false'
404
+
405
+ raise OptionArgumentError, '--cache-root can not be used with ' \
406
+ '--cache false'
407
+ end
395
408
  end
396
409
 
397
410
  # This module contains help texts for command line options.
@@ -409,17 +422,20 @@ module RuboCop
409
422
  config: 'Specify configuration file.',
410
423
  auto_gen_config: ['Generate a configuration file acting as a',
411
424
  'TODO list.'],
412
- no_offense_counts: ['Do not include offense counts in configuration',
413
- 'file generated by --auto-gen-config.'],
414
- no_auto_gen_timestamp:
415
- ['Do not include the date and time when',
416
- 'the --auto-gen-config was run in the file it',
417
- 'generates.'],
425
+ regenerate_todo: ['Regenerate the TODO configuration file using',
426
+ 'the last configuration. If there is no existing',
427
+ 'TODO file, acts like --auto-gen-config.'],
428
+ offense_counts: ['Include offense counts in configuration',
429
+ 'file generated by --auto-gen-config.',
430
+ 'Default is true.'],
431
+ auto_gen_timestamp:
432
+ ['Include the date and time when the --auto-gen-config',
433
+ 'was run in the file it generates. Default is true.'],
418
434
  auto_gen_only_exclude:
419
435
  ['Generate only Exclude parameters and not Max',
420
436
  'when running --auto-gen-config, except if the',
421
437
  'number of files with offenses is bigger than',
422
- 'exclude-limit.'],
438
+ 'exclude-limit. Default is false.'],
423
439
  exclude_limit: ['Used together with --auto-gen-config to',
424
440
  'set the limit for how many Exclude',
425
441
  "properties to generate. Default is #{MAX_EXCL}."],
@@ -464,6 +480,10 @@ module RuboCop
464
480
  cache: ["Use result caching (FLAG=true) or don't",
465
481
  '(FLAG=false), default determined by',
466
482
  'configuration parameter AllCops: UseCache.'],
483
+ cache_root: ['Set the cache root directory.',
484
+ 'Takes precedence over the configuration',
485
+ 'parameter AllCops: CacheRootDirectory and',
486
+ 'the $RUBOCOP_CACHE_ROOT environment variable.'],
467
487
  debug: 'Display debug info.',
468
488
  display_cop_names: ['Display cop names in offense messages.',
469
489
  'Default is true.'],