rubocop 0.49.1 → 0.52.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 (506) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -9
  3. data/bin/rubocop +1 -1
  4. data/config/default.yml +264 -118
  5. data/config/disabled.yml +13 -9
  6. data/config/enabled.yml +1156 -918
  7. data/lib/rubocop.rb +555 -489
  8. data/lib/rubocop/ast/builder.rb +6 -1
  9. data/lib/rubocop/ast/node.rb +68 -52
  10. data/lib/rubocop/ast/node/args_node.rb +15 -10
  11. data/lib/rubocop/ast/node/array_node.rb +10 -1
  12. data/lib/rubocop/ast/node/block_node.rb +9 -0
  13. data/lib/rubocop/ast/node/def_node.rb +71 -0
  14. data/lib/rubocop/ast/node/for_node.rb +8 -0
  15. data/lib/rubocop/ast/node/if_node.rb +10 -2
  16. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +16 -0
  17. data/lib/rubocop/ast/node/mixin/collection_node.rb +15 -0
  18. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +174 -0
  19. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +89 -0
  20. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +18 -31
  21. data/lib/rubocop/ast/node/regexp_node.rb +35 -0
  22. data/lib/rubocop/ast/node/send_node.rb +21 -150
  23. data/lib/rubocop/ast/node/str_node.rb +14 -0
  24. data/lib/rubocop/ast/node/super_node.rb +3 -24
  25. data/lib/rubocop/ast/node/symbol_node.rb +20 -0
  26. data/lib/rubocop/ast/node/yield_node.rb +21 -0
  27. data/lib/rubocop/ast/traversal.rb +7 -7
  28. data/lib/rubocop/cached_data.rb +1 -6
  29. data/lib/rubocop/cli.rb +59 -13
  30. data/lib/rubocop/comment_config.rb +2 -5
  31. data/lib/rubocop/config.rb +136 -29
  32. data/lib/rubocop/config_loader.rb +61 -104
  33. data/lib/rubocop/config_loader_resolver.rb +102 -4
  34. data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
  35. data/lib/rubocop/cop/bundler/duplicated_gem.rb +13 -11
  36. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +67 -0
  37. data/lib/rubocop/cop/bundler/ordered_gems.rb +7 -58
  38. data/lib/rubocop/cop/commissioner.rb +6 -3
  39. data/lib/rubocop/cop/cop.rb +11 -6
  40. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +102 -0
  41. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +97 -0
  42. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +87 -0
  43. data/lib/rubocop/cop/generator.rb +122 -25
  44. data/lib/rubocop/cop/internal_affairs.rb +6 -2
  45. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +46 -0
  46. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +16 -5
  47. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +54 -0
  48. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +59 -0
  49. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +71 -0
  50. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +3 -3
  51. data/lib/rubocop/cop/layout/access_modifier_indentation.rb +6 -10
  52. data/lib/rubocop/cop/layout/align_array.rb +2 -2
  53. data/lib/rubocop/cop/layout/align_hash.rb +18 -18
  54. data/lib/rubocop/cop/layout/align_parameters.rb +11 -23
  55. data/lib/rubocop/cop/layout/block_end_newline.rb +20 -6
  56. data/lib/rubocop/cop/layout/case_indentation.rb +15 -18
  57. data/lib/rubocop/cop/layout/class_structure.rb +306 -0
  58. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +7 -6
  59. data/lib/rubocop/cop/layout/comment_indentation.rb +42 -3
  60. data/lib/rubocop/cop/layout/dot_position.rb +31 -13
  61. data/lib/rubocop/cop/layout/else_alignment.rb +37 -17
  62. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +1 -1
  63. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -18
  64. data/lib/rubocop/cop/layout/empty_lines.rb +16 -2
  65. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +23 -6
  66. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +89 -0
  67. data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +2 -2
  68. data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +4 -8
  69. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +30 -5
  70. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +10 -6
  71. data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +5 -5
  72. data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +22 -7
  73. data/lib/rubocop/cop/layout/end_of_line.rb +2 -2
  74. data/lib/rubocop/cop/layout/extra_spacing.rb +23 -26
  75. data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +3 -3
  76. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +9 -3
  77. data/lib/rubocop/cop/layout/indent_array.rb +68 -21
  78. data/lib/rubocop/cop/layout/indent_hash.rb +71 -26
  79. data/lib/rubocop/cop/layout/indent_heredoc.rb +70 -35
  80. data/lib/rubocop/cop/layout/indentation_consistency.rb +1 -2
  81. data/lib/rubocop/cop/layout/indentation_width.rb +40 -27
  82. data/lib/rubocop/cop/layout/initial_indentation.rb +10 -7
  83. data/lib/rubocop/cop/layout/leading_comment_space.rb +32 -17
  84. data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +47 -14
  85. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +12 -11
  86. data/lib/rubocop/cop/layout/multiline_block_layout.rb +19 -16
  87. data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +46 -13
  88. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +29 -27
  89. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +7 -3
  90. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -0
  91. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +12 -4
  92. data/lib/rubocop/cop/layout/space_after_colon.rb +13 -6
  93. data/lib/rubocop/cop/layout/space_after_comma.rb +11 -1
  94. data/lib/rubocop/cop/layout/space_after_method_name.rb +8 -6
  95. data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
  96. data/lib/rubocop/cop/layout/space_after_semicolon.rb +8 -1
  97. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +32 -25
  98. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +28 -17
  99. data/lib/rubocop/cop/layout/space_around_keyword.rb +22 -16
  100. data/lib/rubocop/cop/layout/space_around_operators.rb +27 -14
  101. data/lib/rubocop/cop/layout/space_before_block_braces.rb +61 -12
  102. data/lib/rubocop/cop/layout/space_before_comma.rb +12 -1
  103. data/lib/rubocop/cop/layout/space_before_comment.rb +10 -5
  104. data/lib/rubocop/cop/layout/space_before_first_arg.rb +5 -4
  105. data/lib/rubocop/cop/layout/space_before_semicolon.rb +8 -1
  106. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +12 -14
  107. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +235 -0
  108. data/lib/rubocop/cop/layout/space_inside_array_percent_literal.rb +4 -4
  109. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +89 -18
  110. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +62 -36
  111. data/lib/rubocop/cop/layout/space_inside_parens.rb +40 -3
  112. data/lib/rubocop/cop/layout/space_inside_percent_literal_delimiters.rb +1 -1
  113. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +15 -15
  114. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +81 -0
  115. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +32 -17
  116. data/lib/rubocop/cop/layout/tab.rb +7 -4
  117. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +11 -9
  118. data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
  119. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +12 -19
  120. data/lib/rubocop/cop/lint/assignment_in_condition.rb +16 -2
  121. data/lib/rubocop/cop/lint/block_alignment.rb +42 -30
  122. data/lib/rubocop/cop/lint/boolean_symbol.rb +38 -0
  123. data/lib/rubocop/cop/lint/circular_argument_reference.rb +3 -14
  124. data/lib/rubocop/cop/lint/condition_position.rb +5 -1
  125. data/lib/rubocop/cop/lint/debugger.rb +18 -11
  126. data/lib/rubocop/cop/lint/def_end_alignment.rb +9 -14
  127. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
  128. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +3 -3
  129. data/lib/rubocop/cop/lint/duplicate_methods.rb +75 -5
  130. data/lib/rubocop/cop/lint/duplicated_key.rb +1 -1
  131. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  132. data/lib/rubocop/cop/lint/else_layout.rb +3 -3
  133. data/lib/rubocop/cop/lint/empty_ensure.rb +1 -1
  134. data/lib/rubocop/cop/lint/empty_expression.rb +1 -1
  135. data/lib/rubocop/cop/lint/empty_interpolation.rb +1 -1
  136. data/lib/rubocop/cop/lint/empty_when.rb +1 -1
  137. data/lib/rubocop/cop/lint/end_alignment.rb +13 -14
  138. data/lib/rubocop/cop/lint/end_in_method.rb +1 -1
  139. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  140. data/lib/rubocop/cop/lint/float_out_of_range.rb +5 -5
  141. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +36 -41
  142. data/lib/rubocop/cop/lint/handle_exceptions.rb +1 -1
  143. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
  144. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +25 -20
  145. data/lib/rubocop/cop/lint/inherit_exception.rb +16 -19
  146. data/lib/rubocop/cop/lint/interpolation_check.rb +37 -0
  147. data/lib/rubocop/cop/lint/{literal_in_condition.rb → literal_as_condition.rb} +21 -7
  148. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
  149. data/lib/rubocop/cop/lint/loop.rb +1 -1
  150. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +81 -0
  151. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  152. data/lib/rubocop/cop/lint/nested_method_definition.rb +6 -8
  153. data/lib/rubocop/cop/lint/nested_percent_literal.rb +58 -0
  154. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  155. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +4 -4
  156. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +4 -3
  157. data/lib/rubocop/cop/lint/percent_string_array.rb +13 -22
  158. data/lib/rubocop/cop/lint/percent_symbol_array.rb +12 -12
  159. data/lib/rubocop/cop/lint/rand_one.rb +8 -2
  160. data/lib/rubocop/cop/lint/redundant_with_index.rb +80 -0
  161. data/lib/rubocop/cop/lint/redundant_with_object.rb +81 -0
  162. data/lib/rubocop/cop/lint/regexp_as_condition.rb +29 -0
  163. data/lib/rubocop/cop/lint/require_parentheses.rb +5 -3
  164. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  165. data/lib/rubocop/cop/lint/rescue_type.rb +18 -9
  166. data/lib/rubocop/cop/lint/return_in_void_context.rb +74 -0
  167. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +1 -1
  168. data/lib/rubocop/cop/lint/script_permission.rb +8 -1
  169. data/lib/rubocop/cop/lint/shadowed_argument.rb +146 -0
  170. data/lib/rubocop/cop/lint/shadowed_exception.rb +37 -10
  171. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
  172. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +7 -7
  173. data/lib/rubocop/cop/lint/syntax.rb +23 -20
  174. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +1 -1
  175. data/lib/rubocop/cop/lint/unified_integer.rb +5 -4
  176. data/lib/rubocop/cop/lint/unneeded_disable.rb +41 -16
  177. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +51 -0
  178. data/lib/rubocop/cop/lint/unneeded_splat_expansion.rb +45 -19
  179. data/lib/rubocop/cop/lint/unreachable_code.rb +53 -8
  180. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  181. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +74 -0
  182. data/lib/rubocop/cop/lint/uri_regexp.rb +73 -0
  183. data/lib/rubocop/cop/lint/useless_access_modifier.rb +12 -16
  184. data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
  185. data/lib/rubocop/cop/lint/useless_comparison.rb +1 -1
  186. data/lib/rubocop/cop/lint/useless_setter_call.rb +15 -12
  187. data/lib/rubocop/cop/lint/void.rb +38 -27
  188. data/lib/rubocop/cop/message_annotator.rb +4 -2
  189. data/lib/rubocop/cop/metrics/abc_size.rb +2 -2
  190. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  191. data/lib/rubocop/cop/metrics/class_length.rb +3 -1
  192. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -1
  193. data/lib/rubocop/cop/metrics/line_length.rb +8 -5
  194. data/lib/rubocop/cop/metrics/method_length.rb +8 -3
  195. data/lib/rubocop/cop/metrics/module_length.rb +3 -1
  196. data/lib/rubocop/cop/metrics/parameter_lists.rb +14 -5
  197. data/lib/rubocop/cop/metrics/perceived_complexity.rb +2 -1
  198. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +3 -2
  199. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +2 -2
  200. data/lib/rubocop/cop/mixin/code_length.rb +1 -1
  201. data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -1
  202. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  203. data/lib/rubocop/cop/mixin/documentation_comment.rb +1 -1
  204. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +14 -7
  205. data/lib/rubocop/cop/mixin/empty_parameter.rb +23 -0
  206. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +8 -4
  207. data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -3
  208. data/lib/rubocop/cop/mixin/first_element_line_break.rb +12 -3
  209. data/lib/rubocop/cop/mixin/heredoc.rb +28 -0
  210. data/lib/rubocop/cop/mixin/method_complexity.rb +33 -7
  211. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +74 -33
  212. data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +34 -8
  213. data/lib/rubocop/cop/mixin/negative_conditional.rb +4 -1
  214. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +67 -0
  215. data/lib/rubocop/cop/mixin/parentheses.rb +12 -0
  216. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +4 -1
  217. data/lib/rubocop/cop/mixin/percent_array.rb +52 -0
  218. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +9 -8
  219. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -10
  220. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -17
  221. data/lib/rubocop/cop/mixin/string_help.rb +1 -1
  222. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  223. data/lib/rubocop/cop/mixin/surrounding_space.rb +95 -8
  224. data/lib/rubocop/cop/mixin/too_many_lines.rb +2 -2
  225. data/lib/rubocop/cop/mixin/trailing_comma.rb +25 -17
  226. data/lib/rubocop/cop/mixin/unused_argument.rb +6 -2
  227. data/lib/rubocop/cop/naming/accessor_method_name.rb +55 -0
  228. data/lib/rubocop/cop/{style → naming}/ascii_identifiers.rb +35 -2
  229. data/lib/rubocop/cop/{style/op_method.rb → naming/binary_operator_parameter_name.rb} +7 -6
  230. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +33 -0
  231. data/lib/rubocop/cop/naming/constant_name.rb +58 -0
  232. data/lib/rubocop/cop/{style → naming}/file_name.rb +28 -13
  233. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +62 -0
  234. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +59 -0
  235. data/lib/rubocop/cop/naming/method_name.rb +40 -0
  236. data/lib/rubocop/cop/naming/predicate_name.rb +101 -0
  237. data/lib/rubocop/cop/naming/variable_name.rb +50 -0
  238. data/lib/rubocop/cop/{style → naming}/variable_number.rb +11 -28
  239. data/lib/rubocop/cop/offense.rb +6 -1
  240. data/lib/rubocop/cop/performance/caller.rb +39 -11
  241. data/lib/rubocop/cop/performance/case_when_splat.rb +3 -7
  242. data/lib/rubocop/cop/performance/casecmp.rb +9 -8
  243. data/lib/rubocop/cop/performance/compare_with_block.rb +23 -13
  244. data/lib/rubocop/cop/performance/count.rb +7 -4
  245. data/lib/rubocop/cop/performance/detect.rb +9 -6
  246. data/lib/rubocop/cop/performance/double_start_end_with.rb +12 -20
  247. data/lib/rubocop/cop/performance/end_with.rb +6 -6
  248. data/lib/rubocop/cop/performance/fixed_size.rb +1 -1
  249. data/lib/rubocop/cop/performance/flat_map.rb +5 -2
  250. data/lib/rubocop/cop/performance/hash_each_methods.rb +85 -40
  251. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +9 -6
  252. data/lib/rubocop/cop/performance/range_include.rb +3 -3
  253. data/lib/rubocop/cop/performance/redundant_block_call.rb +28 -28
  254. data/lib/rubocop/cop/performance/redundant_match.rb +13 -12
  255. data/lib/rubocop/cop/performance/redundant_merge.rb +44 -26
  256. data/lib/rubocop/cop/performance/redundant_sort_by.rb +9 -6
  257. data/lib/rubocop/cop/performance/regexp_match.rb +19 -10
  258. data/lib/rubocop/cop/performance/reverse_each.rb +1 -1
  259. data/lib/rubocop/cop/performance/sample.rb +1 -1
  260. data/lib/rubocop/cop/performance/size.rb +3 -3
  261. data/lib/rubocop/cop/performance/start_with.rb +6 -6
  262. data/lib/rubocop/cop/performance/string_replacement.rb +6 -6
  263. data/lib/rubocop/cop/performance/times_map.rb +32 -22
  264. data/lib/rubocop/cop/performance/unfreeze_string.rb +50 -0
  265. data/lib/rubocop/cop/performance/uri_default_parser.rb +47 -0
  266. data/lib/rubocop/cop/rails/action_filter.rb +23 -1
  267. data/lib/rubocop/cop/rails/active_support_aliases.rb +4 -5
  268. data/lib/rubocop/cop/rails/application_job.rb +5 -3
  269. data/lib/rubocop/cop/rails/application_record.rb +5 -3
  270. data/lib/rubocop/cop/rails/blank.rb +20 -17
  271. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +82 -0
  272. data/lib/rubocop/cop/rails/date.rb +7 -6
  273. data/lib/rubocop/cop/rails/delegate.rb +53 -29
  274. data/lib/rubocop/cop/rails/delegate_allow_blank.rb +4 -4
  275. data/lib/rubocop/cop/rails/dynamic_find_by.rb +2 -2
  276. data/lib/rubocop/cop/rails/enum_uniqueness.rb +4 -4
  277. data/lib/rubocop/cop/rails/environment_comparison.rb +66 -0
  278. data/lib/rubocop/cop/rails/exit.rb +8 -1
  279. data/lib/rubocop/cop/rails/file_path.rb +8 -11
  280. data/lib/rubocop/cop/rails/find_by.rb +2 -1
  281. data/lib/rubocop/cop/rails/find_each.rb +1 -1
  282. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +8 -1
  283. data/lib/rubocop/cop/rails/has_many_or_has_one_dependent.rb +76 -0
  284. data/lib/rubocop/cop/rails/http_positional_arguments.rb +40 -44
  285. data/lib/rubocop/cop/rails/inverse_of.rb +96 -0
  286. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +112 -0
  287. data/lib/rubocop/cop/rails/not_null_column.rb +6 -6
  288. data/lib/rubocop/cop/rails/output.rb +11 -2
  289. data/lib/rubocop/cop/rails/output_safety.rb +16 -21
  290. data/lib/rubocop/cop/rails/pluralization_grammar.rb +10 -10
  291. data/lib/rubocop/cop/rails/presence.rb +105 -0
  292. data/lib/rubocop/cop/rails/present.rb +14 -17
  293. data/lib/rubocop/cop/rails/read_write_attribute.rb +13 -13
  294. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +91 -0
  295. data/lib/rubocop/cop/rails/relative_date_constant.rb +11 -11
  296. data/lib/rubocop/cop/rails/request_referer.rb +3 -3
  297. data/lib/rubocop/cop/rails/reversible_migration.rb +36 -35
  298. data/lib/rubocop/cop/rails/safe_navigation.rb +7 -8
  299. data/lib/rubocop/cop/rails/save_bang.rb +19 -17
  300. data/lib/rubocop/cop/rails/scope_args.rb +2 -2
  301. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  302. data/lib/rubocop/cop/rails/time_zone.rb +3 -2
  303. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +4 -2
  304. data/lib/rubocop/cop/rails/unknown_env.rb +63 -0
  305. data/lib/rubocop/cop/rails/validation.rb +8 -8
  306. data/lib/rubocop/cop/registry.rb +2 -1
  307. data/lib/rubocop/cop/security/eval.rb +4 -4
  308. data/lib/rubocop/cop/security/json_load.rb +7 -5
  309. data/lib/rubocop/cop/security/marshal_load.rb +8 -6
  310. data/lib/rubocop/cop/security/yaml_load.rb +4 -4
  311. data/lib/rubocop/cop/style/alias.rb +49 -27
  312. data/lib/rubocop/cop/style/and_or.rb +65 -45
  313. data/lib/rubocop/cop/style/array_join.rb +10 -1
  314. data/lib/rubocop/cop/style/ascii_comments.rb +24 -4
  315. data/lib/rubocop/cop/style/attr.rb +15 -5
  316. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +7 -5
  317. data/lib/rubocop/cop/style/bare_percent_literals.rb +31 -10
  318. data/lib/rubocop/cop/style/begin_block.rb +1 -1
  319. data/lib/rubocop/cop/style/block_comments.rb +17 -3
  320. data/lib/rubocop/cop/style/block_delimiters.rb +82 -16
  321. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +68 -32
  322. data/lib/rubocop/cop/style/case_equality.rb +13 -1
  323. data/lib/rubocop/cop/style/character_literal.rb +10 -0
  324. data/lib/rubocop/cop/style/class_and_module_children.rb +8 -4
  325. data/lib/rubocop/cop/style/class_check.rb +29 -10
  326. data/lib/rubocop/cop/style/class_methods.rb +10 -9
  327. data/lib/rubocop/cop/style/class_vars.rb +5 -4
  328. data/lib/rubocop/cop/style/collection_methods.rb +5 -3
  329. data/lib/rubocop/cop/style/colon_method_call.rb +18 -2
  330. data/lib/rubocop/cop/style/colon_method_definition.rb +36 -0
  331. data/lib/rubocop/cop/style/command_literal.rb +90 -30
  332. data/lib/rubocop/cop/style/comment_annotation.rb +39 -11
  333. data/lib/rubocop/cop/style/commented_keyword.rb +84 -0
  334. data/lib/rubocop/cop/style/conditional_assignment.rb +41 -41
  335. data/lib/rubocop/cop/style/copyright.rb +27 -28
  336. data/lib/rubocop/cop/style/date_time.rb +44 -0
  337. data/lib/rubocop/cop/style/def_with_parentheses.rb +31 -5
  338. data/lib/rubocop/cop/style/dir.rb +48 -0
  339. data/lib/rubocop/cop/style/documentation.rb +17 -2
  340. data/lib/rubocop/cop/style/documentation_method.rb +2 -6
  341. data/lib/rubocop/cop/style/double_negation.rb +1 -1
  342. data/lib/rubocop/cop/style/each_for_simple_loop.rb +8 -8
  343. data/lib/rubocop/cop/style/each_with_object.rb +6 -5
  344. data/lib/rubocop/cop/style/empty_block_parameter.rb +47 -0
  345. data/lib/rubocop/cop/style/empty_case_condition.rb +3 -3
  346. data/lib/rubocop/cop/style/empty_else.rb +55 -24
  347. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +43 -0
  348. data/lib/rubocop/cop/style/empty_literal.rb +25 -14
  349. data/lib/rubocop/cop/style/empty_method.rb +29 -25
  350. data/lib/rubocop/cop/style/encoding.rb +8 -51
  351. data/lib/rubocop/cop/style/end_block.rb +1 -1
  352. data/lib/rubocop/cop/style/eval_with_location.rb +146 -0
  353. data/lib/rubocop/cop/style/even_odd.rb +4 -2
  354. data/lib/rubocop/cop/style/extend_self.rb +92 -0
  355. data/lib/rubocop/cop/style/flip_flop.rb +13 -2
  356. data/lib/rubocop/cop/style/for.rb +6 -2
  357. data/lib/rubocop/cop/style/format_string.rb +33 -5
  358. data/lib/rubocop/cop/style/format_string_token.rb +17 -15
  359. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -6
  360. data/lib/rubocop/cop/style/global_vars.rb +12 -2
  361. data/lib/rubocop/cop/style/guard_clause.rb +6 -4
  362. data/lib/rubocop/cop/style/hash_syntax.rb +56 -56
  363. data/lib/rubocop/cop/style/identical_conditional_branches.rb +12 -8
  364. data/lib/rubocop/cop/style/if_inside_else.rb +11 -11
  365. data/lib/rubocop/cop/style/if_unless_modifier.rb +8 -7
  366. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +3 -2
  367. data/lib/rubocop/cop/style/if_with_semicolon.rb +10 -1
  368. data/lib/rubocop/cop/style/implicit_runtime_error.rb +7 -6
  369. data/lib/rubocop/cop/style/infinite_loop.rb +4 -4
  370. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  371. data/lib/rubocop/cop/style/inverse_methods.rb +24 -14
  372. data/lib/rubocop/cop/style/lambda.rb +45 -43
  373. data/lib/rubocop/cop/style/lambda_call.rb +37 -10
  374. data/lib/rubocop/cop/style/line_end_concatenation.rb +5 -5
  375. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +3 -19
  376. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +6 -4
  377. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +1 -1
  378. data/lib/rubocop/cop/style/method_def_parentheses.rb +20 -25
  379. data/lib/rubocop/cop/style/method_missing.rb +13 -26
  380. data/lib/rubocop/cop/style/min_max.rb +68 -0
  381. data/lib/rubocop/cop/style/missing_else.rb +20 -6
  382. data/lib/rubocop/cop/style/mixin_grouping.rb +31 -21
  383. data/lib/rubocop/cop/style/mixin_usage.rb +71 -0
  384. data/lib/rubocop/cop/style/module_function.rb +27 -11
  385. data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
  386. data/lib/rubocop/cop/style/multiline_if_modifier.rb +8 -4
  387. data/lib/rubocop/cop/style/multiline_if_then.rb +15 -13
  388. data/lib/rubocop/cop/style/multiline_memoization.rb +33 -17
  389. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
  390. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  391. data/lib/rubocop/cop/style/mutable_constant.rb +11 -15
  392. data/lib/rubocop/cop/style/negated_if.rb +27 -31
  393. data/lib/rubocop/cop/style/negated_while.rb +1 -5
  394. data/lib/rubocop/cop/style/nested_modifier.rb +1 -1
  395. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +26 -23
  396. data/lib/rubocop/cop/style/nested_ternary_operator.rb +1 -1
  397. data/lib/rubocop/cop/style/next.rb +41 -12
  398. data/lib/rubocop/cop/style/nil_comparison.rb +8 -8
  399. data/lib/rubocop/cop/style/non_nil_check.rb +41 -38
  400. data/lib/rubocop/cop/style/not.rb +15 -5
  401. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +8 -4
  402. data/lib/rubocop/cop/style/numeric_literals.rb +9 -9
  403. data/lib/rubocop/cop/style/numeric_predicate.rb +21 -21
  404. data/lib/rubocop/cop/style/one_line_conditional.rb +9 -4
  405. data/lib/rubocop/cop/style/option_hash.rb +11 -25
  406. data/lib/rubocop/cop/style/optional_arguments.rb +1 -2
  407. data/lib/rubocop/cop/style/or_assignment.rb +88 -0
  408. data/lib/rubocop/cop/style/parallel_assignment.rb +16 -16
  409. data/lib/rubocop/cop/style/parentheses_around_condition.rb +30 -13
  410. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +25 -4
  411. data/lib/rubocop/cop/style/percent_q_literals.rb +29 -8
  412. data/lib/rubocop/cop/style/perl_backrefs.rb +8 -1
  413. data/lib/rubocop/cop/style/preferred_hash_methods.rb +7 -11
  414. data/lib/rubocop/cop/style/proc.rb +10 -2
  415. data/lib/rubocop/cop/style/raise_args.rb +22 -29
  416. data/lib/rubocop/cop/style/random_with_offset.rb +160 -0
  417. data/lib/rubocop/cop/style/redundant_begin.rb +16 -5
  418. data/lib/rubocop/cop/style/redundant_conditional.rb +96 -0
  419. data/lib/rubocop/cop/style/redundant_exception.rb +4 -4
  420. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  421. data/lib/rubocop/cop/style/redundant_parentheses.rb +14 -12
  422. data/lib/rubocop/cop/style/redundant_return.rb +28 -15
  423. data/lib/rubocop/cop/style/redundant_self.rb +35 -27
  424. data/lib/rubocop/cop/style/regexp_literal.rb +88 -27
  425. data/lib/rubocop/cop/style/rescue_modifier.rb +12 -1
  426. data/lib/rubocop/cop/style/rescue_standard_error.rb +122 -0
  427. data/lib/rubocop/cop/style/return_nil.rb +89 -0
  428. data/lib/rubocop/cop/style/safe_navigation.rb +100 -48
  429. data/lib/rubocop/cop/style/self_assignment.rb +13 -13
  430. data/lib/rubocop/cop/style/semicolon.rb +19 -9
  431. data/lib/rubocop/cop/style/send.rb +10 -1
  432. data/lib/rubocop/cop/style/signal_exception.rb +104 -3
  433. data/lib/rubocop/cop/style/single_line_block_params.rb +16 -15
  434. data/lib/rubocop/cop/style/single_line_methods.rb +26 -18
  435. data/lib/rubocop/cop/style/special_global_vars.rb +19 -14
  436. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +23 -50
  437. data/lib/rubocop/cop/style/stderr_puts.rb +54 -0
  438. data/lib/rubocop/cop/style/string_hash_keys.rb +36 -0
  439. data/lib/rubocop/cop/style/string_literals.rb +26 -3
  440. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +16 -1
  441. data/lib/rubocop/cop/style/string_methods.rb +19 -8
  442. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  443. data/lib/rubocop/cop/style/symbol_array.rb +7 -35
  444. data/lib/rubocop/cop/style/symbol_literal.rb +1 -1
  445. data/lib/rubocop/cop/style/symbol_proc.rb +11 -25
  446. data/lib/rubocop/cop/style/ternary_parentheses.rb +46 -51
  447. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +101 -0
  448. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +20 -6
  449. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +22 -7
  450. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +95 -0
  451. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +70 -24
  452. data/lib/rubocop/cop/style/trivial_accessors.rb +72 -65
  453. data/lib/rubocop/cop/style/unless_else.rb +16 -1
  454. data/lib/rubocop/cop/style/unneeded_capital_w.rb +18 -8
  455. data/lib/rubocop/cop/style/unneeded_interpolation.rb +15 -19
  456. data/lib/rubocop/cop/style/unneeded_percent_q.rb +14 -13
  457. data/lib/rubocop/cop/style/variable_interpolation.rb +23 -9
  458. data/lib/rubocop/cop/style/when_then.rb +14 -1
  459. data/lib/rubocop/cop/style/while_until_do.rb +27 -4
  460. data/lib/rubocop/cop/style/while_until_modifier.rb +26 -6
  461. data/lib/rubocop/cop/style/word_array.rb +9 -30
  462. data/lib/rubocop/cop/style/yoda_condition.rb +51 -22
  463. data/lib/rubocop/cop/style/zero_length_predicate.rb +44 -29
  464. data/lib/rubocop/cop/team.rb +16 -8
  465. data/lib/rubocop/cop/util.rb +43 -34
  466. data/lib/rubocop/cop/variable_force.rb +1 -1
  467. data/lib/rubocop/cop/variable_force/assignment.rb +4 -2
  468. data/lib/rubocop/cop/variable_force/scope.rb +1 -5
  469. data/lib/rubocop/cop/variable_force/variable.rb +1 -1
  470. data/lib/rubocop/formatter/disabled_config_formatter.rb +3 -4
  471. data/lib/rubocop/formatter/formatter_set.rb +3 -1
  472. data/lib/rubocop/formatter/html_formatter.rb +1 -1
  473. data/lib/rubocop/formatter/json_formatter.rb +9 -3
  474. data/lib/rubocop/formatter/offense_count_formatter.rb +2 -0
  475. data/lib/rubocop/formatter/quiet_formatter.rb +13 -0
  476. data/lib/rubocop/formatter/simple_text_formatter.rb +3 -3
  477. data/lib/rubocop/formatter/tap_formatter.rb +71 -0
  478. data/lib/rubocop/formatter/worst_offenders_formatter.rb +2 -0
  479. data/lib/rubocop/node_pattern.rb +46 -29
  480. data/lib/rubocop/options.rb +13 -8
  481. data/lib/rubocop/path_util.rb +15 -3
  482. data/lib/rubocop/processed_source.rb +8 -9
  483. data/lib/rubocop/rake_task.rb +16 -23
  484. data/lib/rubocop/remote_config.rb +13 -1
  485. data/lib/rubocop/result_cache.rb +1 -0
  486. data/lib/rubocop/rspec/cop_helper.rb +10 -10
  487. data/lib/rubocop/rspec/expect_offense.rb +6 -8
  488. data/lib/rubocop/rspec/shared_contexts.rb +4 -8
  489. data/lib/rubocop/rspec/shared_examples.rb +8 -8
  490. data/lib/rubocop/rspec/support.rb +5 -5
  491. data/lib/rubocop/runner.rb +1 -1
  492. data/lib/rubocop/string_util.rb +2 -0
  493. data/lib/rubocop/token.rb +74 -0
  494. data/lib/rubocop/version.rb +1 -1
  495. metadata +118 -48
  496. data/lib/rubocop/cop/layout/space_inside_brackets.rb +0 -20
  497. data/lib/rubocop/cop/lint/invalid_character_literal.rb +0 -41
  498. data/lib/rubocop/cop/mixin/access_modifier_node.rb +0 -41
  499. data/lib/rubocop/cop/mixin/on_method_def.rb +0 -44
  500. data/lib/rubocop/cop/mixin/space_inside.rb +0 -76
  501. data/lib/rubocop/cop/style/accessor_method_name.rb +0 -45
  502. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +0 -29
  503. data/lib/rubocop/cop/style/constant_name.rb +0 -29
  504. data/lib/rubocop/cop/style/method_name.rb +0 -34
  505. data/lib/rubocop/cop/style/predicate_name.rb +0 -67
  506. data/lib/rubocop/cop/style/variable_name.rb +0 -39
@@ -17,7 +17,7 @@ module RuboCop
17
17
  MSG = '`allow_blank` is not a valid option, use `allow_nil`.'.freeze
18
18
 
19
19
  def_node_matcher :delegate_options, <<-PATTERN
20
- (send nil :delegate _ $hash)
20
+ (send nil? :delegate _ $hash)
21
21
  PATTERN
22
22
 
23
23
  def_node_matcher :allow_blank_option?, <<-PATTERN
@@ -29,17 +29,17 @@ module RuboCop
29
29
 
30
30
  return unless offending_node
31
31
 
32
- add_offense(offending_node, :expression)
32
+ add_offense(offending_node)
33
33
  end
34
34
 
35
- private
36
-
37
35
  def autocorrect(pair_node)
38
36
  lambda do |corrector|
39
37
  corrector.replace(pair_node.key.source_range, 'allow_nil')
40
38
  end
41
39
  end
42
40
 
41
+ private
42
+
43
43
  def allow_blank_option(node)
44
44
  delegate_options(node) do |hash|
45
45
  hash.pairs.find { |opt| allow_blank_option?(opt) }
@@ -38,8 +38,8 @@ module RuboCop
38
38
 
39
39
  return unless static_name
40
40
 
41
- add_offense(node, :expression,
42
- format(MSG, static_name, node.method_name))
41
+ add_offense(node,
42
+ message: format(MSG, static_name, node.method_name))
43
43
  end
44
44
 
45
45
  def autocorrect(node)
@@ -22,9 +22,9 @@ module RuboCop
22
22
 
23
23
  MSG = 'Duplicate value `%s` found in `%s` enum declaration.'.freeze
24
24
 
25
- def_node_matcher :enum_declaration, <<-END
26
- (send nil :enum (hash (pair (_ $_) ${array hash})))
27
- END
25
+ def_node_matcher :enum_declaration, <<-PATTERN
26
+ (send nil? :enum (hash (pair (_ $_) ${array hash})))
27
+ PATTERN
28
28
 
29
29
  def on_send(node)
30
30
  enum_declaration(node) do |name, args|
@@ -33,7 +33,7 @@ module RuboCop
33
33
  return unless duplicates?(items)
34
34
 
35
35
  consecutive_duplicates(items).each do |item|
36
- add_offense(item, :expression, format(MSG, item.source, name))
36
+ add_offense(item, message: format(MSG, item.source, name))
37
37
  end
38
38
  end
39
39
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop checks that Rails.env is compared using `.production?`-like
7
+ # methods instead of equality against a string or symbol.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # Rails.env == 'production'
12
+ #
13
+ # # bad, always returns false
14
+ # Rails.env == :test
15
+ #
16
+ # # good
17
+ # Rails.env.production?
18
+ class EnvironmentComparison < Cop
19
+ MSG = 'Favor `Rails.env.%s?` over `Rails.env == %s`.'.freeze
20
+
21
+ SYM_MSG = 'Do not compare `Rails.env` with a symbol, it will always ' \
22
+ 'evaluate to `false`.'.freeze
23
+
24
+ def_node_matcher :environment_str_comparison?, <<-PATTERN
25
+ (send
26
+ (send (const {nil? cbase} :Rails) :env)
27
+ :==
28
+ $str
29
+ )
30
+ PATTERN
31
+
32
+ def_node_matcher :environment_sym_comparison?, <<-PATTERN
33
+ (send
34
+ (send (const {nil? cbase} :Rails) :env)
35
+ :==
36
+ $sym
37
+ )
38
+ PATTERN
39
+
40
+ def on_send(node)
41
+ environment_str_comparison?(node) do |env_node|
42
+ env, = *env_node
43
+ add_offense(node, message: format(MSG, env, env_node.source))
44
+ end
45
+ environment_sym_comparison?(node) do |_|
46
+ add_offense(node, message: SYM_MSG)
47
+ end
48
+ end
49
+
50
+ def autocorrect(node)
51
+ lambda do |corrector|
52
+ corrector.replace(node.source_range, replacement(node))
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def replacement(node)
59
+ receiver, _, compared = *node
60
+ environment, = *compared
61
+ "#{receiver.source}.#{environment}?"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -16,6 +16,13 @@ module RuboCop
16
16
  # - Usage in application code outside of the web process could result in
17
17
  # the program exiting, which could result in the code failing to run and
18
18
  # do its job.
19
+ #
20
+ # @example
21
+ # # bad
22
+ # exit(0)
23
+ #
24
+ # # good
25
+ # raise 'a bad error has happened'
19
26
  class Exit < Cop
20
27
  include ConfigurableEnforcedStyle
21
28
 
@@ -24,7 +31,7 @@ module RuboCop
24
31
  EXPLICIT_RECEIVERS = %i[Kernel Process].freeze
25
32
 
26
33
  def on_send(node)
27
- add_offense(node, :selector) if offending_node?(node)
34
+ add_offense(node, location: :selector) if offending_node?(node)
28
35
  end
29
36
 
30
37
  private
@@ -18,15 +18,15 @@ module RuboCop
18
18
  MSG = 'Please use `Rails.root.join(\'path\', \'to\')` instead.'.freeze
19
19
 
20
20
  def_node_matcher :file_join_nodes?, <<-PATTERN
21
- (send (const nil :File) :join ...)
21
+ (send (const nil? :File) :join ...)
22
22
  PATTERN
23
23
 
24
24
  def_node_search :rails_root_nodes?, <<-PATTERN
25
- (send (const nil :Rails) :root)
25
+ (send (const nil? :Rails) :root)
26
26
  PATTERN
27
27
 
28
28
  def_node_matcher :rails_root_join_nodes?, <<-PATTERN
29
- (send (send (const nil :Rails) :root) :join ...)
29
+ (send (send (const nil? :Rails) :root) :join ...)
30
30
  PATTERN
31
31
 
32
32
  def on_dstr(node)
@@ -43,7 +43,7 @@ module RuboCop
43
43
 
44
44
  def check_for_file_join_with_rails_root(node)
45
45
  return unless file_join_nodes?(node)
46
- return unless node.method_args.any? { |e| rails_root_nodes?(e) }
46
+ return unless node.arguments.any? { |e| rails_root_nodes?(e) }
47
47
 
48
48
  register_offense(node)
49
49
  end
@@ -51,7 +51,7 @@ module RuboCop
51
51
  def check_for_rails_root_join_with_slash_separated_path(node)
52
52
  return unless rails_root_nodes?(node)
53
53
  return unless rails_root_join_nodes?(node)
54
- return unless node.method_args.any? { |arg| string_with_slash?(arg) }
54
+ return unless node.arguments.any? { |arg| string_with_slash?(arg) }
55
55
 
56
56
  register_offense(node)
57
57
  end
@@ -62,12 +62,9 @@ module RuboCop
62
62
 
63
63
  def register_offense(node)
64
64
  line_range = node.loc.column...node.loc.last_column
65
-
66
- add_offense(
67
- node,
68
- source_range(processed_source.buffer, node.loc.line, line_range),
69
- MSG
70
- )
65
+ source_range = source_range(processed_source.buffer, node.loc.line,
66
+ line_range)
67
+ add_offense(node, location: source_range)
71
68
  end
72
69
  end
73
70
  end
@@ -27,7 +27,8 @@ module RuboCop
27
27
  range = range_between(node.receiver.loc.selector.begin_pos,
28
28
  node.loc.selector.end_pos)
29
29
 
30
- add_offense(node, range, format(MSG, node.method_name))
30
+ add_offense(node, location: range,
31
+ message: format(MSG, node.method_name))
31
32
  end
32
33
 
33
34
  def autocorrect(node)
@@ -24,7 +24,7 @@ module RuboCop
24
24
  return unless SCOPE_METHODS.include?(node.receiver.method_name)
25
25
  return if method_chain(node).any? { |m| ignored_by_find_each?(m) }
26
26
 
27
- add_offense(node, node.loc.selector, MSG)
27
+ add_offense(node, location: :selector)
28
28
  end
29
29
 
30
30
  def autocorrect(node)
@@ -4,13 +4,20 @@ module RuboCop
4
4
  module Cop
5
5
  module Rails
6
6
  # This cop checks for the use of the has_and_belongs_to_many macro.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # # has_and_belongs_to_many :ingredients
11
+ #
12
+ # # good
13
+ # # has_many :ingredients, through: :recipe_ingredients
7
14
  class HasAndBelongsToMany < Cop
8
15
  MSG = 'Prefer `has_many :through` to `has_and_belongs_to_many`.'.freeze
9
16
 
10
17
  def on_send(node)
11
18
  return unless node.command?(:has_and_belongs_to_many)
12
19
 
13
- add_offense(node, :selector)
20
+ add_offense(node, location: :selector)
14
21
  end
15
22
  end
16
23
  end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop looks for `has_many` or `has_one` associations that don't
7
+ # specify a `:dependent` option.
8
+ # It doesn't register an offense if `:through` option was specified.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # class User < ActiveRecord::Base
13
+ # has_many :comments
14
+ # has_one :avatar
15
+ # end
16
+ #
17
+ # # good
18
+ # class User < ActiveRecord::Base
19
+ # has_many :comments, dependent: :restrict_with_exception
20
+ # has_one :avatar, dependent: :destroy
21
+ # has_many :patients, through: :appointments
22
+ # end
23
+ class HasManyOrHasOneDependent < Cop
24
+ MSG = 'Specify a `:dependent` option.'.freeze
25
+
26
+ def_node_matcher :association_without_options?, <<-PATTERN
27
+ (send nil? {:has_many :has_one} _)
28
+ PATTERN
29
+
30
+ def_node_matcher :association_with_options?, <<-PATTERN
31
+ (send nil? {:has_many :has_one} _ (hash $...))
32
+ PATTERN
33
+
34
+ def_node_matcher :dependent_option?, <<-PATTERN
35
+ (pair (sym :dependent) !nil)
36
+ PATTERN
37
+
38
+ def_node_matcher :present_option?, <<-PATTERN
39
+ (pair (sym :through) !nil)
40
+ PATTERN
41
+
42
+ def_node_matcher :with_options_block, <<-PATTERN
43
+ (block
44
+ (send nil? :with_options
45
+ (hash $...))
46
+ (args) ...)
47
+ PATTERN
48
+
49
+ def on_send(node)
50
+ if !association_without_options?(node)
51
+ return if valid_options?(association_with_options?(node))
52
+ else
53
+ n = node.parent.begin_type? ? node.parent.parent : node.parent
54
+
55
+ if with_options_block(n)
56
+ return if valid_options?(with_options_block(n))
57
+ end
58
+ end
59
+
60
+ add_offense(node, location: :selector)
61
+ end
62
+
63
+ private
64
+
65
+ def valid_options?(options)
66
+ return true unless options
67
+ return true if options.any? do |o|
68
+ dependent_option?(o) || present_option?(o)
69
+ end
70
+
71
+ false
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -6,7 +6,7 @@ module RuboCop
6
6
  # This cop is used to identify usages of http methods like `get`, `post`,
7
7
  # `put`, `patch` without the usage of keyword arguments in your tests and
8
8
  # change them to use keyword args. This cop only applies to Rails >= 5 .
9
- # If you are not running Rails < 5 you should disable # the
9
+ # If you are running Rails < 5 you should disable the
10
10
  # Rails/HttpPositionalArguments cop or set your TargetRailsVersion in your
11
11
  # .rubocop.yml file to 4.0, etc.
12
12
  #
@@ -28,52 +28,17 @@ module RuboCop
28
28
 
29
29
  minimum_target_rails_version 5.0
30
30
 
31
- def_node_matcher :http_request?, <<-END
32
- (send nil {#{HTTP_METHODS.map(&:inspect).join(' ')}} !nil $_data ...)
33
- END
31
+ def_node_matcher :http_request?, <<-PATTERN
32
+ (send nil? {#{HTTP_METHODS.map(&:inspect).join(' ')}} !nil? $_ ...)
33
+ PATTERN
34
34
 
35
35
  def on_send(node)
36
- data = http_request?(node)
37
- # if the data is nil then we don't need to add keyword arguments
38
- # because there is no data to put in params or headers, so skip
39
- return if data.nil?
40
- return unless needs_conversion?(data)
36
+ http_request?(node) do |data|
37
+ return unless needs_conversion?(data)
41
38
 
42
- add_offense(node, node.loc.selector, format(MSG, node.method_name))
43
- end
44
-
45
- # @return [Boolean] true if the line needs to be converted
46
- def needs_conversion?(data)
47
- return true unless data.hash_type?
48
- children = data.child_nodes
49
-
50
- value = children.find do |d|
51
- special_keyword_arg?(d.children.first) ||
52
- (format_arg?(d.children.first) && children.size == 1)
39
+ add_offense(node, location: :selector,
40
+ message: format(MSG, node.method_name))
53
41
  end
54
-
55
- value.nil?
56
- end
57
-
58
- def special_keyword_arg?(node)
59
- KEYWORD_ARGS.include?(node.children.first) if node.sym_type?
60
- end
61
-
62
- def format_arg?(node)
63
- node.children.first == :format if node.sym_type?
64
- end
65
-
66
- def convert_hash_data(data, type)
67
- # empty hash or no hash return empty string
68
- return '' if data.nil? || data.children.empty?
69
- hash_data = if data.hash_type?
70
- format('{ %s }', data.pairs.map(&:source).join(', '))
71
- else
72
- # user supplies an object,
73
- # no need to surround with braces
74
- data.source
75
- end
76
- format(', %s: %s', type, hash_data)
77
42
  end
78
43
 
79
44
  # given a pre Rails 5 method: get :new, user_id: @user.id, {}
@@ -81,7 +46,7 @@ module RuboCop
81
46
  # @return lambda of auto correct procedure
82
47
  # the result should look like:
83
48
  # get :new, params: { user_id: @user.id }, headers: {}
84
- # the http_method is the method use to call the controller
49
+ # the http_method is the method used to call the controller
85
50
  # the controller node can be a symbol, method, object or string
86
51
  # that represents the path/action on the Rails controller
87
52
  # the data is the http parameters and environment sent in
@@ -100,6 +65,37 @@ module RuboCop
100
65
  params, headers)
101
66
  ->(corrector) { corrector.replace(code_to_replace, new_code) }
102
67
  end
68
+
69
+ def needs_conversion?(data)
70
+ return true unless data.hash_type?
71
+
72
+ data.each_pair.none? do |pair|
73
+ special_keyword_arg?(pair.key) ||
74
+ format_arg?(pair.key) && data.pairs.one?
75
+ end
76
+ end
77
+
78
+ def special_keyword_arg?(node)
79
+ node.sym_type? && KEYWORD_ARGS.include?(node.value)
80
+ end
81
+
82
+ def format_arg?(node)
83
+ node.sym_type? && node.value == :format
84
+ end
85
+
86
+ def convert_hash_data(data, type)
87
+ return '' if data.hash_type? && data.empty?
88
+
89
+ hash_data = if data.hash_type?
90
+ format('{ %s }', data.pairs.map(&:source).join(', '))
91
+ else
92
+ # user supplies an object,
93
+ # no need to surround with braces
94
+ data.source
95
+ end
96
+
97
+ format(', %s: %s', type, hash_data)
98
+ end
103
99
  end
104
100
  end
105
101
  end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Rails
6
+ # This cop looks for has_(one|many) and belongs_to associations where
7
+ # ActiveRecord can't automatically determine the inverse association
8
+ # because of a scope or the options used. This can result in unnecessary
9
+ # queries in some circumstances. `:inverse_of` must be manually specified
10
+ # for associations to work in both ways, or set to `false` to opt-out.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # class Blog < ApplicationRecord
15
+ # has_many :recent_posts, -> { order(published_at: :desc) }
16
+ # end
17
+ #
18
+ # # good
19
+ # class Blog < ApplicationRecord
20
+ # has_many(:recent_posts,
21
+ # -> { order(published_at: :desc) },
22
+ # inverse_of: :blog
23
+ # )
24
+ # end
25
+ #
26
+ # @see http://guides.rubyonrails.org/association_basics.html#bi-directional-associations
27
+ # @see http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Setting+Inverses
28
+ class InverseOf < Cop
29
+ extend TargetRailsVersion
30
+
31
+ minimum_target_rails_version 4.1
32
+
33
+ MSG = 'Specify an `:inverse_of` option.'.freeze
34
+
35
+ def_node_matcher :association_arguments, <<-PATTERN
36
+ (send nil? {:has_many :has_one :belongs_to} _ $...)
37
+ PATTERN
38
+
39
+ def_node_matcher :options_from_argument, <<-PATTERN
40
+ (hash $...)
41
+ PATTERN
42
+
43
+ def_node_matcher :conditions_option?, <<-PATTERN
44
+ (pair (sym :conditions) !nil)
45
+ PATTERN
46
+
47
+ def_node_matcher :through_option?, <<-PATTERN
48
+ (pair (sym :through) !nil)
49
+ PATTERN
50
+
51
+ def_node_matcher :polymorphic_option?, <<-PATTERN
52
+ (pair (sym :polymorphic) !nil)
53
+ PATTERN
54
+
55
+ def_node_matcher :foreign_key_option?, <<-PATTERN
56
+ (pair (sym :foreign_key) !nil)
57
+ PATTERN
58
+
59
+ def_node_matcher :inverse_of_option?, <<-PATTERN
60
+ (pair (sym :inverse_of) !nil)
61
+ PATTERN
62
+
63
+ def on_send(node)
64
+ arguments = association_arguments(node)
65
+ return unless arguments
66
+
67
+ options = arguments.flat_map { |arg| options_from_argument(arg) }
68
+ return unless scope?(arguments) ||
69
+ options_requiring_inverse_of?(options)
70
+
71
+ return if options_contain_inverse_of?(options)
72
+ add_offense(node, location: :selector)
73
+ end
74
+
75
+ def scope?(arguments)
76
+ arguments.any?(&:block_type?)
77
+ end
78
+
79
+ def options_requiring_inverse_of?(options)
80
+ required = options.any? do |opt|
81
+ conditions_option?(opt) ||
82
+ through_option?(opt) ||
83
+ foreign_key_option?(opt)
84
+ end
85
+
86
+ return required if target_rails_version >= 5.2
87
+ required || options.any? { |opt| polymorphic_option?(opt) }
88
+ end
89
+
90
+ def options_contain_inverse_of?(options)
91
+ options.any? { |opt| inverse_of_option?(opt) }
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end