rubocop 0.52.1 → 0.53.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 (292) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +118 -46
  5. data/config/disabled.yml +8 -8
  6. data/config/enabled.yml +84 -28
  7. data/lib/rubocop.rb +28 -8
  8. data/lib/rubocop/ast/builder.rb +35 -37
  9. data/lib/rubocop/ast/node.rb +16 -1
  10. data/lib/rubocop/ast/node/and_node.rb +0 -8
  11. data/lib/rubocop/ast/node/block_node.rb +1 -9
  12. data/lib/rubocop/ast/node/case_node.rb +0 -8
  13. data/lib/rubocop/ast/node/ensure_node.rb +0 -8
  14. data/lib/rubocop/ast/node/for_node.rb +0 -8
  15. data/lib/rubocop/ast/node/or_node.rb +0 -8
  16. data/lib/rubocop/ast/node/pair_node.rb +0 -8
  17. data/lib/rubocop/ast/node/resbody_node.rb +0 -8
  18. data/lib/rubocop/ast/node/send_node.rb +0 -8
  19. data/lib/rubocop/ast/node/symbol_node.rb +0 -8
  20. data/lib/rubocop/ast/node/until_node.rb +0 -8
  21. data/lib/rubocop/ast/node/when_node.rb +0 -8
  22. data/lib/rubocop/ast/node/while_node.rb +0 -8
  23. data/lib/rubocop/cli.rb +17 -7
  24. data/lib/rubocop/comment_config.rb +24 -3
  25. data/lib/rubocop/config.rb +75 -6
  26. data/lib/rubocop/config_loader.rb +18 -28
  27. data/lib/rubocop/config_loader_resolver.rb +61 -9
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/commissioner.rb +2 -2
  32. data/lib/rubocop/cop/cop.rb +4 -0
  33. data/lib/rubocop/cop/corrector.rb +11 -1
  34. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
  37. data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
  38. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
  40. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
  42. data/lib/rubocop/cop/generator.rb +29 -8
  43. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
  45. data/lib/rubocop/cop/layout/align_hash.rb +106 -37
  46. data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
  47. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
  48. data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
  49. data/lib/rubocop/cop/layout/class_structure.rb +6 -7
  50. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  51. data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
  52. data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
  55. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
  56. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  57. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  58. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
  59. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
  60. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
  61. data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
  62. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  63. data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
  64. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
  65. data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
  66. data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
  67. data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
  68. data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
  69. data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
  70. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
  71. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  72. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
  73. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
  75. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
  76. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  77. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
  78. data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
  80. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
  83. data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  86. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
  87. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
  88. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
  89. data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
  90. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
  91. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
  92. data/lib/rubocop/cop/layout/tab.rb +42 -16
  93. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
  94. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
  95. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
  96. data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
  97. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  98. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
  99. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  100. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
  101. data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
  102. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
  103. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
  104. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
  105. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  106. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  107. data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
  108. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
  109. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
  110. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  111. data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
  112. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
  115. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  116. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
  117. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
  118. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
  119. data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
  120. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
  122. data/lib/rubocop/cop/lint/script_permission.rb +30 -10
  123. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  124. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
  125. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  126. data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
  127. data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
  128. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
  129. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
  131. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
  132. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  135. data/lib/rubocop/cop/lint/void.rb +49 -10
  136. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  137. data/lib/rubocop/cop/metrics/line_length.rb +5 -2
  138. data/lib/rubocop/cop/mixin/alignment.rb +4 -0
  139. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  140. data/lib/rubocop/cop/mixin/def_node.rb +4 -0
  141. data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
  142. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
  143. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
  144. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  145. data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
  146. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  147. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
  148. data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
  149. data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
  150. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
  151. data/lib/rubocop/cop/mixin/range_help.rb +102 -0
  152. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
  153. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
  154. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
  155. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
  156. data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
  157. data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
  158. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  159. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
  160. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
  161. data/lib/rubocop/cop/naming/file_name.rb +5 -10
  162. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
  163. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
  164. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
  165. data/lib/rubocop/cop/offense.rb +3 -2
  166. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
  167. data/lib/rubocop/cop/performance/casecmp.rb +17 -8
  168. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
  169. data/lib/rubocop/cop/performance/count.rb +1 -0
  170. data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
  171. data/lib/rubocop/cop/performance/flat_map.rb +2 -0
  172. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
  173. data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
  174. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
  175. data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
  176. data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
  177. data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
  178. data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
  179. data/lib/rubocop/cop/rails/blank.rb +3 -3
  180. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
  181. data/lib/rubocop/cop/rails/delegate.rb +6 -6
  182. data/lib/rubocop/cop/rails/file_path.rb +7 -1
  183. data/lib/rubocop/cop/rails/find_by.rb +2 -0
  184. data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
  185. data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
  186. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
  187. data/lib/rubocop/cop/rails/presence.rb +8 -2
  188. data/lib/rubocop/cop/rails/present.rb +5 -5
  189. data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
  190. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  191. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
  192. data/lib/rubocop/cop/rails/request_referer.rb +3 -2
  193. data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
  194. data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
  195. data/lib/rubocop/cop/rails/save_bang.rb +11 -12
  196. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  197. data/lib/rubocop/cop/rails/time_zone.rb +38 -16
  198. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
  199. data/lib/rubocop/cop/rails/validation.rb +30 -2
  200. data/lib/rubocop/cop/security/open.rb +48 -0
  201. data/lib/rubocop/cop/style/and_or.rb +1 -0
  202. data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
  203. data/lib/rubocop/cop/style/attr.rb +2 -0
  204. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  205. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
  206. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  207. data/lib/rubocop/cop/style/class_vars.rb +23 -0
  208. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  209. data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
  210. data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  212. data/lib/rubocop/cop/style/copyright.rb +3 -1
  213. data/lib/rubocop/cop/style/each_with_object.rb +15 -1
  214. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
  215. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
  216. data/lib/rubocop/cop/style/empty_else.rb +9 -5
  217. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  218. data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
  219. data/lib/rubocop/cop/style/empty_literal.rb +1 -0
  220. data/lib/rubocop/cop/style/encoding.rb +2 -0
  221. data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
  222. data/lib/rubocop/cop/style/for.rb +33 -0
  223. data/lib/rubocop/cop/style/format_string.rb +1 -1
  224. data/lib/rubocop/cop/style/format_string_token.rb +4 -5
  225. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  226. data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  228. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  229. data/lib/rubocop/cop/style/lambda.rb +1 -1
  230. data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
  231. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
  232. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
  233. data/lib/rubocop/cop/style/missing_else.rb +72 -7
  234. data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
  235. data/lib/rubocop/cop/style/module_function.rb +10 -0
  236. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
  237. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  238. data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
  239. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
  240. data/lib/rubocop/cop/style/next.rb +1 -0
  241. data/lib/rubocop/cop/style/not.rb +2 -0
  242. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  243. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
  245. data/lib/rubocop/cop/style/redundant_return.rb +37 -3
  246. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  247. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  248. data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
  249. data/lib/rubocop/cop/style/semicolon.rb +3 -1
  250. data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
  251. data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
  252. data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
  253. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  254. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
  255. data/lib/rubocop/cop/style/symbol_array.rb +29 -0
  256. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  257. data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
  258. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
  259. data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
  260. data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
  261. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
  262. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
  263. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  264. data/lib/rubocop/cop/style/unless_else.rb +2 -0
  265. data/lib/rubocop/cop/style/word_array.rb +0 -1
  266. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  267. data/lib/rubocop/cop/team.rb +5 -5
  268. data/lib/rubocop/cop/util.rb +23 -188
  269. data/lib/rubocop/cop/variable_force.rb +1 -1
  270. data/lib/rubocop/file_finder.rb +45 -0
  271. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
  272. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  273. data/lib/rubocop/formatter/html_formatter.rb +12 -5
  274. data/lib/rubocop/formatter/json_formatter.rb +1 -1
  275. data/lib/rubocop/node_pattern.rb +8 -5
  276. data/lib/rubocop/options.rb +40 -33
  277. data/lib/rubocop/path_util.rb +5 -8
  278. data/lib/rubocop/processed_source.rb +53 -0
  279. data/lib/rubocop/remote_config.rb +1 -1
  280. data/lib/rubocop/result_cache.rb +1 -1
  281. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  282. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
  283. data/lib/rubocop/rspec/shared_contexts.rb +3 -1
  284. data/lib/rubocop/rspec/shared_examples.rb +23 -25
  285. data/lib/rubocop/rspec/support.rb +5 -0
  286. data/lib/rubocop/runner.rb +3 -2
  287. data/lib/rubocop/string_util.rb +10 -9
  288. data/lib/rubocop/target_finder.rb +4 -1
  289. data/lib/rubocop/token.rb +26 -16
  290. data/lib/rubocop/version.rb +6 -4
  291. metadata +31 -17
  292. data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -23,17 +23,19 @@ module RuboCop
23
23
  # 'Item 2'
24
24
  # ]
25
25
  class ImplicitStringConcatenation < Cop
26
- MSG = 'Combine %s and %s into a single string literal, rather than ' \
27
- 'using implicit string concatenation.'.freeze
26
+ MSG = 'Combine %<string1>s and %<string2>s into a single string ' \
27
+ 'literal, rather than using implicit string concatenation.'.freeze
28
28
  FOR_ARRAY = ' Or, if they were intended to be separate array ' \
29
29
  'elements, separate them with a comma.'.freeze
30
30
  FOR_METHOD = ' Or, if they were intended to be separate method ' \
31
31
  'arguments, separate them with a comma.'.freeze
32
32
 
33
33
  def on_dstr(node)
34
- each_bad_cons(node) do |child1, child2|
35
- range = child1.source_range.join(child2.source_range)
36
- message = format(MSG, display_str(child1), display_str(child2))
34
+ each_bad_cons(node) do |child_node1, child_node2|
35
+ range = child_node1.source_range.join(child_node2.source_range)
36
+ message = format(MSG,
37
+ string1: display_str(child_node1),
38
+ string2: display_str(child_node2))
37
39
  if node.parent && node.parent.array_type?
38
40
  message << FOR_ARRAY
39
41
  elsif node.parent && node.parent.send_type?
@@ -46,17 +48,17 @@ module RuboCop
46
48
  private
47
49
 
48
50
  def each_bad_cons(node)
49
- node.children.each_cons(2) do |child1, child2|
51
+ node.children.each_cons(2) do |child_node1, child_node2|
50
52
  # `'abc' 'def'` -> (dstr (str "abc") (str "def"))
51
- next unless string_literal?(child1) && string_literal?(child2)
52
- next unless child1.last_line == child2.first_line
53
+ next unless string_literals?(child_node1, child_node2)
54
+ next unless child_node1.last_line == child_node2.first_line
53
55
 
54
56
  # Make sure we don't flag a string literal which simply has
55
57
  # embedded newlines
56
58
  # `"abc\ndef"` also -> (dstr (str "abc") (str "def"))
57
- next unless child1.source[-1] == ending_delimiter(child1)
59
+ next unless child_node1.source[-1] == ending_delimiter(child_node1)
58
60
 
59
- yield child1, child2
61
+ yield child_node1, child_node2
60
62
  end
61
63
  end
62
64
 
@@ -74,6 +76,10 @@ module RuboCop
74
76
  (node.dstr_type? && node.children.all? { |c| string_literal?(c) })
75
77
  end
76
78
 
79
+ def string_literals?(node1, node2)
80
+ string_literal?(node1) && string_literal?(node2)
81
+ end
82
+
77
83
  def display_str(node)
78
84
  if node.source =~ /\n/
79
85
  str_content(node).inspect
@@ -46,8 +46,8 @@ module RuboCop
46
46
  # end
47
47
  # end
48
48
  class IneffectiveAccessModifier < Cop
49
- MSG = '`%s` (on line %d) does not make singleton methods %s. ' \
50
- 'Use %s instead.'.freeze
49
+ MSG = '`%<modifier>s` (on line %<line>d) does not make singleton ' \
50
+ 'methods %<modifier>s. Use %<alternative>s instead.'.freeze
51
51
  ALTERNATIVE_PRIVATE = '`private_class_method` or `private` inside a ' \
52
52
  '`class << self` block'.freeze
53
53
  ALTERNATIVE_PROTECTED = '`protected` inside a `class << self` ' \
@@ -91,8 +91,9 @@ module RuboCop
91
91
  else
92
92
  ALTERNATIVE_PROTECTED
93
93
  end
94
- format(MSG, visibility, modifier.location.expression.line, visibility,
95
- alternative)
94
+ format(MSG, modifier: visibility,
95
+ line: modifier.location.expression.line,
96
+ alternative: alternative)
96
97
  end
97
98
 
98
99
  def check_scope(node, cur_vis = :public)
@@ -28,7 +28,7 @@ module RuboCop
28
28
  class InheritException < Cop
29
29
  include ConfigurableEnforcedStyle
30
30
 
31
- MSG = 'Inherit from `%s` instead of `%s`.'.freeze
31
+ MSG = 'Inherit from `%<prefer>s` instead of `%<current>s`.'.freeze
32
32
  PREFERRED_BASE_CLASS = {
33
33
  runtime_error: 'RuntimeError',
34
34
  standard_error: 'StandardError'
@@ -64,7 +64,7 @@ module RuboCop
64
64
  private
65
65
 
66
66
  def message(node)
67
- format(MSG, preferred_base_class, node.const_name)
67
+ format(MSG, prefer: preferred_base_class, current: node.const_name)
68
68
  end
69
69
 
70
70
  def illegal_class_name?(class_node)
@@ -18,12 +18,13 @@ module RuboCop
18
18
  # foo = "something with #{interpolation} inside"
19
19
  class InterpolationCheck < Cop
20
20
  MSG = 'Interpolation in single quoted string detected. '\
21
- 'Use double quoted strings if you need interpolation.'.freeze
21
+ 'Use double quoted strings if you need interpolation.'.freeze
22
22
 
23
23
  def on_str(node)
24
24
  return if heredoc?(node)
25
- return if node.parent && node.parent.dstr_type?
26
- return unless node.str_content.scrub =~ /#\{.*\}/
25
+ parent = node.parent
26
+ return if parent && (parent.dstr_type? || parent.regexp_type?)
27
+ return unless node.source.scrub =~ /(?<!\\)#\{.*\}/
27
28
  add_offense(node)
28
29
  end
29
30
 
@@ -31,7 +31,7 @@ module RuboCop
31
31
  # do_something
32
32
  # end
33
33
  class LiteralAsCondition < Cop
34
- MSG = 'Literal `%s` appeared as a condition.'.freeze
34
+ MSG = 'Literal `%<literal>s` appeared as a condition.'.freeze
35
35
 
36
36
  def on_if(node)
37
37
  check_for_literal(node)
@@ -71,7 +71,7 @@ module RuboCop
71
71
  end
72
72
 
73
73
  def message(node)
74
- format(MSG, node.source)
74
+ format(MSG, literal: node.source)
75
75
  end
76
76
 
77
77
  private
@@ -17,6 +17,8 @@ module RuboCop
17
17
  #
18
18
  # "result is 10"
19
19
  class LiteralInInterpolation < Cop
20
+ include RangeHelp
21
+
20
22
  MSG = 'Literal interpolation detected.'.freeze
21
23
  COMPOSITE = %i[array hash pair irange erange].freeze
22
24
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Lint/UnneededDisable
3
+ # rubocop:disable Lint/UnneededCopDisableDirective
4
4
  module RuboCop
5
5
  module Cop
6
6
  module Lint
@@ -43,9 +43,11 @@ module RuboCop
43
43
  # # rubocop:enable Layout/SpaceAroundOperators
44
44
  #
45
45
  class MissingCopEnableDirective < Cop
46
- MSG = 'Re-enable %{cop} cop with `# rubocop:enable` after disabling it.'
47
- .freeze
48
- MSG_BOUND = 'Re-enable %{cop} cop within %{max_range} lines after ' \
46
+ include RangeHelp
47
+
48
+ MSG = 'Re-enable %<cop>s cop with `# rubocop:enable` after ' \
49
+ 'disabling it.'.freeze
50
+ MSG_BOUND = 'Re-enable %<cop>s cop within %<max_range>s lines after ' \
49
51
  'disabling it.'.freeze
50
52
 
51
53
  def investigate(processed_source)
@@ -78,4 +80,4 @@ module RuboCop
78
80
  end
79
81
  end
80
82
  end
81
- # rubocop:enable Lint/UnneededDisable, Layout/SpaceAroundOperators
83
+ # rubocop:enable Lint/UnneededCopDisableDirective, Layout/SpaceAroundOperators
@@ -25,7 +25,7 @@ module RuboCop
25
25
  # if found within a percent literal expression, will cause a
26
26
  # NestedPercentLiteral violation to be emitted.
27
27
  REGEXES = PercentLiteral::PERCENT_LITERAL_TYPES.map do |percent_literal|
28
- /#{percent_literal}\W/
28
+ /\A#{percent_literal}\W/
29
29
  end.freeze
30
30
 
31
31
  def on_array(node)
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # This cop warns the usage of unsafe number conversions. Unsafe
7
+ # number conversion can cause unexpected error if auto type conversion
8
+ # fails. Cop prefer parsing with number class instead.
9
+ #
10
+ # @example
11
+ #
12
+ # # bad
13
+ #
14
+ # '10'.to_i
15
+ # '10.2'.to_f
16
+ # '10'.to_c
17
+ #
18
+ # # good
19
+ #
20
+ # Integer('10', 10)
21
+ # Float('10.2')
22
+ # Complex('10')
23
+ class NumberConversion < Cop
24
+ CONVERSION_METHOD_CLASS_MAPPING = {
25
+ to_i: "#{Integer.name}(%<number_object>s, 10)",
26
+ to_f: "#{Float.name}(%<number_object>s)",
27
+ to_c: "#{Complex.name}(%<number_object>s)"
28
+ }.freeze
29
+ MSG = 'Replace unsafe number conversion with number '\
30
+ 'class parsing, instead of using '\
31
+ '%<number_object>s.%<to_method>s, use stricter '\
32
+ '%<corrected_method>s.'.freeze
33
+
34
+ def_node_matcher :to_method, <<-PATTERN
35
+ (send $_ ${:to_i :to_f :to_c})
36
+ PATTERN
37
+
38
+ def on_send(node)
39
+ to_method(node) do |receiver, to_method|
40
+ message = format(
41
+ MSG,
42
+ number_object: receiver.source,
43
+ to_method: to_method,
44
+ corrected_method: correct_method(node, receiver)
45
+ )
46
+ add_offense(node, message: message)
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def correct_method(node, receiver)
53
+ format(CONVERSION_METHOD_CLASS_MAPPING[node.method_name],
54
+ number_object: receiver.source)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ #
7
+ # Checks the proper ordering of magic comments and whether
8
+ # a magic comment is not placed before a shebang.
9
+ #
10
+ # @example
11
+ # # bad
12
+ #
13
+ # # frozen_string_literal: true
14
+ # # encoding: ascii
15
+ # p [''.frozen?, ''.encoding] #=> [true, #<Encoding:UTF-8>]
16
+ #
17
+ # # good
18
+ #
19
+ # # encoding: ascii
20
+ # # frozen_string_literal: true
21
+ # p [''.frozen?, ''.encoding] #=> [true, #<Encoding:US-ASCII>]
22
+ #
23
+ # # good
24
+ #
25
+ # #!/usr/bin/env ruby
26
+ # # encoding: ascii
27
+ # # frozen_string_literal: true
28
+ # p [''.frozen?, ''.encoding] #=> [true, #<Encoding:US-ASCII>]
29
+ #
30
+ class OrderedMagicComments < Cop
31
+ include FrozenStringLiteral
32
+
33
+ MSG = 'The encoding magic comment should precede all other ' \
34
+ 'magic comments.'.freeze
35
+
36
+ def investigate(processed_source)
37
+ return if processed_source.buffer.source.empty?
38
+
39
+ encoding_line, frozen_string_literal_line = magic_comment_lines
40
+
41
+ return unless encoding_line && frozen_string_literal_line
42
+ return if encoding_line < frozen_string_literal_line
43
+
44
+ range = processed_source.buffer.line_range(encoding_line + 1)
45
+
46
+ add_offense(range, location: range)
47
+ end
48
+
49
+ def autocorrect(_node)
50
+ encoding_line, frozen_string_literal_line = magic_comment_lines
51
+
52
+ range1 = processed_source.buffer.line_range(encoding_line + 1)
53
+ range2 =
54
+ processed_source.buffer.line_range(frozen_string_literal_line + 1)
55
+
56
+ lambda do |corrector|
57
+ corrector.replace(range1, range2.source)
58
+ corrector.replace(range2, range1.source)
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def magic_comment_lines
65
+ lines = [nil, nil]
66
+
67
+ magic_comments.each.with_index do |comment, index|
68
+ if comment.encoding_specified?
69
+ lines[0] = index
70
+ elsif comment.frozen_string_literal_specified?
71
+ lines[1] = index
72
+ end
73
+
74
+ return lines if lines[0] && lines[1]
75
+ end
76
+
77
+ lines
78
+ end
79
+
80
+ def magic_comments
81
+ leading_comment_lines.map { |line| MagicComment.parse(line) }
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -18,6 +18,8 @@ module RuboCop
18
18
  #
19
19
  # puts(x + y)
20
20
  class ParenthesesAsGroupedExpression < Cop
21
+ include RangeHelp
22
+
21
23
  MSG = '`(...)` interpreted as grouped expression.'.freeze
22
24
 
23
25
  def on_send(node)
@@ -40,7 +40,6 @@ module RuboCop
40
40
  add_offense(node)
41
41
  end
42
42
 
43
- # rubocop:disable Performance/HashEachMethods
44
43
  def autocorrect(node)
45
44
  lambda do |corrector|
46
45
  node.values.each do |value|
@@ -55,7 +54,6 @@ module RuboCop
55
54
  end
56
55
  end
57
56
  end
58
- # rubocop:enable Performance/HashEachMethods
59
57
 
60
58
  private
61
59
 
@@ -21,7 +21,7 @@ module RuboCop
21
21
  #
22
22
  # 0 # just use 0 instead
23
23
  class RandOne < Cop
24
- MSG = '`%s` always returns `0`. ' \
24
+ MSG = '`%<method>s` always returns `0`. ' \
25
25
  'Perhaps you meant `rand(2)` or `rand`?'.freeze
26
26
 
27
27
  def_node_matcher :rand_one?, <<-PATTERN
@@ -37,7 +37,7 @@ module RuboCop
37
37
  private
38
38
 
39
39
  def message(node)
40
- format(MSG, node.source)
40
+ format(MSG, method: node.source)
41
41
  end
42
42
  end
43
43
  end
@@ -27,6 +27,8 @@ module RuboCop
27
27
  # end
28
28
  #
29
29
  class RedundantWithIndex < Cop
30
+ include RangeHelp
31
+
30
32
  MSG_EACH_WITH_INDEX = 'Use `each` instead of `each_with_index`.'.freeze
31
33
  MSG_WITH_INDEX = 'Remove redundant `with_index`.'.freeze
32
34
 
@@ -27,6 +27,8 @@ module RuboCop
27
27
  # end
28
28
  #
29
29
  class RedundantWithObject < Cop
30
+ include RangeHelp
31
+
30
32
  MSG_EACH_WITH_OBJECT = 'Use `each` instead of `each_with_object`.'
31
33
  .freeze
32
34
  MSG_WITH_OBJECT = 'Remove redundant `with_object`.'.freeze
@@ -28,6 +28,8 @@ module RuboCop
28
28
  # # ...
29
29
  # end
30
30
  class RequireParentheses < Cop
31
+ include RangeHelp
32
+
31
33
  MSG = 'Use parentheses in the method call to avoid confusion about ' \
32
34
  'precedence.'.freeze
33
35
 
@@ -37,8 +37,8 @@ module RuboCop
37
37
  class RescueType < Cop
38
38
  include RescueNode
39
39
 
40
- MSG = 'Rescuing from `%s` will raise a `TypeError` instead of ' \
41
- 'catching the actual exception.'.freeze
40
+ MSG = 'Rescuing from `%<invalid_exceptions>s` will raise a ' \
41
+ '`TypeError` instead of catching the actual exception.'.freeze
42
42
  INVALID_TYPES = %i[array dstr float hash nil int str sym].freeze
43
43
 
44
44
  def on_resbody(node)
@@ -51,7 +51,10 @@ module RuboCop
51
51
  add_offense(
52
52
  node,
53
53
  location: node.loc.keyword.join(rescued.loc.expression),
54
- message: format(MSG, invalid_exceptions.map(&:source).join(', '))
54
+ message: format(
55
+ MSG, invalid_exceptions: invalid_exceptions.map(&:source)
56
+ .join(', ')
57
+ )
55
58
  )
56
59
  end
57
60
 
@@ -32,7 +32,7 @@ module RuboCop
32
32
  # return
33
33
  # end
34
34
  class ReturnInVoidContext < Cop
35
- MSG = 'Do not return a value in `%s`.'.freeze
35
+ MSG = 'Do not return a value in `%<method>s`.'.freeze
36
36
 
37
37
  def on_return(return_node)
38
38
  return unless return_node.descendants.any?
@@ -47,7 +47,7 @@ module RuboCop
47
47
 
48
48
  add_offense(return_node,
49
49
  location: :keyword,
50
- message: format(message, method_name))
50
+ message: format(message, method: method_name))
51
51
  end
52
52
 
53
53
  private