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,16 +17,16 @@ module RuboCop
17
17
  MSG = 'Do not specify cop behavior using `described_class::MSG`.'.freeze
18
18
 
19
19
  def_node_search :described_class_msg, <<-PATTERN
20
- (const (send nil :described_class) :MSG)
20
+ (const (send nil? :described_class) :MSG)
21
21
  PATTERN
22
22
 
23
23
  def_node_matcher :rspec_expectation_on_msg?, <<-PATTERN
24
- (send (send nil :expect #contains_described_class_msg?) :to ...)
24
+ (send (send nil? :expect #contains_described_class_msg?) :to ...)
25
25
  PATTERN
26
26
 
27
27
  def investigate(_processed_source)
28
28
  assertions_using_described_class_msg.each do |node|
29
- add_offense(node, :expression)
29
+ add_offense(node)
30
30
  end
31
31
  end
32
32
 
@@ -6,9 +6,7 @@ module RuboCop
6
6
  # Modifiers should be indented as deep as method definitions, or as deep
7
7
  # as the class/module keyword, depending on configuration.
8
8
  #
9
- # @example
10
- # # EnforcedStyle: indent (default)
11
- #
9
+ # @example EnforcedStyle: indent (default)
12
10
  # # bad
13
11
  # class Plumbus
14
12
  # private
@@ -21,8 +19,7 @@ module RuboCop
21
19
  # def smooth; end
22
20
  # end
23
21
  #
24
- # # EnforcedStyle: outdent
25
- #
22
+ # @example EnforcedStyle: outdent
26
23
  # # bad
27
24
  # class Plumbus
28
25
  # private
@@ -37,9 +34,8 @@ module RuboCop
37
34
  class AccessModifierIndentation < Cop
38
35
  include AutocorrectAlignment
39
36
  include ConfigurableEnforcedStyle
40
- include AccessModifierNode
41
37
 
42
- MSG = '%s access modifiers like `%s`.'.freeze
38
+ MSG = '%<style>s access modifiers like `%<node>s`.'.freeze
43
39
 
44
40
  def on_class(node)
45
41
  _name, _base_class, body = *node
@@ -67,7 +63,7 @@ module RuboCop
67
63
  def check_body(body, node)
68
64
  return if body.nil? # Empty class etc.
69
65
 
70
- modifiers = body.each_child_node.select { |c| modifier_node?(c) }
66
+ modifiers = body.each_child_node(:send).select(&:access_modifier?)
71
67
  class_column = node.source_range.column
72
68
 
73
69
  modifiers.each { |modifier| check_modifier(modifier, class_column) }
@@ -81,7 +77,7 @@ module RuboCop
81
77
  if @column_delta.zero?
82
78
  correct_style_detected
83
79
  else
84
- add_offense(send_node, :expression) do
80
+ add_offense(send_node) do
85
81
  if offset == unexpected_indent_offset
86
82
  opposite_style_detected
87
83
  else
@@ -92,7 +88,7 @@ module RuboCop
92
88
  end
93
89
 
94
90
  def message(node)
95
- format(MSG, style.capitalize, node.loc.selector.source)
91
+ format(MSG, style: style.capitalize, node: node.loc.selector.source)
96
92
  end
97
93
 
98
94
  def expected_indent_offset
@@ -8,14 +8,14 @@ module RuboCop
8
8
  #
9
9
  # @example
10
10
  # # bad
11
- # a = [1, 2, 3
11
+ # a = [1, 2, 3,
12
12
  # 4, 5, 6]
13
13
  # array = ['run',
14
14
  # 'forrest',
15
15
  # 'run']
16
16
  #
17
17
  # # good
18
- # a = [1, 2, 3
18
+ # a = [1, 2, 3,
19
19
  # 4, 5, 6]
20
20
  # a = ['run',
21
21
  # 'forrest',
@@ -116,7 +116,7 @@ module RuboCop
116
116
 
117
117
  def on_hash(node)
118
118
  return if ignored_node?(node)
119
- return if node.pairs.empty? || node.single_line?
119
+ return if node.empty? || node.single_line?
120
120
 
121
121
  return unless alignment_for_hash_rockets.checkable_layout?(node) &&
122
122
  alignment_for_colons.checkable_layout?(node)
@@ -124,6 +124,21 @@ module RuboCop
124
124
  check_pairs(node)
125
125
  end
126
126
 
127
+ def autocorrect(node)
128
+ # We can't use the instance variable inside the lambda. That would
129
+ # just give each lambda the same reference and they would all get the
130
+ # last value of each. A local variable fixes the problem.
131
+ key_delta = column_deltas[:key] || 0
132
+
133
+ if !node.value
134
+ correct_no_value(key_delta, node.source_range)
135
+ else
136
+ correct_key_value(key_delta, node.key.source_range,
137
+ node.value.source_range,
138
+ node.loc.operator)
139
+ end
140
+ end
141
+
127
142
  private
128
143
 
129
144
  attr_accessor :column_deltas
@@ -136,12 +151,12 @@ module RuboCop
136
151
  first_pair = node.pairs.first
137
152
  self.column_deltas = alignment_for(first_pair)
138
153
  .deltas_for_first_pair(first_pair, node)
139
- add_offense(first_pair, :expression) unless good_alignment?
154
+ add_offense(first_pair) unless good_alignment?
140
155
 
141
156
  node.children.each do |current|
142
157
  self.column_deltas = alignment_for(current)
143
158
  .deltas(first_pair, current)
144
- add_offense(current, :expression) unless good_alignment?
159
+ add_offense(current) unless good_alignment?
145
160
  end
146
161
  end
147
162
 
@@ -172,21 +187,6 @@ module RuboCop
172
187
  new_alignment('EnforcedColonStyle')
173
188
  end
174
189
 
175
- def autocorrect(node)
176
- # We can't use the instance variable inside the lambda. That would
177
- # just give each lambda the same reference and they would all get the
178
- # last value of each. A local variable fixes the problem.
179
- key_delta = column_deltas[:key] || 0
180
-
181
- if !node.value
182
- correct_no_value(key_delta, node.source_range)
183
- else
184
- correct_key_value(key_delta, node.key.source_range,
185
- node.value.source_range,
186
- node.loc.operator)
187
- end
188
- end
189
-
190
190
  def correct_no_value(key_delta, key)
191
191
  ->(corrector) { adjust(corrector, key_delta, key) }
192
192
  end
@@ -6,10 +6,7 @@ module RuboCop
6
6
  # Here we check if the parameters on a multi-line method call or
7
7
  # definition are aligned.
8
8
  #
9
- # @example
10
- #
11
- # # EnforcedStyle: with_first_parameter
12
- #
9
+ # @example EnforcedStyle: with_first_parameter (default)
13
10
  # # good
14
11
  #
15
12
  # foo :bar,
@@ -20,10 +17,7 @@ module RuboCop
20
17
  # foo :bar,
21
18
  # :baz
22
19
  #
23
- # @example
24
- #
25
- # # EnforcedStyle: with_fixed_indentation
26
- #
20
+ # @example EnforcedStyle: with_fixed_indentation
27
21
  # # good
28
22
  #
29
23
  # foo :bar,
@@ -35,37 +29,31 @@ module RuboCop
35
29
  # :baz
36
30
  class AlignParameters < Cop
37
31
  include AutocorrectAlignment
38
- include OnMethodDef
39
32
 
40
- ALIGN_PARAMS_MSG = 'Align the parameters of a method %s if they span ' \
41
- 'more than one line.'.freeze
33
+ ALIGN_PARAMS_MSG = 'Align the parameters of a method %<type>s if ' \
34
+ 'they span more than one line.'.freeze
42
35
 
43
36
  FIXED_INDENT_MSG = 'Use one level of indentation for parameters ' \
44
- 'following the first line of a multi-line method %s.'.freeze
37
+ 'following the first line of a multi-line method %<type>s.'.freeze
45
38
 
46
39
  def on_send(node)
47
- return if node.arguments.size < 2 || node.method?(:[]=)
40
+ return if node.arguments.size < 2 ||
41
+ node.send_type? && node.method?(:[]=)
48
42
 
49
43
  check_alignment(node.arguments, base_column(node, node.arguments))
50
44
  end
45
+ alias on_def on_send
46
+ alias on_defs on_send
51
47
 
52
- def on_method_def(node, _method_name, args, _body)
53
- args = args.children
54
-
55
- return if args.size < 2
56
-
57
- check_alignment(args, base_column(node, args))
58
- end
48
+ private
59
49
 
60
50
  def message(node)
61
51
  type = node && node.parent.send_type? ? 'call' : 'definition'
62
52
  msg = fixed_indentation? ? FIXED_INDENT_MSG : ALIGN_PARAMS_MSG
63
53
 
64
- format(msg, type)
54
+ format(msg, type: type)
65
55
  end
66
56
 
67
- private
68
-
69
57
  def fixed_indentation?
70
58
  cop_config['EnforcedStyle'] == 'with_fixed_indentation'
71
59
  end
@@ -25,7 +25,8 @@ module RuboCop
25
25
  # foo(i)
26
26
  # }
27
27
  class BlockEndNewline < Cop
28
- MSG = 'Expression at %d, %d should be on its own line.'.freeze
28
+ MSG = 'Expression at %<line>d, %<column>d should be on its own line.'
29
+ .freeze
29
30
 
30
31
  def on_block(node)
31
32
  return if node.single_line?
@@ -35,26 +36,39 @@ module RuboCop
35
36
  # If the end is on its own line, there is no offense
36
37
  return if end_loc.source_line =~ /^\s*#{end_loc.source}/
37
38
 
38
- add_offense(node, end_loc)
39
+ add_offense(node, location: end_loc)
39
40
  end
40
41
 
41
- private
42
-
43
42
  def autocorrect(node)
44
43
  lambda do |corrector|
45
44
  indentation = indentation_of_block_start_line(node)
46
- corrector.insert_before(node.loc.end, "\n" + (' ' * indentation))
45
+ new_block_end = "\n" + node.loc.end.source + (' ' * indentation)
46
+ corrector.replace(delimiter_range(node), new_block_end)
47
47
  end
48
48
  end
49
49
 
50
+ private
51
+
50
52
  def message(node)
51
- format(MSG, node.loc.end.line, node.loc.end.column + 1)
53
+ format(MSG, line: node.loc.end.line, column: node.loc.end.column + 1)
52
54
  end
53
55
 
54
56
  def indentation_of_block_start_line(node)
55
57
  match = /\S.*/.match(node.loc.begin.source_line)
56
58
  match.begin(0)
57
59
  end
60
+
61
+ def delimiter_range(node)
62
+ Parser::Source::Range.new(
63
+ node.loc.end.source_buffer,
64
+ index_of_delimiter_with_whitespaces(node),
65
+ node.source.length
66
+ )
67
+ end
68
+
69
+ def index_of_delimiter_with_whitespaces(node)
70
+ node.source =~ /\s*#{node.closing_delimiter}/
71
+ end
58
72
  end
59
73
  end
60
74
  end
@@ -30,13 +30,11 @@ module RuboCop
30
30
  # y / 3
31
31
  # end
32
32
  #
33
- # @example
33
+ # @example EnforcedStyle: case (default)
34
34
  # # if EndAlignment is set to other style such as
35
35
  # # start_of_line (as shown below), then *when* alignment
36
36
  # # configuration does have an effect.
37
37
  #
38
- # # EnforcedStyle: case (default)
39
- #
40
38
  # # bad
41
39
  # a = case n
42
40
  # when 0
@@ -53,8 +51,7 @@ module RuboCop
53
51
  # y / 3
54
52
  # end
55
53
  #
56
- # # EnforcedStyle: end
57
- #
54
+ # @example EnforcedStyle: end
58
55
  # # bad
59
56
  # a = case n
60
57
  # when 0
@@ -74,7 +71,7 @@ module RuboCop
74
71
  include AutocorrectAlignment
75
72
  include ConfigurableEnforcedStyle
76
73
 
77
- MSG = 'Indent `when` %s `%s`.'.freeze
74
+ MSG = 'Indent `when` %<depth>s `%<base>s`.'.freeze
78
75
 
79
76
  def on_case(case_node)
80
77
  return if case_node.single_line?
@@ -84,6 +81,16 @@ module RuboCop
84
81
  end
85
82
  end
86
83
 
84
+ def autocorrect(node)
85
+ whitespace = whitespace_range(node)
86
+
87
+ return false unless whitespace.source.strip.empty?
88
+
89
+ lambda do |corrector|
90
+ corrector.replace(whitespace, replacement(node))
91
+ end
92
+ end
93
+
87
94
  private
88
95
 
89
96
  def check_when(when_node)
@@ -109,7 +116,7 @@ module RuboCop
109
116
  when_column = when_node.loc.keyword.column
110
117
  base_column = base_column(when_node.parent, alternative_style)
111
118
 
112
- add_offense(when_node, :keyword, message(style)) do
119
+ add_offense(when_node, location: :keyword, message: message(style)) do
113
120
  if when_column == base_column
114
121
  opposite_style_detected
115
122
  else
@@ -121,7 +128,7 @@ module RuboCop
121
128
  def message(base)
122
129
  depth = indent_one_step? ? 'one step more than' : 'as deep as'
123
130
 
124
- format(MSG, depth, base)
131
+ format(MSG, depth: depth, base: base)
125
132
  end
126
133
 
127
134
  def base_column(case_node, base)
@@ -131,16 +138,6 @@ module RuboCop
131
138
  end
132
139
  end
133
140
 
134
- def autocorrect(node)
135
- whitespace = whitespace_range(node)
136
-
137
- return false unless whitespace.source.strip.empty?
138
-
139
- lambda do |corrector|
140
- corrector.replace(whitespace, replacement(node))
141
- end
142
- end
143
-
144
141
  def whitespace_range(node)
145
142
  when_column = node.location.keyword.column
146
143
  begin_pos = node.loc.keyword.begin_pos
@@ -0,0 +1,306 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Layout
6
+ # Checks if the code style follows the ExpectedOrder configuration:
7
+ #
8
+ # `Categories` allows us to map macro names into a category.
9
+ #
10
+ # Consider an example of code style that covers the following order:
11
+ # - Constants
12
+ # - Associations (has_one, has_many)
13
+ # - Attributes (attr_accessor, attr_writer, attr_reader)
14
+ # - Initializer
15
+ # - Instance methods
16
+ # - Protected methods
17
+ # - Private methods
18
+ #
19
+ # You can configure the following order:
20
+ #
21
+ # ```yaml
22
+ # Layout/ClassStructure:
23
+ # Categories:
24
+ # module_inclusion:
25
+ # - include
26
+ # - prepend
27
+ # - extend
28
+ # ExpectedOrder:
29
+ # - module_inclusion
30
+ # - constants
31
+ # - public_class_methods
32
+ # - initializer
33
+ # - public_methods
34
+ # - protected_methods
35
+ # - private_methods
36
+ #
37
+ # ```
38
+ # Instead of putting all literals in the expected order, is also
39
+ # possible to group categories of macros.
40
+ #
41
+ # ```yaml
42
+ # Layout/ClassStructure:
43
+ # Categories:
44
+ # association:
45
+ # - has_many
46
+ # - has_one
47
+ # attribute:
48
+ # - attr_accessor
49
+ # - attr_reader
50
+ # - attr_writer
51
+ # ```
52
+ #
53
+ # @example
54
+ # # bad
55
+ # # Expect extend be before constant
56
+ # class Person < ApplicationRecord
57
+ # has_many :orders
58
+ # ANSWER = 42
59
+ #
60
+ # extend SomeModule
61
+ # include AnotherModule
62
+ # end
63
+ #
64
+ # # good
65
+ # class Person
66
+ # # extend and include go first
67
+ # extend SomeModule
68
+ # include AnotherModule
69
+ #
70
+ # # inner classes
71
+ # CustomError = Class.new(StandardError)
72
+ #
73
+ # # constants are next
74
+ # SOME_CONSTANT = 20
75
+ #
76
+ # # afterwards we have attribute macros
77
+ # attr_reader :name
78
+ #
79
+ # # followed by other macros (if any)
80
+ # validates :name
81
+ #
82
+ # # public class methods are next in line
83
+ # def self.some_method
84
+ # end
85
+ #
86
+ # # initialization goes between class methods and instance methods
87
+ # def initialize
88
+ # end
89
+ #
90
+ # # followed by other public instance methods
91
+ # def some_method
92
+ # end
93
+ #
94
+ # # protected and private methods are grouped near the end
95
+ # protected
96
+ #
97
+ # def some_protected_method
98
+ # end
99
+ #
100
+ # private
101
+ #
102
+ # def some_private_method
103
+ # end
104
+ # end
105
+ #
106
+ # @see https://github.com/bbatsov/ruby-style-guide#consistent-classes
107
+ class ClassStructure < Cop
108
+ HUMANIZED_NODE_TYPE = {
109
+ casgn: :constants,
110
+ defs: :class_methods,
111
+ def: :public_methods
112
+ }.freeze
113
+
114
+ VISIBILITY_SCOPES = %i[private protected public].freeze
115
+ MSG = '`%s` is supposed to appear before `%s`.'.freeze
116
+
117
+ def_node_matcher :visibility_block?, <<-PATTERN
118
+ (send nil? { :private :protected :public })
119
+ PATTERN
120
+
121
+ # Validates code style on class declaration.
122
+ # Add offense when find a node out of expected order.
123
+ def on_class(class_node)
124
+ previous = -1
125
+ walk_over_nested_class_definition(class_node) do |node, category|
126
+ index = expected_order.index(category)
127
+ if index < previous
128
+ message = format(MSG, category, expected_order[previous])
129
+ add_offense(node, message: message)
130
+ end
131
+ previous = index
132
+ end
133
+ end
134
+
135
+ # Autocorrect by swapping between two nodes autocorrecting them
136
+ def autocorrect(node)
137
+ node_classification = classify(node)
138
+ previous = left_siblings_of(node).find do |sibling|
139
+ classification = classify(sibling)
140
+ !ignore?(classification) && node_classification != classification
141
+ end
142
+
143
+ current_range = source_range_with_comment(node)
144
+ previous_range = source_range_with_comment(previous)
145
+
146
+ lambda do |corrector|
147
+ corrector.insert_before(previous_range, current_range.source)
148
+ corrector.remove(current_range)
149
+ end
150
+ end
151
+
152
+ private
153
+
154
+ # Classifies a node to match with something in the {expected_order}
155
+ # @param node to be analysed
156
+ # @return String when the node type is a `:block` then
157
+ # {classify} recursively with the first children
158
+ # @return String when the node type is a `:send` then {find_category}
159
+ # by method name
160
+ # @return String otherwise trying to {humanize_node} of the current node
161
+ def classify(node)
162
+ return node.to_s unless node.respond_to?(:type)
163
+ case node.type
164
+ when :block
165
+ classify(node.send_node)
166
+ when :send
167
+ find_category(node.method_name)
168
+ else
169
+ humanize_node(node)
170
+ end.to_s
171
+ end
172
+
173
+ # Categorize a method_name according to the {expected_order}
174
+ # @param method_name try to match {categories} values
175
+ # @return [String] with the key category or the `method_name` as string
176
+ def find_category(method_name)
177
+ name = method_name.to_s
178
+ category, = categories.find { |_, names| names.include?(name) }
179
+ category || name
180
+ end
181
+
182
+ def walk_over_nested_class_definition(class_node)
183
+ class_elements(class_node).each do |node|
184
+ classification = classify(node)
185
+ next if ignore?(classification)
186
+ yield node, classification
187
+ end
188
+ end
189
+
190
+ def class_elements(class_node)
191
+ *, class_def = class_node.children
192
+ return [] unless class_def
193
+ if class_def.def_type? || class_def.send_type?
194
+ [class_def]
195
+ else
196
+ class_def.children.compact
197
+ end
198
+ end
199
+
200
+ def ignore?(classification)
201
+ classification.nil? ||
202
+ classification.to_s.end_with?('=') ||
203
+ expected_order.index(classification).nil?
204
+ end
205
+
206
+ def node_visibility(node)
207
+ _, method_name, = *find_visibility_start(node)
208
+ method_name || :public
209
+ end
210
+
211
+ def find_visibility_start(node)
212
+ left_siblings_of(node)
213
+ .reverse
214
+ .find(&method(:visibility_block?))
215
+ end
216
+
217
+ # Navigate to find the last protected method
218
+ def find_visibility_end(node)
219
+ possible_visibilities = VISIBILITY_SCOPES - [node_visibility(node)]
220
+ right = right_siblings_of(node)
221
+ right.find do |child_node|
222
+ possible_visibilities.include?(node_visibility(child_node))
223
+ end || right.last
224
+ end
225
+
226
+ def siblings_of(node)
227
+ node.parent.children
228
+ end
229
+
230
+ def right_siblings_of(node)
231
+ siblings_of(node)[node.sibling_index..-1]
232
+ end
233
+
234
+ def left_siblings_of(node)
235
+ siblings_of(node)[0, node.sibling_index]
236
+ end
237
+
238
+ def humanize_node(node)
239
+ method_name, = *node
240
+ if node.def_type?
241
+ return :initializer if method_name == :initialize
242
+ return "#{node_visibility(node)}_methods"
243
+ end
244
+ HUMANIZED_NODE_TYPE[node.type] || node.type
245
+ end
246
+
247
+ def source_range_with_comment(node)
248
+ begin_pos, end_pos =
249
+ if node.def_type?
250
+ start_node = find_visibility_start(node) || node
251
+ end_node = find_visibility_end(node) || node
252
+ [begin_pos_with_comment(start_node),
253
+ end_position_for(end_node) + 1]
254
+ else
255
+ [begin_pos_with_comment(node), end_position_for(node)]
256
+ end
257
+
258
+ Parser::Source::Range.new(buffer, begin_pos, end_pos)
259
+ end
260
+
261
+ def end_position_for(node)
262
+ end_line = buffer.line_for_position(node.loc.expression.end_pos)
263
+ buffer.line_range(end_line).end_pos
264
+ end
265
+
266
+ def begin_pos_with_comment(node)
267
+ annotation_line = node.loc.line - 1
268
+ first_comment = nil
269
+
270
+ comments_before_line(annotation_line).reverse_each do |comment|
271
+ if comment.location.line == annotation_line
272
+ first_comment = comment
273
+ annotation_line -= 1
274
+ end
275
+ end
276
+
277
+ start_line_position(first_comment || node)
278
+ end
279
+
280
+ def start_line_position(node)
281
+ buffer.line_range(node.loc.line).begin_pos - 1
282
+ end
283
+
284
+ def comments_before_line(line)
285
+ processed_source.comments.select { |c| c.location.line <= line }
286
+ end
287
+
288
+ def buffer
289
+ processed_source.buffer
290
+ end
291
+
292
+ # Load expected order from `ExpectedOrder` config.
293
+ # Define new terms in the expected order by adding new {categories}.
294
+ def expected_order
295
+ cop_config['ExpectedOrder']
296
+ end
297
+
298
+ # Setting categories hash allow you to group methods in group to match
299
+ # in the {expected_order}.
300
+ def categories
301
+ cop_config['Categories']
302
+ end
303
+ end
304
+ end
305
+ end
306
+ end