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
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies places where `Hash#merge!` can be replaced by
8
+ # `Hash#[]=`.
9
+ #
10
+ # @example
11
+ # hash.merge!(a: 1)
12
+ # hash.merge!({'key' => 'value'})
13
+ # hash.merge!(a: 1, b: 2)
14
+ class RedundantMerge < Cop
15
+ AREF_ASGN = '%s[%s] = %s'.freeze
16
+ MSG = 'Use `%s` instead of `%s`.'.freeze
17
+
18
+ def_node_matcher :redundant_merge, '(send $_ :merge! (hash $...))'
19
+ def_node_matcher :modifier_flow_control, '[{if while until} #modifier?]'
20
+
21
+ def on_send(node)
22
+ redundant_merge(node) do |receiver, pairs|
23
+ next if node.value_used?
24
+ next if pairs.size > 1 && !receiver.pure?
25
+
26
+ assignments = to_assignments(receiver, pairs).join('; ')
27
+ message = format(MSG, assignments, node.source)
28
+ add_offense(node, :expression, message)
29
+ end
30
+ end
31
+
32
+ def autocorrect(node)
33
+ redundant_merge(node) do |receiver, pairs|
34
+ lambda do |corrector|
35
+ new_source = to_assignments(receiver, pairs).join("\n")
36
+
37
+ parent = node.parent
38
+ if parent && pairs.size > 1
39
+ if modifier_flow_control(parent)
40
+ cond, = *parent
41
+ padding = "\n#{' ' * indent_width}"
42
+ new_source.gsub!(/\n/, padding)
43
+ new_source = parent.loc.keyword.source << ' ' <<
44
+ cond.source << padding << leading_spaces(node) <<
45
+ new_source << "\n" << leading_spaces(node) <<
46
+ 'end'
47
+ node = parent
48
+ end
49
+ end
50
+
51
+ corrector.replace(node.source_range, new_source)
52
+ end
53
+ end
54
+ end
55
+
56
+ private
57
+
58
+ def to_assignments(receiver, pairs)
59
+ pairs.map do |pair|
60
+ key, value = *pair
61
+ key_src = if key.sym_type? && !key.source.start_with?(':')
62
+ ":#{key.source}"
63
+ else
64
+ key.source
65
+ end
66
+
67
+ format(AREF_ASGN, receiver.source, key_src, value.source)
68
+ end
69
+ end
70
+
71
+ def leading_spaces(node)
72
+ node.source_range.source_line[/\A\s*/]
73
+ end
74
+
75
+ def indent_width
76
+ @config.for_cop('IndentationWidth')['Width'] || 2
77
+ end
78
+
79
+ def modifier?(node)
80
+ node.loc.respond_to?(:end) && node.loc.end.nil?
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies places where `sort_by { ... }` can be replaced by
8
+ # `sort`.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # array.sort_by { |x| x }
13
+ # array.sort_by do |var|
14
+ # var
15
+ # end
16
+ #
17
+ # @good
18
+ # array.sort
19
+ class RedundantSortBy < Cop
20
+ MSG = 'Use `sort` instead of `sort_by { |%s| %s }`.'.freeze
21
+
22
+ def_node_matcher :redundant_sort_by, <<-END
23
+ (block $(send _ :sort_by) (args (arg $_x)) (lvar _x))
24
+ END
25
+
26
+ def on_block(node)
27
+ redundant_sort_by(node) do |send, var_name|
28
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
29
+ send.loc.selector.begin_pos,
30
+ node.loc.end.end_pos)
31
+ add_offense(node, range, format(MSG, var_name, var_name))
32
+ end
33
+ end
34
+
35
+ def autocorrect(node)
36
+ send, = *node
37
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
38
+ send.loc.selector.begin_pos,
39
+ node.loc.end.end_pos)
40
+ ->(corrector) { corrector.replace(range, 'sort') }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ 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
@@ -13,7 +14,7 @@ module RuboCop
13
14
  # # good
14
15
  # [].reverse_each
15
16
  class ReverseEach < Cop
16
- MSG = 'Use `reverse_each` instead of `reverse.each`.'
17
+ MSG = 'Use `reverse_each` instead of `reverse.each`.'.freeze
17
18
 
18
19
  def on_send(node)
19
20
  receiver, second_method = *node
@@ -22,7 +23,7 @@ module RuboCop
22
23
  _, first_method = *receiver
23
24
  return unless first_method == :reverse
24
25
 
25
- source_buffer = node.loc.expression.source_buffer
26
+ source_buffer = node.source_range.source_buffer
26
27
  location_of_reverse = receiver.loc.selector.begin_pos
27
28
  end_location = node.loc.selector.end_pos
28
29
 
@@ -1,4 +1,5 @@
1
1
  # encoding: UTF-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -25,7 +26,7 @@ module RuboCop
25
26
  # [1, 2, 3].shuffle[foo, bar]
26
27
  # [1, 2, 3].shuffle(random: Random.new)
27
28
  class Sample < Cop
28
- MSG = 'Use `%<correct>s` instead of `%<incorrect>s`.'
29
+ MSG = 'Use `%<correct>s` instead of `%<incorrect>s`.'.freeze
29
30
 
30
31
  def on_send(node)
31
32
  analyzer = ShuffleAnalyzer.new(node)
@@ -57,9 +58,9 @@ module RuboCop
57
58
  end
58
59
 
59
60
  def source_range
60
- Parser::Source::Range.new(shuffle_node.loc.expression.source_buffer,
61
+ Parser::Source::Range.new(shuffle_node.source_range.source_buffer,
61
62
  shuffle_node.loc.selector.begin_pos,
62
- method_node.loc.expression.end_pos)
63
+ method_node.source_range.end_pos)
63
64
  end
64
65
 
65
66
  private
@@ -85,7 +86,7 @@ module RuboCop
85
86
 
86
87
  def method_arg
87
88
  _, _, arg = *method_node
88
- arg.loc.expression.source if arg
89
+ arg.source if arg
89
90
  end
90
91
 
91
92
  # FIXME: use Range#size once Ruby 1.9 support is dropped
@@ -126,7 +127,7 @@ module RuboCop
126
127
 
127
128
  def shuffle_arg
128
129
  _, _, arg = *shuffle_node
129
- arg.loc.expression.source if arg
130
+ arg.source if arg
130
131
  end
131
132
  end
132
133
  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
@@ -24,7 +25,7 @@ module RuboCop
24
25
  # TODO: Add advanced detection of variables that could
25
26
  # have been assigned to an array or a hash.
26
27
  class Size < Cop
27
- MSG = 'Use `size` instead of `count`.'
28
+ MSG = 'Use `size` instead of `count`.'.freeze
28
29
 
29
30
  def on_send(node)
30
31
  receiver, method, args = *node
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies unnecessary use of a regex where
8
+ # `String#start_with?` would suffice.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # 'abc' =~ /\Aab/
13
+ # 'abc'.match(/\Aab/)
14
+ #
15
+ # @good
16
+ # 'abc' =~ /ab/
17
+ # 'abc' =~ /\A\w*/
18
+ class StartWith < Cop
19
+ MSG = 'Use `String#start_with?` instead of a regex match anchored to ' \
20
+ 'the beginning of the string.'.freeze
21
+ SINGLE_QUOTE = "'".freeze
22
+
23
+ def_node_matcher :redundant_regex?, <<-END
24
+ {(send $_ {:match :=~} (regexp (str $#literal_at_start?) (regopt)))
25
+ (send (regexp (str $#literal_at_start?) (regopt)) {:match :=~} $_)}
26
+ END
27
+
28
+ def literal_at_start?(regex_str)
29
+ # is this regexp 'literal' in the sense of only matching literal
30
+ # chars, rather than using metachars like . and * and so on?
31
+ # also, is it anchored at the start of the string?
32
+ # (tricky: \s, \d, and so on are metacharacters, but other characters
33
+ # escaped with a slash are just literals. LITERAL_REGEX takes all
34
+ # that into account.)
35
+ regex_str =~ /\A\\A(?:#{LITERAL_REGEX})+\z/
36
+ end
37
+
38
+ def on_send(node)
39
+ add_offense(node, :expression, MSG) if redundant_regex?(node)
40
+ end
41
+
42
+ def autocorrect(node)
43
+ redundant_regex?(node) do |receiver, regex_str|
44
+ receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
45
+ regex_str = regex_str[2..-1] # drop \A anchor
46
+ regex_str = interpret_string_escapes(regex_str)
47
+
48
+ lambda do |corrector|
49
+ new_source = receiver.source + '.start_with?(' +
50
+ to_string_literal(regex_str) + ')'
51
+ corrector.replace(node.source_range, new_source)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ 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
@@ -19,8 +20,8 @@ module RuboCop
19
20
  # 'abc'.tr('b', 'd')
20
21
  # 'a b c'.delete(' ')
21
22
  class StringReplacement < Cop
22
- MSG = 'Use `%s` instead of `%s`.'
23
- DETERMINISTIC_REGEX = /^[\w\s\-,"']+$/.freeze
23
+ MSG = 'Use `%s` instead of `%s`.'.freeze
24
+ DETERMINISTIC_REGEX = /\A(?:#{LITERAL_REGEX})+\Z/
24
25
  REGEXP_CONSTRUCTOR_METHODS = [:new, :compile].freeze
25
26
  GSUB_METHODS = [:gsub, :gsub!].freeze
26
27
  DETERMINISTIC_TYPES = [:regexp, :str, :send].freeze
@@ -43,6 +44,9 @@ module RuboCop
43
44
  if regex?(first_param)
44
45
  return unless first_source =~ DETERMINISTIC_REGEX
45
46
  return if options
47
+ # This must be done after checking DETERMINISTIC_REGEX
48
+ # Otherwise things like \s will trip us up
49
+ first_source = interpret_string_escapes(first_source)
46
50
  end
47
51
 
48
52
  return if first_source.length != 1
@@ -56,6 +60,11 @@ module RuboCop
56
60
  _string, method, first_param, second_param = *node
57
61
  first_source, = first_source(first_param)
58
62
  second_source, = *second_param
63
+
64
+ if regex?(first_param)
65
+ first_source = interpret_string_escapes(first_source)
66
+ end
67
+
59
68
  replacement_method = replacement_method(method,
60
69
  first_source,
61
70
  second_source)
@@ -63,8 +72,8 @@ module RuboCop
63
72
  lambda do |corrector|
64
73
  corrector.replace(node.loc.selector, replacement_method)
65
74
  unless first_param.str_type?
66
- corrector.replace(first_param.loc.expression,
67
- escape(first_source))
75
+ corrector.replace(first_param.source_range,
76
+ to_string_literal(first_source))
68
77
  end
69
78
 
70
79
  if second_source.empty? && first_source.length == 1
@@ -83,7 +92,6 @@ module RuboCop
83
92
  case first_param.type
84
93
  when :regexp, :send
85
94
  return nil unless regex?(first_param)
86
-
87
95
  source, options = extract_source(first_param)
88
96
  when :str
89
97
  source, = *first_param
@@ -129,9 +137,9 @@ module RuboCop
129
137
  end
130
138
 
131
139
  def range(node)
132
- Parser::Source::Range.new(node.loc.expression.source_buffer,
140
+ Parser::Source::Range.new(node.source_range.source_buffer,
133
141
  node.loc.selector.begin_pos,
134
- node.loc.expression.end_pos)
142
+ node.source_range.end_pos)
135
143
  end
136
144
 
137
145
  def replacement_method(method, first_source, second_source)
@@ -156,28 +164,15 @@ module RuboCop
156
164
  method.to_s.end_with?(BANG)
157
165
  end
158
166
 
159
- def escape(string)
160
- if require_double_quotes?(string)
161
- string.inspect
162
- else
163
- "'#{string}'"
164
- end
165
- end
166
-
167
- def require_double_quotes?(string)
168
- string.inspect.include?(SINGLE_QUOTE) ||
169
- StringHelp::ESCAPED_CHAR_REGEXP =~ string
170
- end
171
-
172
167
  def method_suffix(node)
173
168
  node.loc.end ? node.loc.end.source : ''
174
169
  end
175
170
 
176
171
  def remove_second_param(corrector, node, first_param)
177
172
  end_range =
178
- Parser::Source::Range.new(node.loc.expression.source_buffer,
179
- first_param.loc.expression.end_pos,
180
- node.loc.expression.end_pos)
173
+ Parser::Source::Range.new(node.source_range.source_buffer,
174
+ first_param.source_range.end_pos,
175
+ node.source_range.end_pos)
181
176
 
182
177
  corrector.replace(end_range, method_suffix(node))
183
178
  end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop checks for .times.map calls.
8
+ # In most cases such calls can be replaced
9
+ # with an explicit array creation.
10
+ #
11
+ # @example
12
+ #
13
+ # @bad
14
+ # 9.times.map do |i|
15
+ # i.to_s
16
+ # end
17
+ #
18
+ # @good
19
+ # Array.new(9) do |i|
20
+ # i.to_s
21
+ # end
22
+ class TimesMap < Cop
23
+ MSG = 'Use `Array.new` with a block instead of `.times.%s`.'.freeze
24
+
25
+ def on_send(node)
26
+ check(node)
27
+ end
28
+
29
+ def on_block(node)
30
+ check(node)
31
+ end
32
+
33
+ private
34
+
35
+ def check(node)
36
+ map_or_collect = times_map_call(node)
37
+ if map_or_collect
38
+ add_offense(node, :expression, format(MSG, map_or_collect))
39
+ end
40
+ end
41
+
42
+ def_node_matcher :times_map_call, <<-END
43
+ {(block (send (send _ :times) ${:map :collect}) ...)
44
+ (send (send _ :times) ${:map :collect} (block_pass ...))}
45
+ END
46
+ end
47
+ end
48
+ end
49
+ 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
@@ -10,7 +11,7 @@ module RuboCop
10
11
  class ActionFilter < Cop
11
12
  include ConfigurableEnforcedStyle
12
13
 
13
- MSG = 'Prefer `%s` over `%s`.'
14
+ MSG = 'Prefer `%s` over `%s`.'.freeze
14
15
 
15
16
  FILTER_METHODS = [
16
17
  :after_filter,
@@ -26,7 +27,7 @@ module RuboCop
26
27
  :skip_around_filter,
27
28
  :skip_before_filter,
28
29
  :skip_filter
29
- ]
30
+ ].freeze
30
31
 
31
32
  ACTION_METHODS = [
32
33
  :after_action,
@@ -42,7 +43,7 @@ module RuboCop
42
43
  :skip_around_action,
43
44
  :skip_before_action,
44
45
  :skip_action_callback
45
- ]
46
+ ].freeze
46
47
 
47
48
  def on_block(node)
48
49
  method, _args, _body = *node