rubocop 0.52.1 → 0.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (292) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.txt +1 -1
  3. data/README.md +2 -2
  4. data/config/default.yml +118 -46
  5. data/config/disabled.yml +8 -8
  6. data/config/enabled.yml +84 -28
  7. data/lib/rubocop.rb +28 -8
  8. data/lib/rubocop/ast/builder.rb +35 -37
  9. data/lib/rubocop/ast/node.rb +16 -1
  10. data/lib/rubocop/ast/node/and_node.rb +0 -8
  11. data/lib/rubocop/ast/node/block_node.rb +1 -9
  12. data/lib/rubocop/ast/node/case_node.rb +0 -8
  13. data/lib/rubocop/ast/node/ensure_node.rb +0 -8
  14. data/lib/rubocop/ast/node/for_node.rb +0 -8
  15. data/lib/rubocop/ast/node/or_node.rb +0 -8
  16. data/lib/rubocop/ast/node/pair_node.rb +0 -8
  17. data/lib/rubocop/ast/node/resbody_node.rb +0 -8
  18. data/lib/rubocop/ast/node/send_node.rb +0 -8
  19. data/lib/rubocop/ast/node/symbol_node.rb +0 -8
  20. data/lib/rubocop/ast/node/until_node.rb +0 -8
  21. data/lib/rubocop/ast/node/when_node.rb +0 -8
  22. data/lib/rubocop/ast/node/while_node.rb +0 -8
  23. data/lib/rubocop/cli.rb +17 -7
  24. data/lib/rubocop/comment_config.rb +24 -3
  25. data/lib/rubocop/config.rb +75 -6
  26. data/lib/rubocop/config_loader.rb +18 -28
  27. data/lib/rubocop/config_loader_resolver.rb +61 -9
  28. data/lib/rubocop/cop/bundler/duplicated_gem.rb +3 -1
  29. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +4 -2
  30. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  31. data/lib/rubocop/cop/commissioner.rb +2 -2
  32. data/lib/rubocop/cop/cop.rb +4 -0
  33. data/lib/rubocop/cop/corrector.rb +11 -1
  34. data/lib/rubocop/cop/correctors/alignment_corrector.rb +3 -6
  35. data/lib/rubocop/cop/correctors/line_break_corrector.rb +59 -0
  36. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +1 -1
  37. data/lib/rubocop/cop/correctors/space_corrector.rb +13 -0
  38. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +1 -1
  39. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +3 -1
  40. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  41. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -5
  42. data/lib/rubocop/cop/generator.rb +29 -8
  43. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +2 -0
  44. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -0
  45. data/lib/rubocop/cop/layout/align_hash.rb +106 -37
  46. data/lib/rubocop/cop/{lint → layout}/block_alignment.rb +8 -5
  47. data/lib/rubocop/cop/layout/block_end_newline.rb +7 -17
  48. data/lib/rubocop/cop/layout/case_indentation.rb +1 -0
  49. data/lib/rubocop/cop/layout/class_structure.rb +6 -7
  50. data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
  51. data/lib/rubocop/cop/{lint → layout}/condition_position.rb +3 -3
  52. data/lib/rubocop/cop/{lint → layout}/def_end_alignment.rb +2 -1
  53. data/lib/rubocop/cop/layout/else_alignment.rb +1 -1
  54. data/lib/rubocop/cop/layout/empty_comment.rb +140 -0
  55. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -0
  56. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +2 -0
  57. data/lib/rubocop/cop/layout/empty_lines.rb +3 -1
  58. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +7 -5
  59. data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +20 -10
  60. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +20 -0
  61. data/lib/rubocop/cop/{lint → layout}/end_alignment.rb +37 -6
  62. data/lib/rubocop/cop/layout/end_of_line.rb +1 -0
  63. data/lib/rubocop/cop/layout/extra_spacing.rb +30 -37
  64. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -0
  65. data/lib/rubocop/cop/layout/indent_heredoc.rb +38 -2
  66. data/lib/rubocop/cop/layout/indentation_consistency.rb +105 -1
  67. data/lib/rubocop/cop/layout/indentation_width.rb +4 -3
  68. data/lib/rubocop/cop/layout/initial_indentation.rb +15 -1
  69. data/lib/rubocop/cop/layout/leading_comment_space.rb +4 -2
  70. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -0
  71. data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
  72. data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +62 -29
  73. data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
  74. data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +74 -33
  75. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +16 -2
  76. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -1
  77. data/lib/rubocop/cop/layout/space_after_method_name.rb +2 -0
  78. data/lib/rubocop/cop/layout/space_after_not.rb +2 -0
  79. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -0
  80. data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +15 -2
  81. data/lib/rubocop/cop/layout/space_around_operators.rb +15 -13
  82. data/lib/rubocop/cop/layout/space_before_block_braces.rb +13 -1
  83. data/lib/rubocop/cop/layout/space_before_comment.rb +6 -4
  84. data/lib/rubocop/cop/layout/space_before_first_arg.rb +1 -0
  85. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +1 -0
  86. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +30 -45
  87. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +3 -2
  88. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +48 -18
  89. data/lib/rubocop/cop/layout/space_inside_parens.rb +8 -7
  90. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +57 -11
  91. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +1 -0
  92. data/lib/rubocop/cop/layout/tab.rb +42 -16
  93. data/lib/rubocop/cop/layout/trailing_blank_lines.rb +46 -13
  94. data/lib/rubocop/cop/layout/trailing_whitespace.rb +12 -0
  95. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +5 -3
  96. data/lib/rubocop/cop/lint/big_decimal_new.rb +44 -0
  97. data/lib/rubocop/cop/lint/boolean_symbol.rb +2 -2
  98. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -2
  99. data/lib/rubocop/cop/lint/debugger.rb +2 -2
  100. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +5 -4
  101. data/lib/rubocop/cop/lint/duplicate_methods.rb +20 -9
  102. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +4 -3
  103. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +16 -10
  104. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +5 -4
  105. data/lib/rubocop/cop/lint/inherit_exception.rb +2 -2
  106. data/lib/rubocop/cop/lint/interpolation_check.rb +4 -3
  107. data/lib/rubocop/cop/lint/literal_as_condition.rb +2 -2
  108. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +2 -0
  109. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +7 -5
  110. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  111. data/lib/rubocop/cop/lint/number_conversion.rb +59 -0
  112. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +86 -0
  113. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +2 -0
  114. data/lib/rubocop/cop/lint/percent_string_array.rb +0 -2
  115. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  116. data/lib/rubocop/cop/lint/redundant_with_index.rb +2 -0
  117. data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -0
  118. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -0
  119. data/lib/rubocop/cop/lint/rescue_type.rb +6 -3
  120. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -2
  121. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -21
  122. data/lib/rubocop/cop/lint/script_permission.rb +30 -10
  123. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  124. data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -0
  125. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  126. data/lib/rubocop/cop/lint/unified_integer.rb +2 -2
  127. data/lib/rubocop/cop/lint/{unneeded_disable.rb → unneeded_cop_disable_directive.rb} +13 -7
  128. data/lib/rubocop/cop/lint/unneeded_cop_enable_directive.rb +97 -0
  129. data/lib/rubocop/cop/lint/unneeded_require_statement.rb +1 -0
  130. data/lib/rubocop/cop/lint/unreachable_code.rb +3 -3
  131. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +11 -10
  132. data/lib/rubocop/cop/lint/useless_access_modifier.rb +7 -5
  133. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -2
  134. data/lib/rubocop/cop/lint/useless_setter_call.rb +2 -2
  135. data/lib/rubocop/cop/lint/void.rb +49 -10
  136. data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
  137. data/lib/rubocop/cop/metrics/line_length.rb +5 -2
  138. data/lib/rubocop/cop/mixin/alignment.rb +4 -0
  139. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -1
  140. data/lib/rubocop/cop/mixin/def_node.rb +4 -0
  141. data/lib/rubocop/cop/mixin/documentation_comment.rb +11 -3
  142. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -2
  143. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +20 -1
  144. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +4 -0
  145. data/lib/rubocop/cop/mixin/hash_alignment.rb +2 -2
  146. data/lib/rubocop/cop/mixin/match_range.rb +2 -0
  147. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +6 -0
  148. data/lib/rubocop/cop/mixin/nil_methods.rb +19 -0
  149. data/lib/rubocop/cop/mixin/percent_literal.rb +57 -9
  150. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +6 -5
  151. data/lib/rubocop/cop/mixin/range_help.rb +102 -0
  152. data/lib/rubocop/cop/mixin/rescue_node.rb +1 -1
  153. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +8 -7
  154. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +11 -9
  155. data/lib/rubocop/cop/mixin/statement_modifier.rb +3 -10
  156. data/lib/rubocop/cop/mixin/surrounding_space.rb +38 -8
  157. data/lib/rubocop/cop/mixin/trailing_body.rb +26 -0
  158. data/lib/rubocop/cop/mixin/trailing_comma.rb +15 -3
  159. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +104 -0
  160. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -1
  161. data/lib/rubocop/cop/naming/file_name.rb +5 -10
  162. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +76 -0
  163. data/lib/rubocop/cop/naming/uncommunicative_block_param_name.rb +48 -0
  164. data/lib/rubocop/cop/naming/uncommunicative_method_param_name.rb +57 -0
  165. data/lib/rubocop/cop/offense.rb +3 -2
  166. data/lib/rubocop/cop/performance/case_when_splat.rb +1 -0
  167. data/lib/rubocop/cop/performance/casecmp.rb +17 -8
  168. data/lib/rubocop/cop/performance/compare_with_block.rb +2 -0
  169. data/lib/rubocop/cop/performance/count.rb +1 -0
  170. data/lib/rubocop/cop/performance/fixed_size.rb +41 -0
  171. data/lib/rubocop/cop/performance/flat_map.rb +2 -0
  172. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +2 -0
  173. data/lib/rubocop/cop/performance/redundant_merge.rb +1 -1
  174. data/lib/rubocop/cop/performance/redundant_sort_by.rb +2 -0
  175. data/lib/rubocop/cop/performance/regexp_match.rb +4 -0
  176. data/lib/rubocop/cop/performance/reverse_each.rb +2 -0
  177. data/lib/rubocop/cop/performance/string_replacement.rb +2 -0
  178. data/lib/rubocop/cop/rails/active_record_aliases.rb +46 -0
  179. data/lib/rubocop/cop/rails/blank.rb +3 -3
  180. data/lib/rubocop/cop/rails/create_table_with_timestamps.rb +6 -0
  181. data/lib/rubocop/cop/rails/delegate.rb +6 -6
  182. data/lib/rubocop/cop/rails/file_path.rb +7 -1
  183. data/lib/rubocop/cop/rails/find_by.rb +2 -0
  184. data/lib/rubocop/cop/rails/http_positional_arguments.rb +17 -5
  185. data/lib/rubocop/cop/rails/inverse_of.rb +21 -2
  186. data/lib/rubocop/cop/rails/lexically_scoped_action_filter.rb +45 -9
  187. data/lib/rubocop/cop/rails/presence.rb +8 -2
  188. data/lib/rubocop/cop/rails/present.rb +5 -5
  189. data/lib/rubocop/cop/rails/read_write_attribute.rb +4 -3
  190. data/lib/rubocop/cop/rails/redundant_receiver_in_with_options.rb +1 -0
  191. data/lib/rubocop/cop/rails/relative_date_constant.rb +4 -3
  192. data/lib/rubocop/cop/rails/request_referer.rb +3 -2
  193. data/lib/rubocop/cop/rails/reversible_migration.rb +9 -8
  194. data/lib/rubocop/cop/rails/safe_navigation.rb +3 -2
  195. data/lib/rubocop/cop/rails/save_bang.rb +11 -12
  196. data/lib/rubocop/cop/rails/skips_model_validations.rb +2 -2
  197. data/lib/rubocop/cop/rails/time_zone.rb +38 -16
  198. data/lib/rubocop/cop/rails/uniq_before_pluck.rb +26 -16
  199. data/lib/rubocop/cop/rails/validation.rb +30 -2
  200. data/lib/rubocop/cop/security/open.rb +48 -0
  201. data/lib/rubocop/cop/style/and_or.rb +1 -0
  202. data/lib/rubocop/cop/style/ascii_comments.rb +3 -1
  203. data/lib/rubocop/cop/style/attr.rb +2 -0
  204. data/lib/rubocop/cop/style/block_comments.rb +3 -1
  205. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +2 -5
  206. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -0
  207. data/lib/rubocop/cop/style/class_vars.rb +23 -0
  208. data/lib/rubocop/cop/style/colon_method_call.rb +1 -2
  209. data/lib/rubocop/cop/style/comment_annotation.rb +6 -4
  210. data/lib/rubocop/cop/style/commented_keyword.rb +3 -1
  211. data/lib/rubocop/cop/style/conditional_assignment.rb +1 -1
  212. data/lib/rubocop/cop/style/copyright.rb +3 -1
  213. data/lib/rubocop/cop/style/each_with_object.rb +15 -1
  214. data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -0
  215. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -0
  216. data/lib/rubocop/cop/style/empty_else.rb +9 -5
  217. data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -0
  218. data/lib/rubocop/cop/style/empty_line_after_guard_clause.rb +80 -0
  219. data/lib/rubocop/cop/style/empty_literal.rb +1 -0
  220. data/lib/rubocop/cop/style/encoding.rb +2 -0
  221. data/lib/rubocop/cop/style/expand_path_arguments.rb +194 -0
  222. data/lib/rubocop/cop/style/for.rb +33 -0
  223. data/lib/rubocop/cop/style/format_string.rb +1 -1
  224. data/lib/rubocop/cop/style/format_string_token.rb +4 -5
  225. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
  226. data/lib/rubocop/cop/style/hash_syntax.rb +1 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +1 -1
  228. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  229. data/lib/rubocop/cop/style/lambda.rb +1 -1
  230. data/lib/rubocop/cop/style/line_end_concatenation.rb +2 -0
  231. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -0
  232. data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -0
  233. data/lib/rubocop/cop/style/missing_else.rb +72 -7
  234. data/lib/rubocop/cop/style/mixin_usage.rb +3 -5
  235. data/lib/rubocop/cop/style/module_function.rb +10 -0
  236. data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -0
  237. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  238. data/lib/rubocop/cop/style/nested_modifier.rb +2 -0
  239. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -0
  240. data/lib/rubocop/cop/style/next.rb +1 -0
  241. data/lib/rubocop/cop/style/not.rb +2 -0
  242. data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
  243. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -2
  244. data/lib/rubocop/cop/style/redundant_exception.rb +8 -3
  245. data/lib/rubocop/cop/style/redundant_return.rb +37 -3
  246. data/lib/rubocop/cop/style/redundant_self.rb +1 -1
  247. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -0
  248. data/lib/rubocop/cop/style/safe_navigation.rb +74 -32
  249. data/lib/rubocop/cop/style/semicolon.rb +3 -1
  250. data/lib/rubocop/cop/style/single_line_methods.rb +14 -23
  251. data/lib/rubocop/cop/style/stderr_puts.rb +2 -0
  252. data/lib/rubocop/cop/style/string_hash_keys.rb +12 -0
  253. data/lib/rubocop/cop/style/string_literals.rb +1 -1
  254. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +1 -1
  255. data/lib/rubocop/cop/style/symbol_array.rb +29 -0
  256. data/lib/rubocop/cop/style/symbol_proc.rb +2 -0
  257. data/lib/rubocop/cop/style/trailing_body_on_class.rb +43 -0
  258. data/lib/rubocop/cop/style/trailing_body_on_method_definition.rb +7 -54
  259. data/lib/rubocop/cop/style/trailing_body_on_module.rb +43 -0
  260. data/lib/rubocop/cop/style/{trailing_comma_in_literal.rb → trailing_comma_in_array_literal.rb} +2 -20
  261. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +56 -0
  262. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +17 -20
  263. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -0
  264. data/lib/rubocop/cop/style/unless_else.rb +2 -0
  265. data/lib/rubocop/cop/style/word_array.rb +0 -1
  266. data/lib/rubocop/cop/style/yoda_condition.rb +1 -0
  267. data/lib/rubocop/cop/team.rb +5 -5
  268. data/lib/rubocop/cop/util.rb +23 -188
  269. data/lib/rubocop/cop/variable_force.rb +1 -1
  270. data/lib/rubocop/file_finder.rb +45 -0
  271. data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -14
  272. data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
  273. data/lib/rubocop/formatter/html_formatter.rb +12 -5
  274. data/lib/rubocop/formatter/json_formatter.rb +1 -1
  275. data/lib/rubocop/node_pattern.rb +8 -5
  276. data/lib/rubocop/options.rb +40 -33
  277. data/lib/rubocop/path_util.rb +5 -8
  278. data/lib/rubocop/processed_source.rb +53 -0
  279. data/lib/rubocop/remote_config.rb +1 -1
  280. data/lib/rubocop/result_cache.rb +1 -1
  281. data/lib/rubocop/rspec/cop_helper.rb +0 -4
  282. data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -4
  283. data/lib/rubocop/rspec/shared_contexts.rb +3 -1
  284. data/lib/rubocop/rspec/shared_examples.rb +23 -25
  285. data/lib/rubocop/rspec/support.rb +5 -0
  286. data/lib/rubocop/runner.rb +3 -2
  287. data/lib/rubocop/string_util.rb +10 -9
  288. data/lib/rubocop/target_finder.rb +4 -1
  289. data/lib/rubocop/token.rb +26 -16
  290. data/lib/rubocop/version.rb +6 -4
  291. metadata +31 -17
  292. data/lib/rubocop/cop/performance/hash_each_methods.rb +0 -129
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for trailing code after the module definition.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # module Foo extend self
11
+ # end
12
+ #
13
+ # # good
14
+ # module Foo
15
+ # extend self
16
+ # end
17
+ #
18
+ class TrailingBodyOnModule < Cop
19
+ include Alignment
20
+ include TrailingBody
21
+
22
+ MSG = 'Place the first line of module body on its own line.'.freeze
23
+
24
+ def on_module(node)
25
+ return unless trailing_body?(node)
26
+
27
+ add_offense(node, location: first_part_of(node.to_a.last))
28
+ end
29
+
30
+ def autocorrect(node)
31
+ lambda do |corrector|
32
+ LineBreakCorrector.correct_trailing_body(
33
+ configured_width: configured_indentation_width,
34
+ corrector: corrector,
35
+ node: node,
36
+ processed_source: processed_source
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- # This cop checks for trailing comma in array and hash literals.
6
+ # This cop checks for trailing comma in array literals.
7
7
  #
8
8
  # @example EnforcedStyleForMultiline: consistent_comma
9
9
  # # bad
@@ -40,8 +40,7 @@ module RuboCop
40
40
  # 1,
41
41
  # 2
42
42
  # ]
43
- class TrailingCommaInLiteral < Cop
44
- include ArraySyntax
43
+ class TrailingCommaInArrayLiteral < Cop
45
44
  include TrailingComma
46
45
 
47
46
  def on_array(node)
@@ -49,26 +48,9 @@ module RuboCop
49
48
  check_literal(node, 'item of %<article>s array')
50
49
  end
51
50
 
52
- def on_hash(node)
53
- check_literal(node, 'item of %<article>s hash')
54
- end
55
-
56
51
  def autocorrect(range)
57
52
  PunctuationCorrector.swap_comma(range)
58
53
  end
59
-
60
- private
61
-
62
- def check_literal(node, kind)
63
- return if node.children.empty?
64
- # A braceless hash is the last parameter of a method call and will be
65
- # checked as such.
66
- return unless brackets?(node)
67
-
68
- check(node, node.children, kind,
69
- node.children.last.source_range.end_pos,
70
- node.loc.end.begin_pos)
71
- end
72
54
  end
73
55
  end
74
56
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for trailing comma in hash literals.
7
+ #
8
+ # @example EnforcedStyleForMultiline: consistent_comma
9
+ # # bad
10
+ # a = { foo: 1, bar: 2, }
11
+ #
12
+ # # good
13
+ # a = {
14
+ # foo: 1, bar: 2,
15
+ # qux: 3,
16
+ # }
17
+ #
18
+ # # good
19
+ # a = {
20
+ # foo: 1,
21
+ # bar: 2,
22
+ # }
23
+ #
24
+ # @example EnforcedStyleForMultiline: comma
25
+ # # bad
26
+ # a = { foo: 1, bar: 2, }
27
+ #
28
+ # # good
29
+ # a = {
30
+ # foo: 1,
31
+ # bar: 2,
32
+ # }
33
+ #
34
+ # @example EnforcedStyleForMultiline: no_comma (default)
35
+ # # bad
36
+ # a = { foo: 1, bar: 2, }
37
+ #
38
+ # # good
39
+ # a = {
40
+ # foo: 1,
41
+ # bar: 2
42
+ # }
43
+ class TrailingCommaInHashLiteral < Cop
44
+ include TrailingComma
45
+
46
+ def on_hash(node)
47
+ check_literal(node, 'item of %<article>s hash')
48
+ end
49
+
50
+ def autocorrect(range)
51
+ PunctuationCorrector.swap_comma(range)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -42,13 +42,13 @@ module RuboCop
42
42
  def on_def(node)
43
43
  return unless trailing_end?(node)
44
44
 
45
- add_offense(node.to_a.last, location: end_token.pos)
45
+ add_offense(node.to_a.last, location: end_token(node).pos)
46
46
  end
47
47
 
48
- def autocorrect(_node)
48
+ def autocorrect(node)
49
49
  lambda do |corrector|
50
- break_line_before_end(corrector)
51
- remove_semicolon(corrector)
50
+ break_line_before_end(node, corrector)
51
+ remove_semicolon(node, corrector)
52
52
  end
53
53
  end
54
54
 
@@ -57,37 +57,34 @@ module RuboCop
57
57
  def trailing_end?(node)
58
58
  node.body &&
59
59
  node.multiline? &&
60
- end_token &&
61
- body_and_end_on_same_line?
60
+ body_and_end_on_same_line?(node)
62
61
  end
63
62
 
64
- def end_token
65
- @end_token ||= processed_source.tokens.reverse.find do |token|
66
- token.type == :kEND
67
- end
63
+ def end_token(node)
64
+ @end_token ||= tokens(node).reverse.find(&:end?)
68
65
  end
69
66
 
70
- def body_and_end_on_same_line?
71
- end_token.line == token_before_end.line
67
+ def body_and_end_on_same_line?(node)
68
+ end_token(node).line == token_before_end(node).line
72
69
  end
73
70
 
74
- def token_before_end
71
+ def token_before_end(node)
75
72
  @token_before_end ||= begin
76
- i = processed_source.tokens.index(end_token)
77
- processed_source.tokens[i - 1]
73
+ i = tokens(node).index(end_token(node))
74
+ tokens(node)[i - 1]
78
75
  end
79
76
  end
80
77
 
81
- def break_line_before_end(corrector)
78
+ def break_line_before_end(node, corrector)
82
79
  corrector.insert_before(
83
- end_token.pos,
80
+ end_token(node).pos,
84
81
  "\n" + ' ' * configured_indentation_width
85
82
  )
86
83
  end
87
84
 
88
- def remove_semicolon(corrector)
89
- return unless token_before_end.semicolon?
90
- corrector.remove(token_before_end.pos)
85
+ def remove_semicolon(node, corrector)
86
+ return unless token_before_end(node).semicolon?
87
+ corrector.remove(token_before_end(node).pos)
91
88
  end
92
89
  end
93
90
  end
@@ -24,6 +24,7 @@ module RuboCop
24
24
  # a, b, _something = foo()
25
25
  class TrailingUnderscoreVariable < Cop
26
26
  include SurroundingSpace
27
+ include RangeHelp
27
28
 
28
29
  MSG = 'Do not use trailing `_`s in parallel assignment. ' \
29
30
  'Prefer `%<code>s`.'.freeze
@@ -20,6 +20,8 @@ module RuboCop
20
20
  # # do a different thing...
21
21
  # end
22
22
  class UnlessElse < Cop
23
+ include RangeHelp
24
+
23
25
  MSG = 'Do not use `unless` with `else`. Rewrite these with the ' \
24
26
  'positive case first.'.freeze
25
27
 
@@ -36,7 +36,6 @@ module RuboCop
36
36
 
37
37
  PERCENT_MSG = 'Use `%w` or `%W` for an array of words.'.freeze
38
38
  ARRAY_MSG = 'Use `[]` for an array of words.'.freeze
39
- QUESTION_MARK_SIZE = '?'.size
40
39
 
41
40
  class << self
42
41
  attr_accessor :largest_brackets
@@ -30,6 +30,7 @@ module RuboCop
30
30
  # 3 < a && a < 5
31
31
  class YodaCondition < Cop
32
32
  include ConfigurableEnforcedStyle
33
+ include RangeHelp
33
34
 
34
35
  MSG = 'Reverse the order of the operands `%<source>s`.'.freeze
35
36
 
@@ -164,21 +164,21 @@ module RuboCop
164
164
  end
165
165
  end
166
166
 
167
- def handle_warning(e, location)
168
- message = Rainbow("#{e.message} (from file: #{location})").yellow
167
+ def handle_warning(error, location)
168
+ message = Rainbow("#{error.message} (from file: #{location})").yellow
169
169
 
170
170
  @warnings << message
171
171
  warn message
172
- puts e.backtrace if debug?
172
+ puts error.backtrace if debug?
173
173
  end
174
174
 
175
- def handle_error(e, location, cop)
175
+ def handle_error(error, location, cop)
176
176
  message = Rainbow("An error occurred while #{cop.name}" \
177
177
  " cop was inspecting #{location}.").red
178
178
  @errors << message
179
179
  warn message
180
180
  if debug?
181
- puts e.message, e.backtrace
181
+ puts error.message, error.backtrace
182
182
  else
183
183
  warn 'To see the complete backtrace run rubocop -d.'
184
184
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # rubocop:disable Metrics/ModuleLength
4
3
  module RuboCop
5
4
  module Cop
6
5
  # This module contains a collection of useful utility methods.
@@ -8,8 +7,6 @@ module RuboCop
8
7
  include PathUtil
9
8
  extend RuboCop::AST::Sexp
10
9
 
11
- BYTE_ORDER_MARK = 0xfeff # The Unicode codepoint
12
-
13
10
  EQUALS_ASGN_NODES = %i[lvasgn ivasgn cvasgn gvasgn
14
11
  casgn masgn].freeze
15
12
  SHORTHAND_ASGN_NODES = %i[op_asgn or_asgn and_asgn].freeze
@@ -36,33 +33,12 @@ module RuboCop
36
33
  OPERATOR_METHODS.include?(symbol)
37
34
  end
38
35
 
39
- def strip_quotes(str)
40
- if str[0] == '"' || str[0] == "'"
41
- str[0] = ''
42
- else
43
- # we're dealing with %q or %Q
44
- str[0, 3] = ''
45
- end
46
- str[-1] = ''
47
-
48
- str
49
- end
50
-
51
36
  def comment_line?(line_source)
52
37
  line_source =~ /^\s*#/
53
38
  end
54
39
 
55
- def line_range(arg)
56
- source_range = case arg
57
- when Parser::Source::Range
58
- arg
59
- when Parser::AST::Node
60
- arg.source_range
61
- else
62
- raise ArgumentError, "Invalid argument #{arg}"
63
- end
64
-
65
- source_range.begin.line..source_range.end.line
40
+ def line_range(node)
41
+ node.first_line..node.last_line
66
42
  end
67
43
 
68
44
  def parentheses?(node)
@@ -70,10 +46,6 @@ module RuboCop
70
46
  node.loc.end.is?(')'.freeze)
71
47
  end
72
48
 
73
- def parenthesized_call?(send)
74
- send.loc.begin && send.loc.begin.is?('(')
75
- end
76
-
77
49
  def on_node(syms, sexp, excludes = [], &block)
78
50
  return to_enum(:on_node, syms, sexp, excludes) unless block_given?
79
51
 
@@ -83,106 +55,10 @@ module RuboCop
83
55
  sexp.each_child_node { |elem| on_node(syms, elem, excludes, &block) }
84
56
  end
85
57
 
86
- def source_range(source_buffer, line_number, column, length = 1)
87
- if column.is_a?(Range)
88
- column_index = column.begin
89
- length = column.size
90
- else
91
- column_index = column
92
- end
93
-
94
- line_begin_pos = if line_number.zero?
95
- 0
96
- else
97
- source_buffer.line_range(line_number).begin_pos
98
- end
99
- begin_pos = line_begin_pos + column_index
100
- end_pos = begin_pos + length
101
-
102
- Parser::Source::Range.new(source_buffer, begin_pos, end_pos)
103
- end
104
-
105
- # Returns the column attribute of the range, except if the range is on
106
- # the first line and there's a byte order mark at the beginning of that
107
- # line, in which case 1 is subtracted from the column value. This gives
108
- # the column as it appears when viewing the file in an editor.
109
- def effective_column(range)
110
- if range.line == 1 &&
111
- @processed_source.raw_source.codepoints.first == BYTE_ORDER_MARK
112
- range.column - 1
113
- else
114
- range.column
115
- end
116
- end
117
-
118
- def range_between(start_pos, end_pos)
119
- Parser::Source::Range.new(processed_source.buffer, start_pos, end_pos)
120
- end
121
-
122
- def range_with_surrounding_comma(range, side = :both)
123
- buffer = @processed_source.buffer
124
- src = buffer.source
125
-
126
- go_left, go_right = directions(side)
127
-
128
- begin_pos = range.begin_pos
129
- end_pos = range.end_pos
130
- begin_pos = move_pos(src, begin_pos, -1, go_left, /,/)
131
- end_pos = move_pos(src, end_pos, 1, go_right, /,/)
132
-
133
- Parser::Source::Range.new(buffer, begin_pos, end_pos)
134
- end
135
-
136
- def range_with_surrounding_space(range:,
137
- side: :both,
138
- newlines: true,
139
- whitespace: false)
140
- buffer = @processed_source.buffer
141
- src = buffer.source
142
-
143
- go_left, go_right = directions(side)
144
-
145
- begin_pos = range.begin_pos
146
- if go_left
147
- begin_pos =
148
- final_pos(src, begin_pos, -1, newlines, whitespace)
149
- end
150
- end_pos = range.end_pos
151
- end_pos = final_pos(src, end_pos, 1, newlines, whitespace) if go_right
152
- Parser::Source::Range.new(buffer, begin_pos, end_pos)
153
- end
154
-
155
- def range_by_whole_lines(range, include_final_newline: false)
156
- buffer = @processed_source.buffer
157
-
158
- begin_pos = range.begin_pos
159
- begin_offset = range.column
160
- begin_of_first_line = begin_pos - begin_offset
161
-
162
- last_line = buffer.source_line(range.last_line)
163
- end_pos = range.end_pos
164
- end_offset = last_line.length - range.last_column
165
- end_offset += 1 if include_final_newline
166
- end_of_last_line = end_pos + end_offset
167
-
168
- Parser::Source::Range.new(buffer, begin_of_first_line, end_of_last_line)
169
- end
170
-
171
58
  def begins_its_line?(range)
172
59
  (range.source_line =~ /\S/) == range.column
173
60
  end
174
61
 
175
- def ends_its_line?(range)
176
- line = range.source_buffer.source_line(range.last_line)
177
- (line =~ /\s*\z/) == range.last_column
178
- end
179
-
180
- def within_node?(inner, outer)
181
- o = outer.is_a?(AST::Node) ? outer.source_range : outer
182
- i = inner.is_a?(AST::Node) ? inner.source_range : inner
183
- i.begin_pos >= o.begin_pos && i.end_pos <= o.end_pos
184
- end
185
-
186
62
  # Returns, for example, a bare `if` node if the given node is an `if`
187
63
  # with calls chained to the end of it.
188
64
  def first_part_of_call_chain(node)
@@ -229,51 +105,14 @@ module RuboCop
229
105
  end
230
106
  end
231
107
 
232
- def to_symbol_literal(string)
233
- if symbol_without_quote?(string)
234
- ":#{string}"
235
- else
236
- ":#{to_string_literal(string)}"
237
- end
238
- end
239
-
240
- def symbol_without_quote?(string)
241
- special_gvars = %w[
242
- $! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
243
- $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
244
- ]
245
- redefinable_operators = %w(
246
- | ^ & <=> == === =~ > >= < <= << >>
247
- + - * / % ** ~ +@ -@ [] []= ` ! != !~
248
- )
249
-
250
- # method name
251
- string =~ /\A[a-zA-Z_]\w*[!?]?\z/ ||
252
- # instance / class variable
253
- string =~ /\A\@\@?[a-zA-Z_]\w*\z/ ||
254
- # global variable
255
- string =~ /\A\$[1-9]\d*\z/ ||
256
- string =~ /\A\$[a-zA-Z_]\w*\z/ ||
257
- special_gvars.include?(string) ||
258
- redefinable_operators.include?(string)
259
- end
260
-
261
108
  def interpret_string_escapes(string)
262
109
  StringInterpreter.interpret(string)
263
110
  end
264
111
 
265
- def same_line?(n1, n2)
266
- n1.respond_to?(:loc) &&
267
- n2.respond_to?(:loc) &&
268
- n1.loc.line == n2.loc.line
269
- end
270
-
271
- def precede?(n1, n2)
272
- line_distance(n1, n2) == 1
273
- end
274
-
275
- def stripped_source_upto(line)
276
- processed_source[0..line].map(&:strip)
112
+ def same_line?(node1, node2)
113
+ node1.respond_to?(:loc) &&
114
+ node2.respond_to?(:loc) &&
115
+ node1.loc.line == node2.loc.line
277
116
  end
278
117
 
279
118
  def to_supported_styles(enforced_style)
@@ -282,37 +121,33 @@ module RuboCop
282
121
  .sub('Style', 'Styles')
283
122
  end
284
123
 
285
- private
124
+ def tokens(node) # rubocop:disable Metrics/AbcSize
125
+ @tokens ||= {}
126
+ return @tokens[node.object_id] if @tokens[node.object_id]
286
127
 
287
- def directions(side)
288
- if side == :both
289
- [true, true]
290
- else
291
- [side == :left, side == :right]
128
+ source_range = node.source_range
129
+ begin_pos = source_range.begin_pos
130
+ end_pos = source_range.end_pos
131
+
132
+ tokens_to_node_end = processed_source.tokens.take_while do |token|
133
+ token.end_pos <= end_pos
292
134
  end
293
- end
294
135
 
295
- def final_pos(src, pos, increment, newlines, whitespace)
296
- pos = move_pos(src, pos, increment, true, /[ \t]/)
297
- pos = move_pos(src, pos, increment, newlines, /\n/)
298
- move_pos(src, pos, increment, whitespace, /\s/)
299
- end
136
+ node_tokens = []
137
+ tokens_to_node_end.reverse_each do |token|
138
+ break unless token.begin_pos >= begin_pos
139
+ node_tokens.unshift(token)
140
+ end
300
141
 
301
- def move_pos(src, pos, step, condition, regexp)
302
- offset = step == -1 ? -1 : 0
303
- pos += step while condition && src[pos + offset] =~ regexp
304
- pos < 0 ? 0 : pos
142
+ @tokens[node.object_id] = node_tokens
305
143
  end
306
144
 
145
+ private
146
+
307
147
  def compatible_external_encoding_for?(src)
308
148
  src = src.dup if RUBY_VERSION < '2.3' || RUBY_ENGINE == 'jruby'
309
149
  src.force_encoding(Encoding.default_external).valid_encoding?
310
150
  end
311
-
312
- def line_distance(n1, n2)
313
- n2.loc.line - n1.loc.line
314
- end
315
151
  end
316
152
  end
317
153
  end
318
- # rubocop:enable Metrics/ModuleLength