rubocop 0.35.1 → 0.36.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (385) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +164 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +72 -21
  5. data/bin/rubocop +1 -0
  6. data/config/default.yml +167 -18
  7. data/config/disabled.yml +19 -6
  8. data/config/enabled.yml +159 -14
  9. data/lib/rubocop.rb +67 -26
  10. data/lib/rubocop/ast_node.rb +488 -14
  11. data/lib/rubocop/ast_node/builder.rb +24 -0
  12. data/lib/rubocop/ast_node/sexp.rb +13 -0
  13. data/lib/rubocop/cached_data.rb +58 -0
  14. data/lib/rubocop/cli.rb +47 -10
  15. data/lib/rubocop/comment_config.rb +9 -2
  16. data/lib/rubocop/config.rb +99 -31
  17. data/lib/rubocop/config_loader.rb +23 -14
  18. data/lib/rubocop/config_store.rb +1 -0
  19. data/lib/rubocop/cop/autocorrect_logic.rb +2 -1
  20. data/lib/rubocop/cop/commissioner.rb +3 -5
  21. data/lib/rubocop/cop/cop.rb +23 -17
  22. data/lib/rubocop/cop/corrector.rb +25 -0
  23. data/lib/rubocop/cop/force.rb +1 -0
  24. data/lib/rubocop/cop/ignored_node.rb +3 -2
  25. data/lib/rubocop/cop/lint/ambiguous_operator.rb +2 -1
  26. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +2 -1
  27. data/lib/rubocop/cop/lint/assignment_in_condition.rb +4 -3
  28. data/lib/rubocop/cop/lint/block_alignment.rb +29 -91
  29. data/lib/rubocop/cop/lint/circular_argument_reference.rb +2 -1
  30. data/lib/rubocop/cop/lint/condition_position.rb +2 -1
  31. data/lib/rubocop/cop/lint/debugger.rb +29 -12
  32. data/lib/rubocop/cop/lint/def_end_alignment.rb +16 -18
  33. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +6 -6
  34. data/lib/rubocop/cop/lint/duplicate_methods.rb +98 -74
  35. data/lib/rubocop/cop/lint/duplicated_key.rb +3 -2
  36. data/lib/rubocop/cop/lint/each_with_object_argument.rb +3 -2
  37. data/lib/rubocop/cop/lint/else_layout.rb +2 -1
  38. data/lib/rubocop/cop/lint/empty_ensure.rb +2 -1
  39. data/lib/rubocop/cop/lint/empty_interpolation.rb +2 -1
  40. data/lib/rubocop/cop/lint/end_alignment.rb +77 -39
  41. data/lib/rubocop/cop/lint/end_in_method.rb +2 -1
  42. data/lib/rubocop/cop/lint/ensure_return.rb +2 -1
  43. data/lib/rubocop/cop/lint/eval.rb +2 -1
  44. data/lib/rubocop/cop/lint/float_out_of_range.rb +31 -0
  45. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +14 -30
  46. data/lib/rubocop/cop/lint/handle_exceptions.rb +2 -1
  47. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +85 -0
  48. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +120 -0
  49. data/lib/rubocop/cop/lint/invalid_character_literal.rb +3 -1
  50. data/lib/rubocop/cop/lint/literal_in_condition.rb +6 -9
  51. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +6 -9
  52. data/lib/rubocop/cop/lint/loop.rb +2 -1
  53. data/lib/rubocop/cop/lint/nested_method_definition.rb +19 -3
  54. data/lib/rubocop/cop/lint/next_without_accumulator.rb +38 -0
  55. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +5 -8
  56. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +8 -6
  57. data/lib/rubocop/cop/lint/rand_one.rb +36 -0
  58. data/lib/rubocop/cop/lint/require_parentheses.rb +6 -5
  59. data/lib/rubocop/cop/lint/rescue_exception.rb +3 -2
  60. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -1
  61. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -4
  62. data/lib/rubocop/cop/lint/syntax.rb +9 -5
  63. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +3 -2
  64. data/lib/rubocop/cop/lint/unneeded_disable.rb +121 -18
  65. data/lib/rubocop/cop/lint/unreachable_code.rb +5 -4
  66. data/lib/rubocop/cop/lint/unused_block_argument.rb +9 -7
  67. data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
  68. data/lib/rubocop/cop/lint/useless_access_modifier.rb +56 -29
  69. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -16
  70. data/lib/rubocop/cop/lint/useless_comparison.rb +3 -2
  71. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +2 -1
  72. data/lib/rubocop/cop/lint/useless_setter_call.rb +14 -20
  73. data/lib/rubocop/cop/lint/void.rb +10 -11
  74. data/lib/rubocop/cop/metrics/abc_size.rb +3 -1
  75. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -1
  76. data/lib/rubocop/cop/metrics/class_length.rb +1 -0
  77. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +4 -2
  78. data/lib/rubocop/cop/metrics/line_length.rb +35 -13
  79. data/lib/rubocop/cop/metrics/method_length.rb +2 -1
  80. data/lib/rubocop/cop/metrics/module_length.rb +1 -0
  81. data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -1
  82. data/lib/rubocop/cop/metrics/perceived_complexity.rb +4 -2
  83. data/lib/rubocop/cop/mixin/access_modifier_node.rb +3 -10
  84. data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -0
  85. data/lib/rubocop/cop/mixin/array_hash_indentation.rb +80 -0
  86. data/lib/rubocop/cop/mixin/array_syntax.rb +2 -1
  87. data/lib/rubocop/cop/mixin/autocorrect_alignment.rb +14 -20
  88. data/lib/rubocop/cop/mixin/autocorrect_unless_changing_ast.rb +5 -4
  89. data/lib/rubocop/cop/mixin/check_assignment.rb +20 -15
  90. data/lib/rubocop/cop/mixin/classish_length.rb +1 -0
  91. data/lib/rubocop/cop/mixin/code_length.rb +1 -0
  92. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +17 -15
  93. data/lib/rubocop/cop/mixin/configurable_max.rb +1 -0
  94. data/lib/rubocop/cop/mixin/configurable_naming.rb +4 -0
  95. data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +9 -4
  96. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +24 -16
  97. data/lib/rubocop/cop/mixin/first_element_line_break.rb +3 -2
  98. data/lib/rubocop/cop/mixin/hash_node.rb +15 -0
  99. data/lib/rubocop/cop/mixin/if_node.rb +1 -0
  100. data/lib/rubocop/cop/mixin/method_complexity.rb +1 -0
  101. data/lib/rubocop/cop/mixin/method_preference.rb +1 -0
  102. data/lib/rubocop/cop/mixin/min_body_length.rb +1 -0
  103. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +177 -0
  104. data/lib/rubocop/cop/mixin/negative_conditional.rb +1 -0
  105. data/lib/rubocop/cop/mixin/on_method_def.rb +6 -5
  106. data/lib/rubocop/cop/mixin/on_normal_if_unless.rb +1 -0
  107. data/lib/rubocop/cop/mixin/parentheses.rb +22 -0
  108. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -0
  109. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -0
  110. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +79 -0
  111. data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -0
  112. data/lib/rubocop/cop/mixin/space_after_punctuation.rb +2 -1
  113. data/lib/rubocop/cop/mixin/space_before_punctuation.rb +2 -1
  114. data/lib/rubocop/cop/mixin/space_inside.rb +2 -1
  115. data/lib/rubocop/cop/mixin/statement_modifier.rb +6 -5
  116. data/lib/rubocop/cop/mixin/string_help.rb +2 -9
  117. data/lib/rubocop/cop/mixin/string_literals_help.rb +13 -7
  118. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -2
  119. data/lib/rubocop/cop/mixin/trailing_comma.rb +134 -0
  120. data/lib/rubocop/cop/mixin/unused_argument.rb +1 -0
  121. data/lib/rubocop/cop/offense.rb +19 -14
  122. data/lib/rubocop/cop/performance/case_when_splat.rb +8 -8
  123. data/lib/rubocop/cop/performance/casecmp.rb +54 -0
  124. data/lib/rubocop/cop/performance/count.rb +10 -9
  125. data/lib/rubocop/cop/performance/detect.rb +6 -5
  126. data/lib/rubocop/cop/performance/double_start_end_with.rb +65 -0
  127. data/lib/rubocop/cop/performance/end_with.rb +55 -0
  128. data/lib/rubocop/cop/performance/fixed_size.rb +1 -0
  129. data/lib/rubocop/cop/performance/flat_map.rb +9 -8
  130. data/lib/rubocop/cop/performance/hash_each.rb +86 -0
  131. data/lib/rubocop/cop/performance/lstrip_rstrip.rb +44 -0
  132. data/lib/rubocop/cop/performance/range_include.rb +40 -0
  133. data/lib/rubocop/cop/performance/redundant_block_call.rb +57 -0
  134. data/lib/rubocop/cop/performance/redundant_match.rb +51 -0
  135. data/lib/rubocop/cop/performance/redundant_merge.rb +85 -0
  136. data/lib/rubocop/cop/performance/redundant_sort_by.rb +45 -0
  137. data/lib/rubocop/cop/performance/reverse_each.rb +3 -2
  138. data/lib/rubocop/cop/performance/sample.rb +6 -5
  139. data/lib/rubocop/cop/performance/size.rb +2 -1
  140. data/lib/rubocop/cop/performance/start_with.rb +58 -0
  141. data/lib/rubocop/cop/performance/string_replacement.rb +18 -23
  142. data/lib/rubocop/cop/performance/times_map.rb +49 -0
  143. data/lib/rubocop/cop/rails/action_filter.rb +4 -3
  144. data/lib/rubocop/cop/rails/date.rb +5 -4
  145. data/lib/rubocop/cop/rails/delegate.rb +3 -2
  146. data/lib/rubocop/cop/rails/find_by.rb +20 -14
  147. data/lib/rubocop/cop/rails/find_each.rb +23 -2
  148. data/lib/rubocop/cop/rails/has_and_belongs_to_many.rb +3 -2
  149. data/lib/rubocop/cop/rails/output.rb +4 -2
  150. data/lib/rubocop/cop/rails/pluralization_grammar.rb +3 -2
  151. data/lib/rubocop/cop/rails/read_write_attribute.rb +5 -7
  152. data/lib/rubocop/cop/rails/scope_args.rb +3 -2
  153. data/lib/rubocop/cop/rails/time_zone.rb +14 -10
  154. data/lib/rubocop/cop/rails/validation.rb +4 -3
  155. data/lib/rubocop/cop/severity.rb +8 -7
  156. data/lib/rubocop/cop/style/access_modifier_indentation.rb +5 -4
  157. data/lib/rubocop/cop/style/accessor_method_name.rb +1 -0
  158. data/lib/rubocop/cop/style/alias.rb +84 -24
  159. data/lib/rubocop/cop/style/align_array.rb +2 -1
  160. data/lib/rubocop/cop/style/align_hash.rb +13 -14
  161. data/lib/rubocop/cop/style/align_parameters.rb +3 -2
  162. data/lib/rubocop/cop/style/and_or.rb +9 -7
  163. data/lib/rubocop/cop/style/array_join.rb +5 -5
  164. data/lib/rubocop/cop/style/ascii_comments.rb +2 -1
  165. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -1
  166. data/lib/rubocop/cop/style/attr.rb +30 -5
  167. data/lib/rubocop/cop/style/auto_resource_cleanup.rb +3 -3
  168. data/lib/rubocop/cop/style/bare_percent_literals.rb +2 -1
  169. data/lib/rubocop/cop/style/begin_block.rb +2 -1
  170. data/lib/rubocop/cop/style/block_comments.rb +2 -1
  171. data/lib/rubocop/cop/style/block_delimiters.rb +10 -9
  172. data/lib/rubocop/cop/style/block_end_newline.rb +3 -2
  173. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +9 -8
  174. data/lib/rubocop/cop/style/case_equality.rb +2 -1
  175. data/lib/rubocop/cop/style/case_indentation.rb +2 -1
  176. data/lib/rubocop/cop/style/character_literal.rb +11 -7
  177. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +2 -1
  178. data/lib/rubocop/cop/style/class_and_module_children.rb +3 -2
  179. data/lib/rubocop/cop/style/class_check.rb +2 -1
  180. data/lib/rubocop/cop/style/class_methods.rb +2 -1
  181. data/lib/rubocop/cop/style/class_vars.rb +2 -1
  182. data/lib/rubocop/cop/style/closing_parenthesis_indentation.rb +3 -2
  183. data/lib/rubocop/cop/style/collection_methods.rb +2 -1
  184. data/lib/rubocop/cop/style/colon_method_call.rb +3 -2
  185. data/lib/rubocop/cop/style/command_literal.rb +8 -7
  186. data/lib/rubocop/cop/style/comment_annotation.rb +3 -2
  187. data/lib/rubocop/cop/style/comment_indentation.rb +4 -6
  188. data/lib/rubocop/cop/style/conditional_assignment.rb +362 -0
  189. data/lib/rubocop/cop/style/constant_name.rb +2 -1
  190. data/lib/rubocop/cop/style/copyright.rb +7 -6
  191. data/lib/rubocop/cop/style/def_with_parentheses.rb +2 -1
  192. data/lib/rubocop/cop/style/deprecated_hash_methods.rb +3 -2
  193. data/lib/rubocop/cop/style/documentation.rb +7 -11
  194. data/lib/rubocop/cop/style/dot_position.rb +3 -2
  195. data/lib/rubocop/cop/style/double_negation.rb +2 -1
  196. data/lib/rubocop/cop/style/each_with_object.rb +4 -3
  197. data/lib/rubocop/cop/style/else_alignment.rb +3 -2
  198. data/lib/rubocop/cop/style/empty_else.rb +4 -3
  199. data/lib/rubocop/cop/style/empty_line_between_defs.rb +2 -1
  200. data/lib/rubocop/cop/style/empty_lines.rb +10 -4
  201. data/lib/rubocop/cop/style/empty_lines_around_access_modifier.rb +13 -5
  202. data/lib/rubocop/cop/style/empty_lines_around_block_body.rb +7 -3
  203. data/lib/rubocop/cop/style/empty_lines_around_class_body.rb +6 -3
  204. data/lib/rubocop/cop/style/empty_lines_around_method_body.rb +4 -3
  205. data/lib/rubocop/cop/style/empty_lines_around_module_body.rb +4 -2
  206. data/lib/rubocop/cop/style/empty_literal.rb +20 -5
  207. data/lib/rubocop/cop/style/encoding.rb +8 -11
  208. data/lib/rubocop/cop/style/end_block.rb +3 -1
  209. data/lib/rubocop/cop/style/end_of_line.rb +2 -1
  210. data/lib/rubocop/cop/style/even_odd.rb +4 -3
  211. data/lib/rubocop/cop/style/extra_spacing.rb +110 -74
  212. data/lib/rubocop/cop/style/file_name.rb +103 -6
  213. data/lib/rubocop/cop/style/first_array_element_line_break.rb +3 -2
  214. data/lib/rubocop/cop/style/first_hash_element_line_break.rb +5 -6
  215. data/lib/rubocop/cop/style/first_method_argument_line_break.rb +14 -1
  216. data/lib/rubocop/cop/style/first_method_parameter_line_break.rb +2 -1
  217. data/lib/rubocop/cop/style/first_parameter_indentation.rb +6 -4
  218. data/lib/rubocop/cop/style/flip_flop.rb +2 -1
  219. data/lib/rubocop/cop/style/for.rb +2 -1
  220. data/lib/rubocop/cop/style/format_string.rb +1 -0
  221. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +89 -0
  222. data/lib/rubocop/cop/style/global_vars.rb +2 -1
  223. data/lib/rubocop/cop/style/guard_clause.rb +63 -11
  224. data/lib/rubocop/cop/style/hash_syntax.rb +10 -10
  225. data/lib/rubocop/cop/style/identical_conditional_branches.rb +93 -0
  226. data/lib/rubocop/cop/style/if_inside_else.rb +49 -0
  227. data/lib/rubocop/cop/style/if_unless_modifier.rb +6 -5
  228. data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -1
  229. data/lib/rubocop/cop/style/indent_array.rb +89 -38
  230. data/lib/rubocop/cop/style/indent_assignment.rb +43 -0
  231. data/lib/rubocop/cop/style/indent_hash.rb +16 -77
  232. data/lib/rubocop/cop/style/indentation_consistency.rb +2 -1
  233. data/lib/rubocop/cop/style/indentation_width.rb +11 -11
  234. data/lib/rubocop/cop/style/infinite_loop.rb +5 -9
  235. data/lib/rubocop/cop/style/initial_indentation.rb +2 -1
  236. data/lib/rubocop/cop/style/inline_comment.rb +2 -1
  237. data/lib/rubocop/cop/style/lambda.rb +14 -11
  238. data/lib/rubocop/cop/style/lambda_call.rb +4 -4
  239. data/lib/rubocop/cop/style/leading_comment_space.rb +2 -1
  240. data/lib/rubocop/cop/style/line_end_concatenation.rb +3 -1
  241. data/lib/rubocop/cop/style/method_call_parentheses.rb +9 -1
  242. data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -2
  243. data/lib/rubocop/cop/style/method_def_parentheses.rb +4 -4
  244. data/lib/rubocop/cop/style/method_name.rb +1 -0
  245. data/lib/rubocop/cop/style/missing_else.rb +5 -3
  246. data/lib/rubocop/cop/style/module_function.rb +2 -1
  247. data/lib/rubocop/cop/style/multiline_array_brace_layout.rb +95 -0
  248. data/lib/rubocop/cop/style/multiline_assignment_layout.rb +91 -0
  249. data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
  250. data/lib/rubocop/cop/style/multiline_block_layout.rb +11 -9
  251. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -0
  252. data/lib/rubocop/cop/style/multiline_method_call_indentation.rb +137 -0
  253. data/lib/rubocop/cop/style/multiline_operation_indentation.rb +25 -135
  254. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +2 -1
  255. data/lib/rubocop/cop/style/mutable_constant.rb +4 -5
  256. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  257. data/lib/rubocop/cop/style/negated_while.rb +3 -3
  258. data/lib/rubocop/cop/style/nested_modifier.rb +6 -5
  259. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +48 -0
  260. data/lib/rubocop/cop/style/nested_ternary_operator.rb +2 -1
  261. data/lib/rubocop/cop/style/next.rb +79 -15
  262. data/lib/rubocop/cop/style/nil_comparison.rb +5 -5
  263. data/lib/rubocop/cop/style/non_nil_check.rb +5 -5
  264. data/lib/rubocop/cop/style/not.rb +5 -9
  265. data/lib/rubocop/cop/style/numeric_literals.rb +5 -4
  266. data/lib/rubocop/cop/style/one_line_conditional.rb +3 -2
  267. data/lib/rubocop/cop/style/op_method.rb +7 -4
  268. data/lib/rubocop/cop/style/option_hash.rb +13 -7
  269. data/lib/rubocop/cop/style/optional_arguments.rb +3 -2
  270. data/lib/rubocop/cop/style/parallel_assignment.rb +40 -16
  271. data/lib/rubocop/cop/style/parentheses_around_condition.rb +3 -16
  272. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +3 -2
  273. data/lib/rubocop/cop/style/percent_q_literals.rb +3 -6
  274. data/lib/rubocop/cop/style/perl_backrefs.rb +4 -3
  275. data/lib/rubocop/cop/style/predicate_name.rb +1 -0
  276. data/lib/rubocop/cop/style/proc.rb +3 -2
  277. data/lib/rubocop/cop/style/raise_args.rb +2 -1
  278. data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
  279. data/lib/rubocop/cop/style/redundant_exception.rb +5 -5
  280. data/lib/rubocop/cop/style/redundant_freeze.rb +5 -4
  281. data/lib/rubocop/cop/style/redundant_parentheses.rb +80 -0
  282. data/lib/rubocop/cop/style/redundant_return.rb +5 -4
  283. data/lib/rubocop/cop/style/redundant_self.rb +7 -8
  284. data/lib/rubocop/cop/style/regexp_literal.rb +9 -8
  285. data/lib/rubocop/cop/style/rescue_ensure_alignment.rb +3 -2
  286. data/lib/rubocop/cop/style/rescue_modifier.rb +11 -9
  287. data/lib/rubocop/cop/style/self_assignment.rb +4 -5
  288. data/lib/rubocop/cop/style/semicolon.rb +3 -2
  289. data/lib/rubocop/cop/style/send.rb +3 -1
  290. data/lib/rubocop/cop/style/signal_exception.rb +5 -3
  291. data/lib/rubocop/cop/style/single_line_block_params.rb +2 -1
  292. data/lib/rubocop/cop/style/single_line_methods.rb +7 -7
  293. data/lib/rubocop/cop/style/space_after_colon.rb +2 -1
  294. data/lib/rubocop/cop/style/space_after_comma.rb +1 -0
  295. data/lib/rubocop/cop/style/space_after_control_keyword.rb +5 -5
  296. data/lib/rubocop/cop/style/space_after_method_name.rb +3 -2
  297. data/lib/rubocop/cop/style/space_after_not.rb +4 -3
  298. data/lib/rubocop/cop/style/space_after_semicolon.rb +1 -0
  299. data/lib/rubocop/cop/style/space_around_block_parameters.rb +8 -7
  300. data/lib/rubocop/cop/style/space_around_equals_in_parameter_default.rb +1 -0
  301. data/lib/rubocop/cop/style/space_around_operators.rb +72 -32
  302. data/lib/rubocop/cop/style/space_before_block_braces.rb +2 -1
  303. data/lib/rubocop/cop/style/space_before_comma.rb +1 -0
  304. data/lib/rubocop/cop/style/space_before_comment.rb +2 -1
  305. data/lib/rubocop/cop/style/{single_space_before_first_arg.rb → space_before_first_arg.rb} +13 -4
  306. data/lib/rubocop/cop/style/space_before_modifier_keyword.rb +4 -3
  307. data/lib/rubocop/cop/style/space_before_semicolon.rb +1 -0
  308. data/lib/rubocop/cop/style/space_inside_block_braces.rb +3 -2
  309. data/lib/rubocop/cop/style/space_inside_brackets.rb +1 -0
  310. data/lib/rubocop/cop/style/space_inside_hash_literal_braces.rb +4 -1
  311. data/lib/rubocop/cop/style/space_inside_parens.rb +1 -0
  312. data/lib/rubocop/cop/style/space_inside_range_literal.rb +5 -4
  313. data/lib/rubocop/cop/style/space_inside_string_interpolation.rb +8 -17
  314. data/lib/rubocop/cop/style/special_global_vars.rb +97 -52
  315. data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +16 -9
  316. data/lib/rubocop/cop/style/string_literals.rb +41 -1
  317. data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +2 -1
  318. data/lib/rubocop/cop/style/string_methods.rb +2 -1
  319. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -2
  320. data/lib/rubocop/cop/style/symbol_array.rb +74 -7
  321. data/lib/rubocop/cop/style/symbol_literal.rb +4 -7
  322. data/lib/rubocop/cop/style/symbol_proc.rb +11 -7
  323. data/lib/rubocop/cop/style/tab.rb +25 -2
  324. data/lib/rubocop/cop/style/trailing_blank_lines.rb +1 -2
  325. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
  326. data/lib/rubocop/cop/style/trailing_comma_in_literal.rb +56 -0
  327. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +8 -7
  328. data/lib/rubocop/cop/style/trailing_whitespace.rb +2 -1
  329. data/lib/rubocop/cop/style/trivial_accessors.rb +18 -9
  330. data/lib/rubocop/cop/style/unless_else.rb +2 -1
  331. data/lib/rubocop/cop/style/unneeded_capital_w.rb +4 -3
  332. data/lib/rubocop/cop/style/unneeded_interpolation.rb +87 -0
  333. data/lib/rubocop/cop/style/unneeded_percent_q.rb +23 -7
  334. data/lib/rubocop/cop/style/variable_interpolation.rb +8 -6
  335. data/lib/rubocop/cop/style/variable_name.rb +1 -0
  336. data/lib/rubocop/cop/style/when_then.rb +2 -1
  337. data/lib/rubocop/cop/style/while_until_do.rb +3 -2
  338. data/lib/rubocop/cop/style/while_until_modifier.rb +3 -4
  339. data/lib/rubocop/cop/style/word_array.rb +74 -51
  340. data/lib/rubocop/cop/team.rb +21 -15
  341. data/lib/rubocop/cop/util.rb +102 -69
  342. data/lib/rubocop/cop/variable_force.rb +2 -1
  343. data/lib/rubocop/cop/variable_force/assignment.rb +2 -1
  344. data/lib/rubocop/cop/variable_force/locatable.rb +1 -0
  345. data/lib/rubocop/cop/variable_force/reference.rb +1 -0
  346. data/lib/rubocop/cop/variable_force/scope.rb +2 -1
  347. data/lib/rubocop/cop/variable_force/variable.rb +2 -1
  348. data/lib/rubocop/cop/variable_force/variable_table.rb +2 -1
  349. data/lib/rubocop/error.rb +12 -0
  350. data/lib/rubocop/formatter/base_formatter.rb +10 -1
  351. data/lib/rubocop/formatter/clang_style_formatter.rb +1 -0
  352. data/lib/rubocop/formatter/colorizable.rb +6 -1
  353. data/lib/rubocop/formatter/disabled_config_formatter.rb +29 -15
  354. data/lib/rubocop/formatter/disabled_lines_formatter.rb +3 -1
  355. data/lib/rubocop/formatter/emacs_style_formatter.rb +7 -3
  356. data/lib/rubocop/formatter/file_list_formatter.rb +1 -0
  357. data/lib/rubocop/formatter/formatter_set.rb +10 -19
  358. data/lib/rubocop/formatter/fuubar_style_formatter.rb +2 -1
  359. data/lib/rubocop/formatter/html_formatter.rb +15 -14
  360. data/lib/rubocop/formatter/json_formatter.rb +2 -1
  361. data/lib/rubocop/formatter/offense_count_formatter.rb +1 -0
  362. data/lib/rubocop/formatter/progress_formatter.rb +3 -3
  363. data/lib/rubocop/formatter/simple_text_formatter.rb +50 -17
  364. data/lib/rubocop/formatter/text_util.rb +8 -10
  365. data/lib/rubocop/formatter/worst_offenders_formatter.rb +61 -0
  366. data/lib/rubocop/name_similarity.rb +22 -0
  367. data/lib/rubocop/node_pattern.rb +126 -35
  368. data/lib/rubocop/options.rb +28 -19
  369. data/lib/rubocop/path_util.rb +1 -0
  370. data/lib/rubocop/processed_source.rb +41 -16
  371. data/lib/rubocop/rake_task.rb +6 -9
  372. data/lib/rubocop/remote_config.rb +1 -0
  373. data/lib/rubocop/result_cache.rb +60 -43
  374. data/lib/rubocop/runner.rb +48 -45
  375. data/lib/rubocop/string_util.rb +1 -0
  376. data/lib/rubocop/target_finder.rb +2 -1
  377. data/lib/rubocop/token.rb +1 -0
  378. data/lib/rubocop/version.rb +3 -2
  379. data/lib/rubocop/warning.rb +1 -0
  380. data/relnotes/v0.36.0.md +306 -0
  381. data/rubocop.gemspec +3 -9
  382. metadata +48 -92
  383. data/lib/rubocop/cop/lint/space_before_first_arg.rb +0 -44
  384. data/lib/rubocop/cop/rails/default_scope.rb +0 -33
  385. data/lib/rubocop/cop/style/trailing_comma.rb +0 -182
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -38,12 +39,12 @@ module RuboCop
38
39
  class Date < Cop
39
40
  include ConfigurableEnforcedStyle
40
41
 
41
- MSG = 'Do not use `%s` without zone. Use `%s` instead.'
42
+ MSG = 'Do not use `%s` without zone. Use `%s` instead.'.freeze
42
43
 
43
- MSG_SEND = 'Do not use `%s` on Date objects, ' \
44
- 'because they know nothing about the time zone in use.'
44
+ MSG_SEND = 'Do not use `%s` on Date objects, because they ' \
45
+ 'know nothing about the time zone in use.'.freeze
45
46
 
46
- BAD_DAYS = [:today, :current, :yesterday, :tomorrow]
47
+ BAD_DAYS = [:today, :current, :yesterday, :tomorrow].freeze
47
48
 
48
49
  def on_const(node)
49
50
  mod, klass = *node.children
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -29,7 +30,7 @@ module RuboCop
29
30
  # foo.bar
30
31
  # end
31
32
  class Delegate < Cop
32
- MSG = 'Use `delegate` to define delegations.'
33
+ MSG = 'Use `delegate` to define delegations.'.freeze
33
34
 
34
35
  def on_def(node)
35
36
  method_name, args, body = *node
@@ -49,7 +50,7 @@ module RuboCop
49
50
  end
50
51
 
51
52
  lambda do |corrector|
52
- corrector.replace(node.loc.expression, delegation.join(', '))
53
+ corrector.replace(node.source_range, delegation.join(', '))
53
54
  end
54
55
  end
55
56
 
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -14,29 +15,34 @@ module RuboCop
14
15
  # # good
15
16
  # User.find_by(name: 'Bruce')
16
17
  class FindBy < Cop
17
- MSG = 'Use `find_by` instead of `where.%s`.'
18
- TARGET_SELECTORS = [:first, :take]
18
+ MSG = 'Use `find_by` instead of `where.%s`.'.freeze
19
+ TARGET_SELECTORS = [:first, :take].freeze
20
+
21
+ def_node_matcher :where_first, <<-PATTERN
22
+ (send $(send _ :where ...) ${:first :take})
23
+ PATTERN
19
24
 
20
25
  def on_send(node)
21
- receiver, second_method, _selector = *node
22
- return unless TARGET_SELECTORS.include?(second_method)
23
- return if receiver.nil?
24
- _scope, first_method = *receiver
25
- return unless first_method == :where
26
- begin_of_offense = receiver.loc.selector.begin_pos
27
- end_of_offense = node.loc.selector.end_pos
28
- range = Parser::Source::Range.new(node.loc.expression.source_buffer,
29
- begin_of_offense,
30
- end_of_offense)
26
+ return unless (recv_and_method = where_first(node))
27
+ receiver, second_method = *recv_and_method
28
+
29
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
30
+ receiver.loc.selector.begin_pos,
31
+ node.loc.selector.end_pos)
31
32
 
32
33
  add_offense(node, range, format(MSG, second_method))
33
34
  end
34
35
 
35
36
  def autocorrect(node)
36
- receiver, = *node
37
+ receiver, second_method = where_first(node)
38
+ # Don't autocorrect where(...).first, because it can return different
39
+ # results from find_by. (They order records differently, so the
40
+ # 'first' record can be different.)
41
+ return if second_method == :first
42
+
37
43
  where_loc = receiver.loc.selector
38
44
  first_loc = Parser::Source::Range.new(
39
- node.loc.expression.source_buffer,
45
+ node.source_range.source_buffer,
40
46
  node.loc.dot.begin_pos,
41
47
  node.loc.selector.end_pos
42
48
  )
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -13,9 +14,9 @@ module RuboCop
13
14
  # # good
14
15
  # User.all.find_each
15
16
  class FindEach < Cop
16
- MSG = 'Use `find_each` instead of `each`.'
17
+ MSG = 'Use `find_each` instead of `each`.'.freeze
17
18
 
18
- SCOPE_METHODS = [:all, :where]
19
+ SCOPE_METHODS = [:all, :where].freeze
19
20
 
20
21
  def on_send(node)
21
22
  receiver, second_method, _selector = *node
@@ -24,6 +25,7 @@ module RuboCop
24
25
 
25
26
  _model, first_method = *receiver
26
27
  return unless SCOPE_METHODS.include?(first_method)
28
+ return if method_chain(node).any? { |m| ignored_by_find_each?(m) }
27
29
 
28
30
  add_offense(node, node.loc.selector, MSG)
29
31
  end
@@ -33,6 +35,25 @@ module RuboCop
33
35
 
34
36
  ->(corrector) { corrector.replace(each_loc, 'find_each') }
35
37
  end
38
+
39
+ private
40
+
41
+ def method_chain(node)
42
+ if (node.send_type? || node.block_type?) && !node.receiver.nil?
43
+ if node.parent
44
+ method_chain(node.parent) << node.method_name
45
+ else
46
+ [node.method_name]
47
+ end
48
+ else
49
+ []
50
+ end
51
+ end
52
+
53
+ def ignored_by_find_each?(relation_method)
54
+ # Active Record's #find_each ignores various extra parameters
55
+ [:order, :limit, :select].include?(relation_method)
56
+ end
36
57
  end
37
58
  end
38
59
  end
@@ -1,14 +1,15 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
5
6
  module Rails
6
7
  # This cop checks for the use of the has_and_belongs_to_many macro.
7
8
  class HasAndBelongsToMany < Cop
8
- MSG = 'Prefer `has_many :through` to `has_and_belongs_to_many`.'
9
+ MSG = 'Prefer `has_many :through` to `has_and_belongs_to_many`.'.freeze
9
10
 
10
11
  def on_send(node)
11
- return unless command?(:has_and_belongs_to_many, node)
12
+ return unless node.command?(:has_and_belongs_to_many)
12
13
  add_offense(node, :selector)
13
14
  end
14
15
  end
@@ -1,17 +1,19 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
5
6
  module Rails
6
7
  # This cop checks for the use of output calls like puts and print
7
8
  class Output < Cop
8
- MSG = 'Do not write to stdout. Use Rails\' logger if you want to log.'
9
+ MSG = 'Do not write to stdout. ' \
10
+ 'Use Rails\' logger if you want to log.'.freeze
9
11
 
10
12
  BLACKLIST = [:puts,
11
13
  :print,
12
14
  :p,
13
15
  :pp,
14
- :pretty_print]
16
+ :pretty_print].freeze
15
17
 
16
18
  def on_send(node)
17
19
  receiver, method_name, *args = *node
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -22,11 +23,11 @@ module RuboCop
22
23
  week: :weeks,
23
24
  fortnight: :fortnights,
24
25
  month: :months,
25
- year: :years }
26
+ year: :years }.freeze
26
27
 
27
28
  PLURAL_DURATION_METHODS = SINGULAR_DURATION_METHODS.invert
28
29
 
29
- MSG = 'Prefer `%s.%s`.'
30
+ MSG = 'Prefer `%s.%s`.'.freeze
30
31
 
31
32
  def on_send(node)
32
33
  receiver, method_name, *_args = *node
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -16,7 +17,7 @@ module RuboCop
16
17
  # x = self[:attr]
17
18
  # self[:attr] = val
18
19
  class ReadWriteAttribute < Cop
19
- MSG = 'Prefer `%s` over `%s`.'
20
+ MSG = 'Prefer `%s` over `%s`.'.freeze
20
21
 
21
22
  def on_send(node)
22
23
  receiver, method_name, *_args = *node
@@ -47,7 +48,7 @@ module RuboCop
47
48
  replacement = write_attribute_replacement(node)
48
49
  end
49
50
 
50
- ->(corrector) { corrector.replace(node.loc.expression, replacement) }
51
+ ->(corrector) { corrector.replace(node.source_range, replacement) }
51
52
  end
52
53
 
53
54
  private
@@ -55,17 +56,14 @@ module RuboCop
55
56
  def read_attribute_replacement(node)
56
57
  _receiver, _method_name, body = *node
57
58
 
58
- "self[#{body.loc.expression.source}]"
59
+ "self[#{body.source}]"
59
60
  end
60
61
 
61
62
  def write_attribute_replacement(node)
62
63
  _receiver, _method_name, *args = *node
63
64
  name, value = *args
64
65
 
65
- name_source = name.loc.expression.source
66
- value_source = value.loc.expression.source
67
-
68
- "self[#{name_source}] = #{value_source}"
66
+ "self[#{name.source}] = #{value.source}"
69
67
  end
70
68
  end
71
69
  end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -14,10 +15,10 @@ module RuboCop
14
15
  # # good
15
16
  # scope :something, -> { where(something: true) }
16
17
  class ScopeArgs < Cop
17
- MSG = 'Use `lambda`/`proc` instead of a plain method call.'
18
+ MSG = 'Use `lambda`/`proc` instead of a plain method call.'.freeze
18
19
 
19
20
  def on_send(node)
20
- return unless command?(:scope, node)
21
+ return unless node.command?(:scope)
21
22
 
22
23
  _receiver, _method_name, *args = *node
23
24
 
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -30,22 +31,24 @@ module RuboCop
30
31
  class TimeZone < Cop
31
32
  include ConfigurableEnforcedStyle
32
33
 
33
- MSG = 'Do not use `%s` without zone. Use `%s` instead.'
34
+ MSG = 'Do not use `%s` without zone. Use `%s` instead.'.freeze
34
35
 
35
- MSG_ACCEPTABLE = 'Do not use `%s` without zone. Use one of %s instead.'
36
+ MSG_ACCEPTABLE = 'Do not use `%s` without zone. ' \
37
+ 'Use one of %s instead.'.freeze
36
38
 
37
- MSG_LOCALTIME = 'Do not use `Time.localtime` without offset or zone.'
39
+ MSG_LOCALTIME = 'Do not use `Time.localtime` without ' \
40
+ 'offset or zone.'.freeze
38
41
 
39
- MSG_CURRENT = 'Do not use `%s`. Use `Time.zone.now` instead.'
42
+ MSG_CURRENT = 'Do not use `%s`. Use `Time.zone.now` instead.'.freeze
40
43
 
41
- TIMECLASS = [:Time, :DateTime]
44
+ TIMECLASS = [:Time, :DateTime].freeze
42
45
 
43
46
  DANGEROUS_METHODS = [:now, :local, :new, :strftime,
44
- :parse, :at, :current]
47
+ :parse, :at, :current].freeze
45
48
 
46
- ACCEPTED_METHODS = [:current, :in_time_zone, :utc, :getlocal,
49
+ ACCEPTED_METHODS = [:in_time_zone, :utc, :getlocal,
47
50
  :iso8601, :jisx0301, :rfc3339,
48
- :to_i, :to_f]
51
+ :to_i, :to_f].freeze
49
52
 
50
53
  def on_const(node)
51
54
  mod, klass = *node
@@ -151,12 +154,13 @@ module RuboCop
151
154
  end
152
155
 
153
156
  def good_methods
154
- style == :strict ? [:zone] : [:zone] + ACCEPTED_METHODS
157
+ style == :strict ? [:zone] : [:zone, :current] + ACCEPTED_METHODS
155
158
  end
156
159
 
157
160
  def acceptable_methods(klass, method_name, node)
158
161
  acceptable = [
159
- "`Time.zone.#{safe_method(method_name, node)}`"
162
+ "`Time.zone.#{safe_method(method_name, node)}`",
163
+ "`#{klass}.current`"
160
164
  ]
161
165
 
162
166
  ACCEPTED_METHODS.each do |am|
@@ -1,11 +1,12 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
5
6
  module Rails
6
7
  # This cop checks for the use of old-style attribute validation macros.
7
8
  class Validation < Cop
8
- MSG = 'Prefer the new style validations `%s` over `%s`.'
9
+ MSG = 'Prefer the new style validations `%s` over `%s`.'.freeze
9
10
 
10
11
  BLACKLIST = [:validates_acceptance_of,
11
12
  :validates_confirmation_of,
@@ -16,7 +17,7 @@ module RuboCop
16
17
  :validates_numericality_of,
17
18
  :validates_presence_of,
18
19
  :validates_size_of,
19
- :validates_uniqueness_of]
20
+ :validates_uniqueness_of].freeze
20
21
 
21
22
  WHITELIST = [
22
23
  'validates :column, acceptance: value',
@@ -29,7 +30,7 @@ module RuboCop
29
30
  'validates :column, presence: value',
30
31
  'validates :column, size: value',
31
32
  'validates :column, uniqueness: value'
32
- ]
33
+ ].freeze
33
34
 
34
35
  def on_send(node)
35
36
  receiver, method_name, *_args = *node
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -7,11 +8,11 @@ module RuboCop
7
8
  include Comparable
8
9
 
9
10
  # @api private
10
- NAMES = [:refactor, :convention, :warning, :error, :fatal]
11
+ NAMES = [:refactor, :convention, :warning, :error, :fatal].freeze
11
12
 
12
13
  # @api private
13
14
  CODE_TABLE = { R: :refactor, C: :convention,
14
- W: :warning, E: :error, F: :fatal }
15
+ W: :warning, E: :error, F: :fatal }.freeze
15
16
 
16
17
  # @api public
17
18
  #
@@ -55,11 +56,11 @@ module RuboCop
55
56
 
56
57
  # @api private
57
58
  def ==(other)
58
- if other.is_a?(Symbol)
59
- @name == other
60
- else
61
- @name == other.name
62
- end
59
+ @name == if other.is_a?(Symbol)
60
+ other
61
+ else
62
+ other.name
63
+ end
63
64
  end
64
65
 
65
66
  # @api private
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -10,7 +11,7 @@ module RuboCop
10
11
  include ConfigurableEnforcedStyle
11
12
  include AccessModifierNode
12
13
 
13
- MSG = '%s access modifiers like `%s`.'
14
+ MSG = '%s access modifiers like `%s`.'.freeze
14
15
 
15
16
  def on_class(node)
16
17
  _name, _base_class, body = *node
@@ -29,7 +30,7 @@ module RuboCop
29
30
 
30
31
  def on_block(node)
31
32
  _method, _args, body = *node
32
- check_body(body, node) if class_constructor?(node)
33
+ check_body(body, node) if node.class_constructor?
33
34
  end
34
35
 
35
36
  private
@@ -38,13 +39,13 @@ module RuboCop
38
39
  return if body.nil? # Empty class etc.
39
40
 
40
41
  modifiers = body.children.select { |c| modifier_node?(c) }
41
- class_column = node.loc.expression.column
42
+ class_column = node.source_range.column
42
43
 
43
44
  modifiers.each { |modifier| check_modifier(modifier, class_column) }
44
45
  end
45
46
 
46
47
  def check_modifier(send_node, class_start_col)
47
- access_modifier_start_col = send_node.loc.expression.column
48
+ access_modifier_start_col = send_node.source_range.column
48
49
  offset = access_modifier_start_col - class_start_col
49
50
 
50
51
  @column_delta = expected_indent_offset - offset
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -1,46 +1,106 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
5
6
  module Style
6
- # The purpose of the this cop is advise the use of
7
- # alias_method over the alias keyword whenever possible.
7
+ # This cop finds uses of `alias` where `alias_method` would be more
8
+ # appropriate (or is simply preferred due to configuration), and vice
9
+ # versa.
10
+ # It also finds uses of `alias :symbol` rather than `alias bareword`.
8
11
  class Alias < Cop
9
- MSG = 'Use `alias_method` instead of `alias`.'
12
+ include ConfigurableEnforcedStyle
10
13
 
11
- def on_block(node)
12
- method, _args, body = *node
13
- _receiver, method_name = *method
14
+ MSG_ALIAS = 'Use `alias_method` instead of `alias`.'.freeze
15
+ MSG_ALIAS_METHOD = 'Use `alias` instead of `alias_method` %s.'.freeze
16
+ MSG_SYMBOL_ARGS = 'Use `alias %s` instead of `alias %s`.'.freeze
14
17
 
15
- # using alias is the only option in certain scenarios
16
- # in such scenarios we don't want to report an offense
17
- return unless method_name == :instance_exec
18
- return unless body
18
+ def on_send(node)
19
+ return unless node.method_name == :alias_method && node.receiver.nil?
20
+ return if style == :prefer_alias_method
21
+ return if scope_type(node) == :dynamic
19
22
 
20
- body.each_node(:alias) { |n| ignore_node(n) }
23
+ msg = format(MSG_ALIAS_METHOD, lexical_scope_type(node))
24
+ add_offense(node, :selector, msg)
21
25
  end
22
26
 
23
27
  def on_alias(node)
24
- return if ignored_node?(node)
25
-
26
28
  # alias_method can't be used with global variables
27
- new, old = *node
28
-
29
- return if new.type == :gvar && old.type == :gvar
29
+ return if node.children.any?(&:gvar_type?)
30
30
 
31
- add_offense(node, :keyword)
31
+ if scope_type(node) == :dynamic || style == :prefer_alias_method
32
+ add_offense(node, :keyword, MSG_ALIAS)
33
+ elsif node.children.none? { |arg| bareword?(arg) }
34
+ existing_args = node.children.map(&:source).join(' ')
35
+ preferred_args = node.children.map { |a| a.source[1..-1] }.join(' ')
36
+ arg_ranges = node.children.map(&:source_range)
37
+ msg = format(MSG_SYMBOL_ARGS, preferred_args,
38
+ existing_args)
39
+ add_offense(node, arg_ranges.reduce(&:join), msg)
40
+ end
32
41
  end
33
42
 
34
43
  def autocorrect(node)
44
+ if node.send_type?
45
+ correct_alias_method_to_alias(node)
46
+ elsif scope_type(node) == :dynamic || style == :prefer_alias_method
47
+ correct_alias_to_alias_method(node)
48
+ else
49
+ correct_alias_with_symbol_args(node)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ # In this expression, will `self` be the same as the innermost enclosing
56
+ # class or module block (:lexical)? Or will it be something else
57
+ # (:dynamic)?
58
+ def scope_type(node)
59
+ while (parent = node.parent)
60
+ case parent.type
61
+ when :class, :module
62
+ return :lexical
63
+ when :def, :defs, :block
64
+ return :dynamic
65
+ end
66
+ node = parent
67
+ end
68
+ :lexical
69
+ end
70
+
71
+ def lexical_scope_type(node)
72
+ node.each_ancestor(:class, :module) do |ancestor|
73
+ return ancestor.class_type? ? 'in a class body' : 'in a module body'
74
+ end
75
+ 'at the top level'
76
+ end
77
+
78
+ def bareword?(sym_node)
79
+ sym_node.source[0] != ':'
80
+ end
81
+
82
+ def correct_alias_method_to_alias(node)
83
+ lambda do |corrector|
84
+ new, old = *node.method_args
85
+ replacement = "alias #{new.children.first} #{old.children.first}"
86
+ corrector.replace(node.source_range, replacement)
87
+ end
88
+ end
89
+
90
+ def correct_alias_to_alias_method(node)
91
+ lambda do |corrector|
92
+ new, old = *node
93
+ replacement = "alias_method :#{new.children.first}, " \
94
+ ":#{old.children.first}"
95
+ corrector.replace(node.source_range, replacement)
96
+ end
97
+ end
98
+
99
+ def correct_alias_with_symbol_args(node)
35
100
  lambda do |corrector|
36
- # replace alias with alias_method
37
- corrector.replace(node.loc.keyword, 'alias_method')
38
- # insert a comma
39
101
  new, old = *node
40
- corrector.insert_after(new.loc.expression, ',')
41
- # convert bareword arguments to symbols
42
- corrector.replace(new.loc.expression, ":#{new.children.first}")
43
- corrector.replace(old.loc.expression, ":#{old.children.first}")
102
+ corrector.replace(new.source_range, new.children.first.to_s)
103
+ corrector.replace(old.source_range, old.children.first.to_s)
44
104
  end
45
105
  end
46
106
  end