rubocop 0.71.0 → 0.75.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 (280) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -8
  3. data/bin/console +1 -0
  4. data/config/default.yml +84 -488
  5. data/lib/rubocop.rb +16 -54
  6. data/lib/rubocop/ast/builder.rb +2 -0
  7. data/lib/rubocop/ast/node.rb +9 -15
  8. data/lib/rubocop/ast/node/float_node.rb +12 -0
  9. data/lib/rubocop/ast/node/int_node.rb +12 -0
  10. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
  11. data/lib/rubocop/ast/node/mixin/numeric_node.rb +21 -0
  12. data/lib/rubocop/ast/node/resbody_node.rb +1 -6
  13. data/lib/rubocop/ast/traversal.rb +3 -3
  14. data/lib/rubocop/cached_data.rb +1 -1
  15. data/lib/rubocop/comment_config.rb +3 -2
  16. data/lib/rubocop/config.rb +21 -508
  17. data/lib/rubocop/config_loader.rb +22 -8
  18. data/lib/rubocop/config_loader_resolver.rb +2 -16
  19. data/lib/rubocop/config_obsoletion.rb +213 -0
  20. data/lib/rubocop/config_validator.rb +239 -0
  21. data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
  22. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  23. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  24. data/lib/rubocop/cop/commissioner.rb +3 -9
  25. data/lib/rubocop/cop/cop.rb +39 -12
  26. data/lib/rubocop/cop/corrector.rb +2 -3
  27. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  28. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
  29. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  30. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  31. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  32. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  33. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  34. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +55 -0
  35. data/lib/rubocop/cop/generator.rb +4 -4
  36. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  37. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  38. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
  39. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  40. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
  41. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  42. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
  43. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  44. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  45. data/lib/rubocop/cop/layout/class_structure.rb +2 -2
  46. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
  51. data/lib/rubocop/cop/layout/indent_assignment.rb +10 -1
  52. data/lib/rubocop/cop/layout/indent_first_argument.rb +7 -3
  53. data/lib/rubocop/cop/layout/indent_first_parameter.rb +7 -3
  54. data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -4
  55. data/lib/rubocop/cop/layout/indentation_consistency.rb +13 -12
  56. data/lib/rubocop/cop/layout/indentation_width.rb +28 -10
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
  58. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  59. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +18 -4
  60. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  61. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  62. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +1 -1
  63. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
  64. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  65. data/lib/rubocop/cop/layout/tab.rb +10 -22
  66. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  67. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
  68. data/lib/rubocop/cop/lint/debugger.rb +4 -6
  69. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  70. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  71. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  72. data/lib/rubocop/cop/lint/erb_new_arguments.rb +57 -1
  73. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
  74. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  75. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  76. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  77. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  78. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
  79. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  80. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  81. data/lib/rubocop/cop/lint/number_conversion.rb +4 -4
  82. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  83. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  84. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  85. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +5 -5
  86. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  87. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  88. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  89. data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
  90. data/lib/rubocop/cop/lint/unneeded_cop_disable_directive.rb +1 -1
  91. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -1
  92. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +7 -2
  93. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  94. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  95. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  96. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  97. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
  98. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
  99. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  100. data/lib/rubocop/cop/lint/void.rb +3 -22
  101. data/lib/rubocop/cop/message_annotator.rb +16 -7
  102. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  103. data/lib/rubocop/cop/metrics/line_length.rb +6 -0
  104. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  105. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  106. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  107. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  108. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  109. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  110. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
  111. data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
  112. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  113. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  114. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
  115. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  116. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  117. data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
  118. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  119. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  120. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  121. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  122. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  123. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +21 -20
  124. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  125. data/lib/rubocop/cop/offense.rb +18 -7
  126. data/lib/rubocop/cop/registry.rb +22 -1
  127. data/lib/rubocop/cop/security/eval.rb +1 -1
  128. data/lib/rubocop/cop/security/json_load.rb +1 -1
  129. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  130. data/lib/rubocop/cop/security/open.rb +1 -1
  131. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  132. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  133. data/lib/rubocop/cop/style/alias.rb +1 -1
  134. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  135. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +29 -10
  136. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  137. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  138. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  139. data/lib/rubocop/cop/style/conditional_assignment.rb +8 -9
  140. data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
  141. data/lib/rubocop/cop/style/date_time.rb +3 -3
  142. data/lib/rubocop/cop/style/dir.rb +1 -1
  143. data/lib/rubocop/cop/style/documentation_method.rb +45 -1
  144. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
  145. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  146. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  147. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  148. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  149. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -4
  150. data/lib/rubocop/cop/style/float_division.rb +94 -0
  151. data/lib/rubocop/cop/style/format_string.rb +13 -9
  152. data/lib/rubocop/cop/style/format_string_token.rb +18 -69
  153. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +18 -33
  154. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  155. data/lib/rubocop/cop/style/hash_syntax.rb +2 -2
  156. data/lib/rubocop/cop/style/if_inside_else.rb +42 -0
  157. data/lib/rubocop/cop/style/if_unless_modifier.rb +51 -15
  158. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  159. data/lib/rubocop/cop/style/inverse_methods.rb +2 -2
  160. data/lib/rubocop/cop/style/lambda.rb +0 -2
  161. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +32 -26
  162. data/lib/rubocop/cop/style/min_max.rb +1 -1
  163. data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
  164. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  165. data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
  166. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  167. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  168. data/lib/rubocop/cop/style/nested_modifier.rb +18 -2
  169. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
  170. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  171. data/lib/rubocop/cop/style/or_assignment.rb +8 -3
  172. data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
  173. data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
  175. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  176. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  177. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
  178. data/lib/rubocop/cop/style/redundant_return.rb +12 -0
  179. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  180. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  181. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  182. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  183. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  184. data/lib/rubocop/cop/style/safe_navigation.rb +19 -2
  185. data/lib/rubocop/cop/style/sample.rb +1 -1
  186. data/lib/rubocop/cop/style/semicolon.rb +11 -0
  187. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  188. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  189. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
  190. data/lib/rubocop/cop/style/strip.rb +1 -1
  191. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  192. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  193. data/lib/rubocop/cop/style/ternary_parentheses.rb +32 -3
  194. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  195. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  196. data/lib/rubocop/cop/style/unneeded_sort.rb +1 -1
  197. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  198. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  199. data/lib/rubocop/cop/style/word_array.rb +2 -2
  200. data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -6
  201. data/lib/rubocop/cop/team.rb +15 -14
  202. data/lib/rubocop/cop/utils/format_string.rb +128 -0
  203. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  204. data/lib/rubocop/core_ext/string.rb +0 -24
  205. data/lib/rubocop/error.rb +23 -0
  206. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
  207. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  208. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  209. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  210. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  211. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  212. data/lib/rubocop/formatter/tap_formatter.rb +17 -4
  213. data/lib/rubocop/magic_comment.rb +4 -0
  214. data/lib/rubocop/node_pattern.rb +2 -2
  215. data/lib/rubocop/options.rb +21 -17
  216. data/lib/rubocop/path_util.rb +1 -1
  217. data/lib/rubocop/processed_source.rb +6 -1
  218. data/lib/rubocop/rspec/cop_helper.rb +0 -1
  219. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  220. data/lib/rubocop/rspec/shared_contexts.rb +12 -17
  221. data/lib/rubocop/rspec/support.rb +0 -1
  222. data/lib/rubocop/runner.rb +14 -25
  223. data/lib/rubocop/target_finder.rb +6 -4
  224. data/lib/rubocop/version.rb +1 -1
  225. data/lib/rubocop/yaml_duplication_checker.rb +8 -2
  226. metadata +17 -92
  227. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
  228. data/lib/rubocop/cop/mixin/target_rails_version.rb +0 -16
  229. data/lib/rubocop/cop/rails/action_filter.rb +0 -117
  230. data/lib/rubocop/cop/rails/active_record_aliases.rb +0 -48
  231. data/lib/rubocop/cop/rails/active_record_override.rb +0 -82
  232. data/lib/rubocop/cop/rails/active_support_aliases.rb +0 -69
  233. data/lib/rubocop/cop/rails/application_job.rb +0 -40
  234. data/lib/rubocop/cop/rails/application_record.rb +0 -40
  235. data/lib/rubocop/cop/rails/assert_not.rb +0 -44
  236. data/lib/rubocop/cop/rails/belongs_to.rb +0 -102
  237. data/lib/rubocop/cop/rails/blank.rb +0 -164
  238. data/lib/rubocop/cop/rails/bulk_change_table.rb +0 -289
  239. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +0 -91
  240. data/lib/rubocop/cop/rails/date.rb +0 -161
  241. data/lib/rubocop/cop/rails/delegate.rb +0 -132
  242. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +0 -37
  243. data/lib/rubocop/cop/rails/dynamic_find_by.rb +0 -91
  244. data/lib/rubocop/cop/rails/enum_uniqueness.rb +0 -45
  245. data/lib/rubocop/cop/rails/environment_comparison.rb +0 -68
  246. data/lib/rubocop/cop/rails/exit.rb +0 -67
  247. data/lib/rubocop/cop/rails/file_path.rb +0 -108
  248. data/lib/rubocop/cop/rails/find_by.rb +0 -55
  249. data/lib/rubocop/cop/rails/find_each.rb +0 -51
  250. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +0 -25
  251. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +0 -106
  252. data/lib/rubocop/cop/rails/http_positional_arguments.rb +0 -117
  253. data/lib/rubocop/cop/rails/http_status.rb +0 -179
  254. data/lib/rubocop/cop/rails/ignored_skip_action_filter_option.rb +0 -94
  255. data/lib/rubocop/cop/rails/inverse_of.rb +0 -246
  256. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +0 -175
  257. data/lib/rubocop/cop/rails/link_to_blank.rb +0 -98
  258. data/lib/rubocop/cop/rails/not_null_column.rb +0 -67
  259. data/lib/rubocop/cop/rails/output.rb +0 -49
  260. data/lib/rubocop/cop/rails/output_safety.rb +0 -99
  261. data/lib/rubocop/cop/rails/pluralization_grammar.rb +0 -107
  262. data/lib/rubocop/cop/rails/presence.rb +0 -124
  263. data/lib/rubocop/cop/rails/present.rb +0 -153
  264. data/lib/rubocop/cop/rails/read_write_attribute.rb +0 -74
  265. data/lib/rubocop/cop/rails/redundant_allow_nil.rb +0 -111
  266. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +0 -136
  267. data/lib/rubocop/cop/rails/reflection_class_name.rb +0 -37
  268. data/lib/rubocop/cop/rails/refute_methods.rb +0 -76
  269. data/lib/rubocop/cop/rails/relative_date_constant.rb +0 -93
  270. data/lib/rubocop/cop/rails/request_referer.rb +0 -56
  271. data/lib/rubocop/cop/rails/reversible_migration.rb +0 -286
  272. data/lib/rubocop/cop/rails/safe_navigation.rb +0 -87
  273. data/lib/rubocop/cop/rails/save_bang.rb +0 -316
  274. data/lib/rubocop/cop/rails/scope_args.rb +0 -29
  275. data/lib/rubocop/cop/rails/skips_model_validations.rb +0 -87
  276. data/lib/rubocop/cop/rails/time_zone.rb +0 -238
  277. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +0 -105
  278. data/lib/rubocop/cop/rails/unknown_env.rb +0 -63
  279. data/lib/rubocop/cop/rails/validation.rb +0 -109
  280. data/lib/rubocop/rspec/shared_examples.rb +0 -59
@@ -3,11 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop is designed to help upgrade to after Ruby 3.0. It will add the
7
- # comment `# frozen_string_literal: true` to the top of files to
8
- # enable frozen string literals. Frozen string literals may be default
9
- # after Ruby 3.0. The comment will be added below a shebang and encoding
10
- # comment. The frozen string literal comment is only valid in Ruby 2.3+.
6
+ # This cop is designed to help you transition from mutable string literals
7
+ # to frozen string literals.
8
+ # It will add the comment `# frozen_string_literal: true` to the top of
9
+ # files to enable frozen string literals. Frozen string literals may be
10
+ # default in future Ruby. The comment will be added below a shebang and
11
+ # encoding comment. The frozen string literal comment is only valid in
12
+ # Ruby 2.3+.
11
13
  #
12
14
  # @example EnforcedStyle: always (default)
13
15
  # # The `always` style will always add the frozen string literal comment
@@ -121,42 +123,25 @@ module RuboCop
121
123
  end
122
124
 
123
125
  def insert_comment(corrector)
124
- last_special_comment = last_special_comment(processed_source)
125
- if last_special_comment.nil?
126
- corrector.insert_before(correction_range, preceding_comment)
127
- else
128
- corrector.insert_after(correction_range, proceeding_comment)
129
- end
130
- end
126
+ comment = last_special_comment(processed_source)
131
127
 
132
- def preceding_comment
133
- if processed_source.tokens[0].space_before?
134
- "#{FROZEN_STRING_LITERAL_ENABLED}\n"
128
+ if comment
129
+ corrector.insert_after(line_range(comment.line), following_comment)
135
130
  else
136
- "#{FROZEN_STRING_LITERAL_ENABLED}\n\n"
131
+ corrector.insert_before(line_range(1), preceding_comment)
137
132
  end
138
133
  end
139
134
 
140
- def proceeding_comment
141
- last_special_comment = last_special_comment(processed_source)
142
- following_line = processed_source.following_line(last_special_comment)
143
-
144
- if following_line&.empty?
145
- "\n#{FROZEN_STRING_LITERAL_ENABLED}"
146
- else
147
- "\n#{FROZEN_STRING_LITERAL_ENABLED}\n"
148
- end
135
+ def line_range(line)
136
+ processed_source.buffer.line_range(line)
149
137
  end
150
138
 
151
- def correction_range
152
- last_special_comment = last_special_comment(processed_source)
139
+ def preceding_comment
140
+ "#{FROZEN_STRING_LITERAL_ENABLED}\n"
141
+ end
153
142
 
154
- if last_special_comment.nil?
155
- range_with_surrounding_space(range: processed_source.tokens[0],
156
- side: :left)
157
- else
158
- last_special_comment.pos
159
- end
143
+ def following_comment
144
+ "\n#{FROZEN_STRING_LITERAL_ENABLED}"
160
145
  end
161
146
  end
162
147
  end
@@ -37,9 +37,10 @@ module RuboCop
37
37
  # ok
38
38
  class GuardClause < Cop
39
39
  include MinBodyLength
40
+ include StatementModifier
40
41
 
41
- MSG = 'Use a guard clause instead of wrapping the code inside a ' \
42
- 'conditional expression.'
42
+ MSG = 'Use a guard clause (`%<example>s`) instead of wrapping the ' \
43
+ 'code inside a conditional expression.'
43
44
 
44
45
  def on_def(node)
45
46
  body = node.body
@@ -55,9 +56,19 @@ module RuboCop
55
56
  alias on_defs on_def
56
57
 
57
58
  def on_if(node)
58
- return if accepted_form?(node) || !contains_guard_clause?(node)
59
+ return if accepted_form?(node)
59
60
 
60
- add_offense(node, location: :keyword)
61
+ guard_clause_in_if = node.if_branch&.guard_clause?
62
+ guard_clause_in_else = node.else_branch&.guard_clause?
63
+ guard_clause = guard_clause_in_if || guard_clause_in_else
64
+ return unless guard_clause
65
+
66
+ kw = if guard_clause_in_if
67
+ node.loc.keyword.source
68
+ else
69
+ opposite_keyword(node)
70
+ end
71
+ register_offense(node, guard_clause.source, kw)
61
72
  end
62
73
 
63
74
  private
@@ -65,7 +76,30 @@ module RuboCop
65
76
  def check_ending_if(node)
66
77
  return if accepted_form?(node, true) || !min_body_length?(node)
67
78
 
68
- add_offense(node, location: :keyword)
79
+ register_offense(node, 'return', opposite_keyword(node))
80
+ end
81
+
82
+ def opposite_keyword(node)
83
+ node.if? ? 'unless' : 'if'
84
+ end
85
+
86
+ def register_offense(node, scope_exiting_keyword, conditional_keyword)
87
+ condition, = node.node_parts
88
+ example = [scope_exiting_keyword,
89
+ conditional_keyword,
90
+ condition.source].join(' ')
91
+ if too_long_for_single_line?(node, example)
92
+ example = "#{conditional_keyword} #{condition.source}; " \
93
+ "#{scope_exiting_keyword}; end"
94
+ end
95
+ add_offense(node,
96
+ location: :keyword,
97
+ message: format(MSG, example: example))
98
+ end
99
+
100
+ def too_long_for_single_line?(node, example)
101
+ max = max_line_length
102
+ max && node.source_range.column + example.length > max
69
103
  end
70
104
 
71
105
  def accepted_form?(node, ending = false)
@@ -81,11 +115,6 @@ module RuboCop
81
115
  !node.else? || node.elsif?
82
116
  end
83
117
  end
84
-
85
- def contains_guard_clause?(node)
86
- node.if_branch&.guard_clause? ||
87
- node.else_branch&.guard_clause?
88
- end
89
118
  end
90
119
  end
91
120
  end
@@ -118,9 +118,9 @@ module RuboCop
118
118
 
119
119
  def alternative_style
120
120
  case style
121
- when :hash_rockets then
121
+ when :hash_rockets
122
122
  :ruby19
123
- when :ruby19, :ruby19_no_mixed_keys then
123
+ when :ruby19, :ruby19_no_mixed_keys
124
124
  :hash_rockets
125
125
  end
126
126
  end
@@ -27,6 +27,37 @@ module RuboCop
27
27
  # else
28
28
  # action_c
29
29
  # end
30
+ #
31
+ # @example AllowIfModifier: false (default)
32
+ # # bad
33
+ # if condition_a
34
+ # action_a
35
+ # else
36
+ # action_b if condition_b
37
+ # end
38
+ #
39
+ # # good
40
+ # if condition_a
41
+ # action_a
42
+ # elsif condition_b
43
+ # action_b
44
+ # end
45
+ #
46
+ # @example AllowIfModifier: true
47
+ # # good
48
+ # if condition_a
49
+ # action_a
50
+ # else
51
+ # action_b if condition_b
52
+ # end
53
+ #
54
+ # # good
55
+ # if condition_a
56
+ # action_a
57
+ # elsif condition_b
58
+ # action_b
59
+ # end
60
+ #
30
61
  class IfInsideElse < Cop
31
62
  MSG = 'Convert `if` nested inside `else` to `elsif`.'
32
63
 
@@ -36,9 +67,20 @@ module RuboCop
36
67
  else_branch = node.else_branch
37
68
 
38
69
  return unless else_branch&.if_type? && else_branch&.if?
70
+ return if allow_if_modifier_in_else_branch?(else_branch)
39
71
 
40
72
  add_offense(else_branch, location: :keyword)
41
73
  end
74
+
75
+ private
76
+
77
+ def allow_if_modifier_in_else_branch?(else_branch)
78
+ allow_if_modifier? && else_branch&.modifier_form?
79
+ end
80
+
81
+ def allow_if_modifier?
82
+ cop_config['AllowIfModifier']
83
+ end
42
84
  end
43
85
  end
44
86
  end
@@ -3,10 +3,13 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # Checks for if and unless statements that would fit on one line
7
- # if written as a modifier if/unless. The maximum line length is
8
- # configured in the `Metrics/LineLength` cop. The tab size is configured
9
- # in the `IndentationWidth` of the `Layout/Tab` cop.
6
+ # Checks for `if` and `unless` statements that would fit on one line if
7
+ # written as modifier `if`/`unless`. The cop also checks for modifier
8
+ # `if`/`unless` lines that exceed the maximum line length.
9
+ #
10
+ # The maximum line length is configured in the `Metrics/LineLength`
11
+ # cop. The tab size is configured in the `IndentationWidth` of the
12
+ # `Layout/Tab` cop.
10
13
  #
11
14
  # @example
12
15
  # # bad
@@ -18,35 +21,59 @@ module RuboCop
18
21
  # Foo.do_something
19
22
  # end
20
23
  #
24
+ # do_something_in_a_method_with_a_long_name(arg) if long_condition
25
+ #
21
26
  # # good
22
27
  # do_stuff(bar) if condition
23
28
  # Foo.do_something unless qux.empty?
29
+ #
30
+ # if long_condition
31
+ # do_something_in_a_method_with_a_long_name(arg)
32
+ # end
24
33
  class IfUnlessModifier < Cop
25
34
  include StatementModifier
26
35
 
27
- MSG = 'Favor modifier `%<keyword>s` usage when having a single-line ' \
28
- 'body. Another good alternative is the usage of control flow ' \
29
- '`&&`/`||`.'
36
+ MSG_USE_MODIFIER = 'Favor modifier `%<keyword>s` usage when having a ' \
37
+ 'single-line body. Another good alternative is ' \
38
+ 'the usage of control flow `&&`/`||`.'
39
+ MSG_USE_NORMAL =
40
+ 'Modifier form of `%<keyword>s` makes the line too long.'
30
41
 
31
42
  ASSIGNMENT_TYPES = %i[lvasgn casgn cvasgn
32
43
  gvasgn ivasgn masgn].freeze
33
44
 
34
45
  def on_if(node)
35
- return unless eligible_node?(node)
36
- return if named_capture_in_condition?(node)
37
-
38
- add_offense(node, location: :keyword,
39
- message: format(MSG, keyword: node.keyword))
46
+ msg = if eligible_node?(node)
47
+ MSG_USE_MODIFIER unless named_capture_in_condition?(node)
48
+ elsif node.modifier_form? && too_long_single_line?(node)
49
+ MSG_USE_NORMAL
50
+ end
51
+ return unless msg
52
+
53
+ add_offense(node,
54
+ location: :keyword,
55
+ message: format(msg, keyword: node.keyword))
40
56
  end
41
57
 
42
58
  def autocorrect(node)
43
- lambda do |corrector|
44
- corrector.replace(node.source_range, to_modifier_form(node))
45
- end
59
+ replacement = if node.modifier_form?
60
+ to_normal_form(node)
61
+ else
62
+ to_modifier_form(node)
63
+ end
64
+ ->(corrector) { corrector.replace(node.source_range, replacement) }
46
65
  end
47
66
 
48
67
  private
49
68
 
69
+ def too_long_single_line?(node)
70
+ return false unless max_line_length
71
+
72
+ range = node.source_range
73
+ range.first_line == range.last_line &&
74
+ range.last_column > max_line_length
75
+ end
76
+
50
77
  def named_capture_in_condition?(node)
51
78
  node.condition.match_with_lvasgn_type?
52
79
  end
@@ -79,6 +106,15 @@ module RuboCop
79
106
  parenthesize?(node) ? "(#{expression})" : expression
80
107
  end
81
108
 
109
+ def to_normal_form(node)
110
+ indentation = ' ' * node.source_range.column
111
+ <<~RUBY.chomp
112
+ #{node.keyword} #{node.condition.source}
113
+ #{indentation} #{node.body.source}
114
+ #{indentation}end
115
+ RUBY
116
+ end
117
+
82
118
  def first_line_comment(node)
83
119
  comment =
84
120
  processed_source.find_comment { |c| c.loc.line == node.loc.line }
@@ -119,7 +119,7 @@ module RuboCop
119
119
  end
120
120
 
121
121
  def configured_indent
122
- ' ' * config.for_cop('IndentationWidth')['Width']
122
+ ' ' * config.for_cop('Layout/IndentationWidth')['Width']
123
123
  end
124
124
  end
125
125
  end
@@ -47,7 +47,7 @@ module RuboCop
47
47
  [Style::Not]
48
48
  end
49
49
 
50
- def_node_matcher :inverse_candidate?, <<-PATTERN
50
+ def_node_matcher :inverse_candidate?, <<~PATTERN
51
51
  {
52
52
  (send $(send $(...) $_ $...) :!)
53
53
  (send (block $(send $(...) $_) $...) :!)
@@ -55,7 +55,7 @@ module RuboCop
55
55
  }
56
56
  PATTERN
57
57
 
58
- def_node_matcher :inverse_block?, <<-PATTERN
58
+ def_node_matcher :inverse_block?, <<~PATTERN
59
59
  (block $(send (...) $_) ... { $(send ... :!)
60
60
  $(send (...) {:!= :!~} ...)
61
61
  (begin ... $(send ... :!))
@@ -62,8 +62,6 @@ module RuboCop
62
62
  }
63
63
  }.freeze
64
64
 
65
- def_node_matcher :lambda_node?, '(block $(send nil? :lambda) ...)'
66
-
67
65
  def on_block(node)
68
66
  return unless node.lambda?
69
67
 
@@ -9,7 +9,7 @@ module RuboCop
9
9
  #
10
10
  # In the default style (require_parentheses), macro methods are ignored.
11
11
  # Additional methods can be added to the `IgnoredMethods`
12
- # or `IgnoredMethodPatterns` list. These options are
12
+ # or `IgnoredPatterns` list. These options are
13
13
  # valid only in the default style. Macros can be included by
14
14
  # either setting `IgnoreMacros` to false or adding specific macros to
15
15
  # the `IncludedMacros` list.
@@ -17,7 +17,7 @@ module RuboCop
17
17
  # Precedence of options is all follows:
18
18
  #
19
19
  # 1. `IgnoredMethods`
20
- # 2. `IgnoredMethodPatterns`
20
+ # 2. `IgnoredPatterns`
21
21
  # 3. `IncludedMacros`
22
22
  #
23
23
  # eg. If a method is listed in both
@@ -61,23 +61,9 @@ module RuboCop
61
61
  # # okay with `puts` listed in `IgnoredMethods`
62
62
  # puts 'test'
63
63
  #
64
- # # okay with `^assert` listed in `IgnoredMethodPatterns`
64
+ # # okay with `^assert` listed in `IgnoredPatterns`
65
65
  # assert_equal 'test', x
66
66
  #
67
- # # IgnoreMacros: true (default)
68
- #
69
- # # good
70
- # class Foo
71
- # bar :baz
72
- # end
73
- #
74
- # # IgnoreMacros: false
75
- #
76
- # # bad
77
- # class Foo
78
- # bar :baz
79
- # end
80
- #
81
67
  # @example EnforcedStyle: omit_parentheses
82
68
  #
83
69
  # # bad
@@ -92,7 +78,21 @@ module RuboCop
92
78
  # # good
93
79
  # foo.enforce strict: true
94
80
  #
95
- # # AllowParenthesesInMultilineCall: false (default)
81
+ # @example IgnoreMacros: true (default)
82
+ #
83
+ # # good
84
+ # class Foo
85
+ # bar :baz
86
+ # end
87
+ #
88
+ # @example IgnoreMacros: false
89
+ #
90
+ # # bad
91
+ # class Foo
92
+ # bar :baz
93
+ # end
94
+ #
95
+ # @example AllowParenthesesInMultilineCall: false (default)
96
96
  #
97
97
  # # bad
98
98
  # foo.enforce(
@@ -103,7 +103,7 @@ module RuboCop
103
103
  # foo.enforce \
104
104
  # strict: true
105
105
  #
106
- # # AllowParenthesesInMultilineCall: true
106
+ # @example AllowParenthesesInMultilineCall: true
107
107
  #
108
108
  # # good
109
109
  # foo.enforce(
@@ -114,7 +114,7 @@ module RuboCop
114
114
  # foo.enforce \
115
115
  # strict: true
116
116
  #
117
- # # AllowParenthesesInChaining: false (default)
117
+ # @example AllowParenthesesInChaining: false (default)
118
118
  #
119
119
  # # bad
120
120
  # foo().bar(1)
@@ -122,7 +122,7 @@ module RuboCop
122
122
  # # good
123
123
  # foo().bar 1
124
124
  #
125
- # # AllowParenthesesInChaining: true
125
+ # @example AllowParenthesesInChaining: true
126
126
  #
127
127
  # # good
128
128
  # foo().bar(1)
@@ -130,7 +130,7 @@ module RuboCop
130
130
  # # good
131
131
  # foo().bar 1
132
132
  #
133
- # # AllowParenthesesInCamelCaseMethod: false (default)
133
+ # @example AllowParenthesesInCamelCaseMethod: false (default)
134
134
  #
135
135
  # # bad
136
136
  # Array(1)
@@ -138,7 +138,7 @@ module RuboCop
138
138
  # # good
139
139
  # Array 1
140
140
  #
141
- # # AllowParenthesesInCamelCaseMethod: true
141
+ # @example AllowParenthesesInCamelCaseMethod: true
142
142
  #
143
143
  # # good
144
144
  # Array(1)
@@ -148,7 +148,7 @@ module RuboCop
148
148
  class MethodCallWithArgsParentheses < Cop
149
149
  include ConfigurableEnforcedStyle
150
150
  include IgnoredMethods
151
- include IgnoredMethodPatterns
151
+ include IgnoredPattern
152
152
 
153
153
  TRAILING_WHITESPACE_REGEX = /\s+\Z/.freeze
154
154
 
@@ -186,7 +186,7 @@ module RuboCop
186
186
 
187
187
  def add_offense_for_require_parentheses(node)
188
188
  return if ignored_method?(node.method_name)
189
- return if ignored_method_pattern?(node.method_name)
189
+ return if matches_ignored_pattern?(node.method_name)
190
190
  return if eligible_for_parentheses_omission?(node)
191
191
  return unless node.arguments? && !node.parenthesized?
192
192
 
@@ -348,7 +348,8 @@ module RuboCop
348
348
  end
349
349
 
350
350
  def ambigious_literal?(node)
351
- splat?(node) || ternary_if?(node) || regexp_slash_literal?(node)
351
+ splat?(node) || ternary_if?(node) || regexp_slash_literal?(node) ||
352
+ unary_literal?(node)
352
353
  end
353
354
 
354
355
  def splat?(node)
@@ -371,6 +372,11 @@ module RuboCop
371
372
  node.regexp_type? && node.loc.begin.source == '/'
372
373
  end
373
374
 
375
+ def unary_literal?(node)
376
+ node.numeric_type? && node.sign? ||
377
+ node.parent&.send_type? && node.parent&.unary_operation?
378
+ end
379
+
374
380
  def assigned_before?(node, target)
375
381
  node.assignment? &&
376
382
  node.loc.operator.begin < target.loc.begin