rubocop 0.75.1 → 0.80.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/LICENSE.txt +1 -1
  3. data/README.md +4 -4
  4. data/config/default.yml +374 -335
  5. data/lib/rubocop.rb +53 -32
  6. data/lib/rubocop/ast/builder.rb +43 -41
  7. data/lib/rubocop/ast/node.rb +5 -13
  8. data/lib/rubocop/ast/node/block_node.rb +2 -0
  9. data/lib/rubocop/ast/node/def_node.rb +11 -0
  10. data/lib/rubocop/ast/node/forward_args_node.rb +18 -0
  11. data/lib/rubocop/ast/node/regexp_node.rb +2 -4
  12. data/lib/rubocop/ast/node/return_node.rb +24 -0
  13. data/lib/rubocop/ast/traversal.rb +20 -3
  14. data/lib/rubocop/cli.rb +11 -227
  15. data/lib/rubocop/cli/command.rb +21 -0
  16. data/lib/rubocop/cli/command/auto_genenerate_config.rb +105 -0
  17. data/lib/rubocop/cli/command/base.rb +33 -0
  18. data/lib/rubocop/cli/command/execute_runner.rb +76 -0
  19. data/lib/rubocop/cli/command/init_dotfile.rb +45 -0
  20. data/lib/rubocop/cli/command/show_cops.rb +80 -0
  21. data/lib/rubocop/cli/command/version.rb +17 -0
  22. data/lib/rubocop/cli/environment.rb +21 -0
  23. data/lib/rubocop/comment_config.rb +8 -3
  24. data/lib/rubocop/config.rb +8 -1
  25. data/lib/rubocop/config_loader.rb +20 -20
  26. data/lib/rubocop/config_loader_resolver.rb +2 -1
  27. data/lib/rubocop/config_obsoletion.rb +73 -10
  28. data/lib/rubocop/config_validator.rb +77 -110
  29. data/lib/rubocop/cop/autocorrect_logic.rb +7 -4
  30. data/lib/rubocop/cop/bundler/gem_comment.rb +4 -4
  31. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +2 -2
  32. data/lib/rubocop/cop/commissioner.rb +15 -7
  33. data/lib/rubocop/cop/cop.rb +31 -6
  34. data/lib/rubocop/cop/corrector.rb +8 -7
  35. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -2
  36. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  37. data/lib/rubocop/cop/generator.rb +3 -4
  38. data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
  39. data/lib/rubocop/cop/internal_affairs.rb +1 -0
  40. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +59 -0
  41. data/lib/rubocop/cop/layout/{align_arguments.rb → argument_alignment.rb} +1 -1
  42. data/lib/rubocop/cop/layout/{align_array.rb → array_alignment.rb} +1 -1
  43. data/lib/rubocop/cop/layout/{indent_assignment.rb → assignment_indentation.rb} +1 -1
  44. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  45. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  46. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -1
  47. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  48. data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
  49. data/lib/rubocop/cop/layout/{indent_first_argument.rb → first_argument_indentation.rb} +14 -12
  50. data/lib/rubocop/cop/layout/{indent_first_array_element.rb → first_array_element_indentation.rb} +4 -4
  51. data/lib/rubocop/cop/layout/{indent_first_hash_element.rb → first_hash_element_indentation.rb} +4 -4
  52. data/lib/rubocop/cop/layout/{indent_first_parameter.rb → first_parameter_indentation.rb} +3 -3
  53. data/lib/rubocop/cop/layout/{align_hash.rb → hash_alignment.rb} +16 -8
  54. data/lib/rubocop/cop/layout/{indent_heredoc.rb → heredoc_indentation.rb} +5 -5
  55. data/lib/rubocop/cop/layout/leading_comment_space.rb +33 -2
  56. data/lib/rubocop/cop/layout/{leading_blank_lines.rb → leading_empty_lines.rb} +1 -1
  57. data/lib/rubocop/cop/{metrics → layout}/line_length.rb +68 -112
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  59. data/lib/rubocop/cop/layout/multiline_block_layout.rb +14 -5
  60. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +0 -4
  61. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  62. data/lib/rubocop/cop/layout/{align_parameters.rb → parameter_alignment.rb} +1 -1
  63. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +2 -0
  64. data/lib/rubocop/cop/layout/space_around_keyword.rb +12 -0
  65. data/lib/rubocop/cop/layout/space_around_operators.rb +50 -7
  66. data/lib/rubocop/cop/layout/space_before_block_braces.rb +17 -0
  67. data/lib/rubocop/cop/layout/space_before_first_arg.rb +8 -0
  68. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  69. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +7 -4
  70. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -9
  71. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  72. data/lib/rubocop/cop/layout/{trailing_blank_lines.rb → trailing_empty_lines.rb} +1 -1
  73. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  74. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  75. data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +1 -1
  76. data/lib/rubocop/cop/lint/{duplicated_key.rb → duplicate_hash_key.rb} +1 -1
  77. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  78. data/lib/rubocop/cop/lint/erb_new_arguments.rb +9 -8
  79. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  80. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  81. data/lib/rubocop/cop/lint/{multiple_compare.rb → multiple_comparison.rb} +1 -1
  82. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +89 -0
  83. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +26 -26
  84. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +18 -15
  85. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +1 -1
  86. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +6 -6
  87. data/lib/rubocop/cop/lint/{string_conversion_in_interpolation.rb → redundant_string_coercion.rb} +1 -1
  88. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -2
  89. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
  90. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -6
  91. data/lib/rubocop/cop/lint/{handle_exceptions.rb → suppressed_exception.rb} +1 -1
  92. data/lib/rubocop/cop/lint/useless_access_modifier.rb +57 -23
  93. data/lib/rubocop/cop/lint/useless_setter_call.rb +5 -1
  94. data/lib/rubocop/cop/lint/void.rb +4 -4
  95. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  96. data/lib/rubocop/cop/metrics/method_length.rb +1 -1
  97. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  98. data/lib/rubocop/cop/migration/department_name.rb +30 -2
  99. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  100. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +4 -0
  101. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +7 -7
  102. data/lib/rubocop/cop/mixin/{hash_alignment.rb → hash_alignment_styles.rb} +1 -1
  103. data/lib/rubocop/cop/mixin/hash_transform_method.rb +172 -0
  104. data/lib/rubocop/cop/mixin/line_length_help.rb +88 -0
  105. data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
  106. data/lib/rubocop/cop/mixin/nil_methods.rb +4 -4
  107. data/lib/rubocop/cop/mixin/rational_literal.rb +18 -0
  108. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -4
  109. data/lib/rubocop/cop/mixin/trailing_comma.rb +16 -18
  110. data/lib/rubocop/cop/naming/{uncommunicative_block_param_name.rb → block_parameter_name.rb} +3 -3
  111. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  112. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -5
  113. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
  114. data/lib/rubocop/cop/naming/{uncommunicative_method_param_name.rb → method_parameter_name.rb} +4 -4
  115. data/lib/rubocop/cop/naming/predicate_name.rb +6 -6
  116. data/lib/rubocop/cop/offense.rb +11 -0
  117. data/lib/rubocop/cop/registry.rb +8 -3
  118. data/lib/rubocop/cop/style/alias.rb +1 -1
  119. data/lib/rubocop/cop/style/array_join.rb +1 -1
  120. data/lib/rubocop/cop/style/attr.rb +10 -2
  121. data/lib/rubocop/cop/style/block_delimiters.rb +60 -1
  122. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  123. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
  124. data/lib/rubocop/cop/style/copyright.rb +11 -7
  125. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +2 -2
  126. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  127. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  128. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  129. data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
  130. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  131. data/lib/rubocop/cop/style/format_string.rb +10 -7
  132. data/lib/rubocop/cop/style/format_string_token.rb +2 -0
  133. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +99 -11
  134. data/lib/rubocop/cop/style/guard_clause.rb +3 -2
  135. data/lib/rubocop/cop/style/hash_each_methods.rb +87 -0
  136. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  137. data/lib/rubocop/cop/style/hash_transform_keys.rb +79 -0
  138. data/lib/rubocop/cop/style/hash_transform_values.rb +79 -0
  139. data/lib/rubocop/cop/style/if_unless_modifier.rb +45 -3
  140. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  141. data/lib/rubocop/cop/style/inverse_methods.rb +19 -13
  142. data/lib/rubocop/cop/style/ip_addresses.rb +4 -4
  143. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  144. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -205
  145. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +169 -0
  146. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +54 -0
  147. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  148. data/lib/rubocop/cop/style/mixin_grouping.rb +1 -1
  149. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  150. data/lib/rubocop/cop/style/multiline_when_then.rb +6 -2
  151. data/lib/rubocop/cop/style/nested_modifier.rb +4 -2
  152. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +5 -5
  153. data/lib/rubocop/cop/style/next.rb +5 -5
  154. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  155. data/lib/rubocop/cop/style/numeric_literals.rb +7 -3
  156. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -3
  157. data/lib/rubocop/cop/style/option_hash.rb +3 -3
  158. data/lib/rubocop/cop/style/or_assignment.rb +3 -2
  159. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +7 -7
  160. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  161. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  162. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  163. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -3
  164. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  165. data/lib/rubocop/cop/style/redundant_return.rb +27 -29
  166. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +5 -5
  167. data/lib/rubocop/cop/style/safe_navigation.rb +13 -10
  168. data/lib/rubocop/cop/style/semicolon.rb +2 -2
  169. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  170. data/lib/rubocop/cop/style/symbol_array.rb +2 -2
  171. data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
  172. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +0 -22
  173. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +7 -1
  174. data/lib/rubocop/cop/style/trivial_accessors.rb +5 -5
  175. data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
  176. data/lib/rubocop/cop/style/yoda_condition.rb +16 -1
  177. data/lib/rubocop/cop/team.rb +5 -0
  178. data/lib/rubocop/cop/util.rb +1 -1
  179. data/lib/rubocop/cop/utils/format_string.rb +10 -18
  180. data/lib/rubocop/cop/variable_force.rb +11 -6
  181. data/lib/rubocop/formatter/base_formatter.rb +2 -2
  182. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -3
  183. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  184. data/lib/rubocop/formatter/json_formatter.rb +6 -5
  185. data/lib/rubocop/formatter/junit_formatter.rb +63 -0
  186. data/lib/rubocop/formatter/tap_formatter.rb +1 -3
  187. data/lib/rubocop/node_pattern.rb +100 -12
  188. data/lib/rubocop/options.rb +17 -11
  189. data/lib/rubocop/processed_source.rb +1 -1
  190. data/lib/rubocop/rake_task.rb +1 -0
  191. data/lib/rubocop/result_cache.rb +24 -8
  192. data/lib/rubocop/rspec/shared_contexts.rb +5 -0
  193. data/lib/rubocop/runner.rb +50 -29
  194. data/lib/rubocop/target_finder.rb +12 -6
  195. data/lib/rubocop/target_ruby.rb +151 -0
  196. data/lib/rubocop/version.rb +1 -1
  197. metadata +69 -35
  198. data/lib/rubocop/cop/mixin/safe_mode.rb +0 -24
  199. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +0 -209
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for uses of "*" as a substitute for *join*.
6
+ # This cop checks for uses of "\*" as a substitute for *join*.
7
7
  #
8
8
  # Not all cases can reliably checked, due to Ruby's dynamic
9
9
  # types, so we consider only cases when the first argument is an
@@ -21,6 +21,10 @@ module RuboCop
21
21
 
22
22
  def on_send(node)
23
23
  return unless node.command?(:attr) && node.arguments?
24
+ # check only for method definitions in class/module body
25
+ return if node.parent &&
26
+ !node.parent.class_type? &&
27
+ !class_eval?(node.parent)
24
28
 
25
29
  add_offense(node, location: :selector)
26
30
  end
@@ -31,7 +35,7 @@ module RuboCop
31
35
  node_expr = node.source_range
32
36
  attr_expr = attr_name.source_range
33
37
 
34
- if setter && (setter.true_type? || setter.false_type?)
38
+ if setter&.boolean_type?
35
39
  remove = range_between(attr_expr.end_pos, node_expr.end_pos)
36
40
  end
37
41
 
@@ -50,12 +54,16 @@ module RuboCop
50
54
  def replacement_method(node)
51
55
  setter = node.last_argument
52
56
 
53
- if setter && (setter.true_type? || setter.false_type?)
57
+ if setter&.boolean_type?
54
58
  setter.true_type? ? 'attr_accessor' : 'attr_reader'
55
59
  else
56
60
  'attr_reader'
57
61
  end
58
62
  end
63
+
64
+ def_node_matcher :class_eval?, <<~PATTERN
65
+ (block (send _ {:class_eval :module_eval}) ...)
66
+ PATTERN
59
67
  end
60
68
  end
61
69
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # rubocop:disable Metrics/ClassLength
3
4
  module RuboCop
4
5
  module Cop
5
6
  module Style
@@ -106,12 +107,41 @@ module RuboCop
106
107
  # word.flip.flop
107
108
  # }
108
109
  #
110
+ # @example BracesRequiredMethods: ['sig']
111
+ #
112
+ # # Methods listed in the BracesRequiredMethods list, such as 'sig'
113
+ # # in this example, will require `{...}` braces. This option takes
114
+ # # precedence over all other configurations except IgnoredMethods.
115
+ #
116
+ # # bad
117
+ # sig do
118
+ # params(
119
+ # foo: string,
120
+ # ).void
121
+ # end
122
+ # def bar(foo)
123
+ # puts foo
124
+ # end
125
+ #
126
+ # # good
127
+ # sig {
128
+ # params(
129
+ # foo: string,
130
+ # ).void
131
+ # }
132
+ # def bar(foo)
133
+ # puts foo
134
+ # end
135
+ #
109
136
  class BlockDelimiters < Cop
110
137
  include ConfigurableEnforcedStyle
111
138
  include IgnoredMethods
112
139
 
113
140
  ALWAYS_BRACES_MESSAGE = 'Prefer `{...}` over `do...end` for blocks.'
114
141
 
142
+ BRACES_REQUIRED_MESSAGE = 'Brace delimiters `{...}` required for ' \
143
+ "'%<method_name>s' method."
144
+
115
145
  def on_send(node)
116
146
  return unless node.arguments?
117
147
  return if node.parenthesized?
@@ -175,7 +205,15 @@ module RuboCop
175
205
  end
176
206
  end
177
207
 
208
+ def braces_required_message(node)
209
+ format(BRACES_REQUIRED_MESSAGE, method_name: node.method_name.to_s)
210
+ end
211
+
178
212
  def message(node)
213
+ if braces_required_method?(node.method_name)
214
+ return braces_required_message(node)
215
+ end
216
+
179
217
  case style
180
218
  when :line_count_based then line_count_based_message(node)
181
219
  when :semantic then semantic_message(node)
@@ -238,7 +276,9 @@ module RuboCop
238
276
  # rubocop:enable Metrics/CyclomaticComplexity
239
277
 
240
278
  def proper_block_style?(node)
241
- return true if ignored_method?(node.method_name)
279
+ if special_method?(node.method_name)
280
+ return special_method_proper_block_style?(node)
281
+ end
242
282
 
243
283
  case style
244
284
  when :line_count_based then line_count_based_block_style?(node)
@@ -248,6 +288,24 @@ module RuboCop
248
288
  end
249
289
  end
250
290
 
291
+ def special_method?(method_name)
292
+ ignored_method?(method_name) || braces_required_method?(method_name)
293
+ end
294
+
295
+ def special_method_proper_block_style?(node)
296
+ method_name = node.method_name
297
+ return true if ignored_method?(method_name)
298
+ return node.braces? if braces_required_method?(method_name)
299
+ end
300
+
301
+ def braces_required_method?(method_name)
302
+ braces_required_methods.include?(method_name.to_s)
303
+ end
304
+
305
+ def braces_required_methods
306
+ cop_config.fetch('BracesRequiredMethods', [])
307
+ end
308
+
251
309
  def line_count_based_block_style?(node)
252
310
  node.multiline? ^ node.braces?
253
311
  end
@@ -329,3 +387,4 @@ module RuboCop
329
387
  end
330
388
  end
331
389
  end
390
+ # rubocop:enable Metrics/ClassLength
@@ -49,10 +49,10 @@ module RuboCop
49
49
  next unless annotation?(comment) &&
50
50
  !correct_annotation?(first_word, colon, space, note)
51
51
 
52
- length = concat_length(first_word, colon, space)
53
52
  add_offense(
54
53
  comment,
55
- location: annotation_range(comment, margin, length),
54
+ location: annotation_range(comment, margin,
55
+ first_word, colon, space),
56
56
  message: format(note ? MSG : MISSING_NOTE, keyword: first_word)
57
57
  )
58
58
  end
@@ -62,8 +62,7 @@ module RuboCop
62
62
  margin, first_word, colon, space, note = split_comment(comment)
63
63
  return if note.nil?
64
64
 
65
- length = concat_length(first_word, colon, space)
66
- range = annotation_range(comment, margin, length)
65
+ range = annotation_range(comment, margin, first_word, colon, space)
67
66
 
68
67
  ->(corrector) { corrector.replace(range, "#{first_word.upcase}: ") }
69
68
  end
@@ -79,8 +78,9 @@ module RuboCop
79
78
  !comment_line?(comment.loc.expression.source_line)
80
79
  end
81
80
 
82
- def annotation_range(comment, margin, length)
81
+ def annotation_range(comment, margin, first_word, colon, space)
83
82
  start = comment.loc.expression.begin_pos + margin.length
83
+ length = concat_length(first_word, colon, space)
84
84
  range_between(start, start + length)
85
85
  end
86
86
 
@@ -212,7 +212,7 @@ module RuboCop
212
212
  %i[casgn cvasgn gvasgn ivasgn lvasgn].freeze
213
213
  ASSIGNMENT_TYPES = VARIABLE_ASSIGNMENT_TYPES +
214
214
  %i[and_asgn or_asgn op_asgn masgn].freeze
215
- LINE_LENGTH = 'Metrics/LineLength'
215
+ LINE_LENGTH = 'Layout/LineLength'
216
216
  INDENTATION_WIDTH = 'Layout/IndentationWidth'
217
217
  ENABLED = 'Enabled'
218
218
  MAX = 'Max'
@@ -376,7 +376,7 @@ module RuboCop
376
376
  assignment_types_match?(*statements)
377
377
  end
378
378
 
379
- # If `Metrics/LineLength` is enabled, we do not want to introduce an
379
+ # If `Layout/LineLength` is enabled, we do not want to introduce an
380
380
  # offense by auto-correcting this cop. Find the max configured line
381
381
  # length. Find the longest line of condition. Remove the assignment
382
382
  # from lines that contain the offending assignment because after
@@ -33,13 +33,7 @@ module RuboCop
33
33
  end
34
34
 
35
35
  def autocorrect(token)
36
- raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
37
-
38
- regex = Regexp.new(notice)
39
- unless autocorrect_notice =~ regex
40
- raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
41
- "match Notice /#{notice}/"
42
- end
36
+ verify_autocorrect_notice!
43
37
 
44
38
  lambda do |corrector|
45
39
  range = token.nil? ? range_between(0, 0) : token.pos
@@ -57,6 +51,16 @@ module RuboCop
57
51
  cop_config['AutocorrectNotice']
58
52
  end
59
53
 
54
+ def verify_autocorrect_notice!
55
+ raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
56
+
57
+ regex = Regexp.new(notice)
58
+ return if autocorrect_notice =~ regex
59
+
60
+ raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
61
+ "match Notice /#{notice}/"
62
+ end
63
+
60
64
  def insert_notice_before(processed_source)
61
65
  token_index = 0
62
66
  token_index += 1 if shebang_token?(processed_source, token_index)
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Lint/UnneededCopDisableDirective
3
+ # rubocop:disable Lint/RedundantCopDisableDirective
4
4
  # rubocop:disable Style/DoubleCopDisableDirective
5
5
 
6
6
  module RuboCop
@@ -26,7 +26,7 @@ module RuboCop
26
26
  #
27
27
  class DoubleCopDisableDirective < Cop
28
28
  # rubocop:enable Style/For, Style/DoubleCopDisableDirective
29
- # rubocop:enable Lint/UnneededCopDisableDirective, Metrics/AbcSize
29
+ # rubocop:enable Lint/RedundantCopDisableDirective, Metrics/AbcSize
30
30
  MSG = 'More than one disable comment on one line.'
31
31
 
32
32
  def investigate(processed_source)
@@ -84,8 +84,8 @@ module RuboCop
84
84
 
85
85
  next unless conditions.size > 1
86
86
 
87
- range = range_between(conditions.first.loc.expression.begin_pos,
88
- conditions.last.loc.expression.end_pos)
87
+ range = range_between(conditions.first.source_range.begin_pos,
88
+ conditions.last.source_range.end_pos)
89
89
 
90
90
  corrector.replace(range, conditions.map(&:source).join(' || '))
91
91
  end
@@ -84,8 +84,8 @@ module RuboCop
84
84
  # to rewrite the arguments to wrap them in parenthesis.
85
85
  args = node.parent.arguments
86
86
 
87
- range_between(args[0].loc.expression.begin_pos - 1,
88
- args[-1].loc.expression.end_pos)
87
+ range_between(args[0].source_range.begin_pos - 1,
88
+ args[-1].source_range.end_pos)
89
89
  else
90
90
  node.source_range
91
91
  end
@@ -73,11 +73,11 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def corrected(node)
76
- has_parentheses = parentheses?(node.arguments)
77
-
78
- arguments = node.arguments? ? node.arguments.source : ''
79
- extra_space = node.arguments? && !has_parentheses ? ' ' : ''
80
- scope = node.receiver ? "#{node.receiver.source}." : ''
76
+ if node.arguments?
77
+ arguments = node.arguments.source
78
+ extra_space = ' ' unless parentheses?(node.arguments)
79
+ end
80
+ scope = node.receiver ? "#{node.receiver.source}." : ''
81
81
 
82
82
  signature = [scope, node.method_name, extra_space, arguments].join
83
83
 
@@ -85,7 +85,7 @@ module RuboCop
85
85
  # FIXME: It's a Style/ConditionalAssignment's false positive.
86
86
  # rubocop:disable Style/ConditionalAssignment
87
87
  def with_lineno?(node)
88
- if node.method_name == :eval
88
+ if node.method?(:eval)
89
89
  node.arguments.size == 4
90
90
  else
91
91
  node.arguments.size == 3
@@ -23,7 +23,7 @@ module RuboCop
23
23
  {(send $_ :% (int 2))
24
24
  (begin (send $_ :% (int 2)))}
25
25
  ${:== :!=}
26
- (int ${0 1 2}))
26
+ (int ${0 1}))
27
27
  PATTERN
28
28
 
29
29
  def on_send(node)
@@ -94,10 +94,12 @@ module RuboCop
94
94
  private
95
95
 
96
96
  def autocorrect_from_percent(corrector, node)
97
- args = if %i[array hash].include?(node.first_argument.type)
98
- node.first_argument.children.map(&:source).join(', ')
97
+ percent_rhs = node.first_argument
98
+ args = case percent_rhs.type
99
+ when :array, :hash
100
+ percent_rhs.children.map(&:source).join(', ')
99
101
  else
100
- node.first_argument.source
102
+ percent_rhs.source
101
103
  end
102
104
 
103
105
  corrected = "#{style}(#{node.receiver.source}, #{args})"
@@ -106,14 +108,15 @@ module RuboCop
106
108
  end
107
109
 
108
110
  def autocorrect_to_percent(corrector, node)
109
- format = node.first_argument.source
111
+ format_arg, *param_args = node.arguments
112
+ format = format_arg.source
110
113
 
111
- args = if node.arguments.size == 2
112
- arg = node.arguments.last
114
+ args = if param_args.one?
115
+ arg = param_args.last
113
116
 
114
117
  arg.hash_type? ? "{ #{arg.source} }" : arg.source
115
118
  else
116
- "[#{node.arguments[1..-1].map(&:source).join(', ')}]"
119
+ "[#{param_args.map(&:source).join(', ')}]"
117
120
  end
118
121
 
119
122
  corrector.replace(node.loc.expression, "#{format} % #{args}")
@@ -104,6 +104,8 @@ module RuboCop
104
104
  format_string = RuboCop::Cop::Utils::FormatString.new(contents.source)
105
105
 
106
106
  format_string.format_sequences.each do |seq|
107
+ next if seq.percent?
108
+
107
109
  detected_style = seq.style
108
110
  token = contents.begin.adjust(
109
111
  begin_pos: seq.begin_pos,
@@ -11,6 +11,9 @@ module RuboCop
11
11
  # encoding comment. The frozen string literal comment is only valid in
12
12
  # Ruby 2.3+.
13
13
  #
14
+ # Note that the cop will ignore files where the comment exists but is set
15
+ # to `false` instead of `true`.
16
+ #
14
17
  # @example EnforcedStyle: always (default)
15
18
  # # The `always` style will always add the frozen string literal comment
16
19
  # # to a file, regardless of the Ruby version or if `freeze` or `<<` are
@@ -27,6 +30,13 @@ module RuboCop
27
30
  # # ...
28
31
  # end
29
32
  #
33
+ # # good
34
+ # # frozen_string_literal: false
35
+ #
36
+ # module Bar
37
+ # # ...
38
+ # end
39
+ #
30
40
  # @example EnforcedStyle: never
31
41
  # # The `never` will enforce that the frozen string literal comment does
32
42
  # # not exist in a file.
@@ -41,29 +51,65 @@ module RuboCop
41
51
  # module Baz
42
52
  # # ...
43
53
  # end
54
+ #
55
+ # @example EnforcedStyle: always_true
56
+ # # The `always_true` style enforces that the frozen string literal
57
+ # # comment is set to `true`. This is a stricter option than `always`
58
+ # # and forces projects to use frozen string literals.
59
+ # # bad
60
+ # # frozen_string_literal: false
61
+ #
62
+ # module Baz
63
+ # # ...
64
+ # end
65
+ #
66
+ # # bad
67
+ # module Baz
68
+ # # ...
69
+ # end
70
+ #
71
+ # # good
72
+ # # frozen_string_literal: true
73
+ #
74
+ # module Bar
75
+ # # ...
76
+ # end
44
77
  class FrozenStringLiteralComment < Cop
45
78
  include ConfigurableEnforcedStyle
46
79
  include FrozenStringLiteral
47
80
  include RangeHelp
48
81
 
49
- MSG = 'Missing magic comment `# frozen_string_literal: true`.'
82
+ MSG_MISSING_TRUE = 'Missing magic comment `# frozen_string_literal: '\
83
+ 'true`.'
84
+ MSG_MISSING = 'Missing frozen string literal comment.'
50
85
  MSG_UNNECESSARY = 'Unnecessary frozen string literal comment.'
86
+ MSG_DISABLED = 'Frozen string literal comment must be set to `true`.'
51
87
  SHEBANG = '#!'
52
88
 
53
89
  def investigate(processed_source)
54
90
  return if processed_source.tokens.empty?
55
91
 
56
- if frozen_string_literal_comment_exists?
57
- check_for_no_comment(processed_source)
92
+ case style
93
+ when :never
94
+ ensure_no_comment(processed_source)
95
+ when :always_true
96
+ ensure_enabled_comment(processed_source)
58
97
  else
59
- check_for_comment(processed_source)
98
+ ensure_comment(processed_source)
60
99
  end
61
100
  end
62
101
 
63
102
  def autocorrect(node)
64
103
  lambda do |corrector|
65
- if style == :never
104
+ case style
105
+ when :never
66
106
  remove_comment(corrector, node)
107
+ when :always_true
108
+ if frozen_string_literal_specified?
109
+ enable_comment(corrector)
110
+ else
111
+ insert_comment(corrector)
112
+ end
67
113
  else
68
114
  insert_comment(corrector)
69
115
  end
@@ -72,12 +118,27 @@ module RuboCop
72
118
 
73
119
  private
74
120
 
75
- def check_for_no_comment(processed_source)
76
- unnecessary_comment_offense(processed_source) if style == :never
121
+ def ensure_no_comment(processed_source)
122
+ return unless frozen_string_literal_comment_exists?
123
+
124
+ unnecessary_comment_offense(processed_source)
125
+ end
126
+
127
+ def ensure_comment(processed_source)
128
+ return if frozen_string_literal_comment_exists?
129
+
130
+ missing_offense(processed_source)
77
131
  end
78
132
 
79
- def check_for_comment(processed_source)
80
- offense(processed_source) unless style == :never
133
+ def ensure_enabled_comment(processed_source)
134
+ if frozen_string_literal_specified?
135
+ return if frozen_string_literals_enabled?
136
+
137
+ # The comment exists, but is not enabled.
138
+ disabled_offense(processed_source)
139
+ else # The comment doesn't exist at all.
140
+ missing_true_offense(processed_source)
141
+ end
81
142
  end
82
143
 
83
144
  def last_special_comment(processed_source)
@@ -101,11 +162,22 @@ module RuboCop
101
162
  end
102
163
  end
103
164
 
104
- def offense(processed_source)
165
+ def missing_offense(processed_source)
105
166
  last_special_comment = last_special_comment(processed_source)
106
167
  range = source_range(processed_source.buffer, 0, 0)
107
168
 
108
- add_offense(last_special_comment, location: range)
169
+ add_offense(last_special_comment,
170
+ location: range,
171
+ message: MSG_MISSING)
172
+ end
173
+
174
+ def missing_true_offense(processed_source)
175
+ last_special_comment = last_special_comment(processed_source)
176
+ range = source_range(processed_source.buffer, 0, 0)
177
+
178
+ add_offense(last_special_comment,
179
+ location: range,
180
+ message: MSG_MISSING_TRUE)
109
181
  end
110
182
 
111
183
  def unnecessary_comment_offense(processed_source)
@@ -117,11 +189,27 @@ module RuboCop
117
189
  message: MSG_UNNECESSARY)
118
190
  end
119
191
 
192
+ def disabled_offense(processed_source)
193
+ frozen_string_literal_comment =
194
+ frozen_string_literal_comment(processed_source)
195
+
196
+ add_offense(frozen_string_literal_comment,
197
+ location: frozen_string_literal_comment.pos,
198
+ message: MSG_DISABLED)
199
+ end
200
+
120
201
  def remove_comment(corrector, node)
121
202
  corrector.remove(range_with_surrounding_space(range: node.pos,
122
203
  side: :right))
123
204
  end
124
205
 
206
+ def enable_comment(corrector)
207
+ comment = frozen_string_literal_comment(processed_source)
208
+
209
+ corrector.replace(line_range(comment.line),
210
+ FROZEN_STRING_LITERAL_ENABLED)
211
+ end
212
+
125
213
  def insert_comment(corrector)
126
214
  comment = last_special_comment(processed_source)
127
215