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
@@ -18,11 +19,11 @@ module RuboCop
18
19
  # [].detect { |item| true }
19
20
  # [].reverse.detect { |item| true }
20
21
  class Detect < Cop
21
- MSG = 'Use `%s` instead of `%s.%s`.'
22
- REVERSE_MSG = 'Use `reverse.%s` instead of `%s.%s`.'
22
+ MSG = 'Use `%s` instead of `%s.%s`.'.freeze
23
+ REVERSE_MSG = 'Use `reverse.%s` instead of `%s.%s`.'.freeze
23
24
 
24
- SELECT_METHODS = [:select, :find_all]
25
- DANGEROUS_METHODS = [:first, :last]
25
+ SELECT_METHODS = [:select, :find_all].freeze
26
+ DANGEROUS_METHODS = [:first, :last].freeze
26
27
 
27
28
  def on_send(node)
28
29
  receiver, second_method = *node
@@ -59,7 +60,7 @@ module RuboCop
59
60
  end
60
61
 
61
62
  first_range = Parser::Source::Range.new(
62
- receiver.loc.expression.source,
63
+ receiver.source,
63
64
  receiver.loc.end.end_pos,
64
65
  receiver.loc.end.end_pos).join(node.loc.selector)
65
66
 
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop checks for double `#start_with?` or `#end_with?` calls
8
+ # separated by `||`. In some cases such calls can be replaced
9
+ # with an single `#start_with?`/`#end_with?` call.
10
+ #
11
+ # @example
12
+ #
13
+ # @bad
14
+ # str.start_with?("a") || str.start_with?(Some::CONST)
15
+ # str.start_with?("a", "b") || str.start_with?("c")
16
+ # var1 = ...
17
+ # var2 = ...
18
+ # str.end_with?(var1) || str.end_with?(var2)
19
+ #
20
+ # @good
21
+ # str.start_with?("a", Some::CONST)
22
+ # str.start_with?("a", "b", "c")
23
+ # var1 = ...
24
+ # var2 = ...
25
+ # str.end_with?(var1, var2)
26
+ class DoubleStartEndWith < Cop
27
+ MSG = 'Use `%{receiver}.%{method}(%{combined_args})` ' \
28
+ 'instead of `%{original_code}`.'.freeze
29
+
30
+ def on_or(node)
31
+ receiver,
32
+ method,
33
+ first_call_args,
34
+ second_call_args = two_start_end_with_calls(node)
35
+
36
+ if receiver && second_call_args.all?(&:pure?)
37
+ add_offense(
38
+ node,
39
+ :expression,
40
+ format(
41
+ MSG,
42
+ receiver: receiver.source,
43
+ method: method,
44
+ combined_args: combine_args(first_call_args, second_call_args),
45
+ original_code: node.source
46
+ )
47
+ )
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def combine_args(first_call_args, second_call_args)
54
+ (first_call_args + second_call_args).map(&:source).join(', ')
55
+ end
56
+
57
+ def_node_matcher :two_start_end_with_calls, <<-END
58
+ (or
59
+ (send $_recv [{:start_with? :end_with?} $_method] $...)
60
+ (send _recv _method $...))
61
+ END
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,55 @@
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 `String#end_with?`
8
+ # would suffice.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # 'abc' =~ /bc\Z/
13
+ # 'abc'.match(/bc\Z/)
14
+ #
15
+ # @good
16
+ # 'abc' =~ /ab/
17
+ # 'abc' =~ /\w*\Z/
18
+ class EndWith < Cop
19
+ MSG = 'Use `String#end_with?` instead of a regex match anchored to ' \
20
+ 'the end of the string.'.freeze
21
+ SINGLE_QUOTE = "'".freeze
22
+
23
+ def_node_matcher :redundant_regex?, <<-END
24
+ {(send $_ {:match :=~} (regexp (str $#literal_at_end?) (regopt)))
25
+ (send (regexp (str $#literal_at_end?) (regopt)) {:match :=~} $_)}
26
+ END
27
+
28
+ def literal_at_end?(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 end of the string?
32
+ regex_str =~ /\A(?:#{LITERAL_REGEX})+\\z\z/
33
+ end
34
+
35
+ def on_send(node)
36
+ add_offense(node, :expression, MSG) if redundant_regex?(node)
37
+ end
38
+
39
+ def autocorrect(node)
40
+ redundant_regex?(node) do |receiver, regex_str|
41
+ receiver, regex_str = regex_str, receiver if receiver.is_a?(String)
42
+ regex_str = regex_str[0..-3] # drop \Z anchor
43
+ regex_str = interpret_string_escapes(regex_str)
44
+
45
+ lambda do |corrector|
46
+ new_source = receiver.source + '.end_with?(' +
47
+ to_string_literal(regex_str) + ')'
48
+ corrector.replace(node.source_range, new_source)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ 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
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  module Cop
@@ -15,11 +16,11 @@ module RuboCop
15
16
  # [1, 2, 3, 4].map { |e| [e, e] }.flatten
16
17
  # [1, 2, 3, 4].collect { |e| [e, e] }.flatten
17
18
  class FlatMap < Cop
18
- MSG = 'Use `flat_map` instead of `%s...%s`.'
19
+ MSG = 'Use `flat_map` instead of `%s...%s`.'.freeze
19
20
  FLATTEN_MULTIPLE_LEVELS = ' Beware, `flat_map` only flattens 1 level ' \
20
21
  'and `flatten` can be used to flatten ' \
21
- 'multiple levels.'
22
- FLATTEN = [:flatten, :flatten!]
22
+ 'multiple levels.'.freeze
23
+ FLATTEN = [:flatten, :flatten!].freeze
23
24
 
24
25
  def on_send(node)
25
26
  left, second_method, flatten_param = *node
@@ -32,11 +33,11 @@ module RuboCop
32
33
  message = MSG
33
34
  if cop_config['EnabledForFlattenWithoutParams'] && flatten_level.nil?
34
35
  message = MSG + FLATTEN_MULTIPLE_LEVELS
35
- else
36
- return unless flatten_level == 1
36
+ elsif flatten_level != 1
37
+ return
37
38
  end
38
39
 
39
- range = Parser::Source::Range.new(node.loc.expression.source_buffer,
40
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
40
41
  expression.loc.selector.begin_pos,
41
42
  node.loc.selector.end_pos)
42
43
 
@@ -51,9 +52,9 @@ module RuboCop
51
52
  array, = *receiver
52
53
 
53
54
  lambda do |corrector|
54
- range = Parser::Source::Range.new(node.loc.expression.source_buffer,
55
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
55
56
  node.loc.dot.begin_pos,
56
- node.loc.expression.end_pos)
57
+ node.source_range.end_pos)
57
58
 
58
59
  corrector.remove(range)
59
60
  corrector.replace(array.loc.selector, 'flat_map')
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop checks for uses of `each_key` & `each_value` Hash methods.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # hash.keys.each { |k| p k }
12
+ # hash.values.each { |v| p v }
13
+ # hash.each { |k, _v| p k }
14
+ # hash.each { |_k, v| p v }
15
+ #
16
+ # # good
17
+ # hash.each_key { |k| p k }
18
+ # hash.each_value { |v| p v }
19
+ class HashEachMethods < Cop
20
+ include Lint::UnusedArgument
21
+
22
+ MSG = 'Use `%s` instead of `%s`.'.freeze
23
+
24
+ def_node_matcher :plain_each, <<-END
25
+ (block $(send (send _ :hash) :each) (args (arg $_k) (arg $_v)) ...)
26
+ END
27
+
28
+ def_node_matcher :kv_each, <<-END
29
+ (block $(send (send (send _ :hash) ${:keys :values}) :each) ...)
30
+ END
31
+
32
+ def on_block(node)
33
+ plain_each(node) do |target, k, v|
34
+ return if @args[k] && @args[v]
35
+ used = @args[k] ? :key : :value
36
+ add_offense(target, range(target), format(message,
37
+ "each_#{used}",
38
+ :each))
39
+ end
40
+ kv_each(node) do |target, method|
41
+ add_offense(target, range(target), format(message,
42
+ "each_#{method[0..-2]}",
43
+ "#{method}.each"))
44
+ end
45
+ end
46
+
47
+ def check_argument(variable)
48
+ return unless variable.block_argument?
49
+ (@args ||= {})[variable.name] = variable.used?
50
+ end
51
+
52
+ def autocorrect(node)
53
+ receiver, _second_method = *node
54
+ caller, first_method = *receiver
55
+ lambda do |corrector|
56
+ if first_method == :hash
57
+ method = @args.values.first ? :key : :value
58
+ new_source = receiver.source + ".each_#{method}"
59
+ corrector.replace(node.loc.expression, new_source)
60
+ correct_args(node, corrector)
61
+ else
62
+ new_source = caller.source + ".each_#{first_method[0..-2]}"
63
+ corrector.replace(node.loc.expression, new_source)
64
+ end
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def correct_args(node, corrector)
71
+ args = node.parent.children[1]
72
+ used_arg = "|#{@args.detect { |_k, v| v }.first}|"
73
+ args_range = Parser::Source::Range.new(node.parent.source,
74
+ args.loc.begin.begin_pos,
75
+ args.loc.end.end_pos)
76
+ corrector.replace(args_range, used_arg)
77
+ end
78
+
79
+ def range(outer_node)
80
+ inner_node = outer_node.children.first
81
+ inner_node.loc.selector.join(outer_node.loc.selector)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,44 @@
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 `lstrip.rstrip` can be replaced by
8
+ # `strip`.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # 'abc'.lstrip.rstrip
13
+ # 'abc'.rstrip.lstrip
14
+ #
15
+ # @good
16
+ # 'abc'.strip
17
+ class LstripRstrip < Cop
18
+ MSG = 'Use `strip` instead of `%s.%s`.'.freeze
19
+
20
+ def_node_matcher :lstrip_rstrip, <<-END
21
+ {(send $(send _ $:rstrip) $:lstrip)
22
+ (send $(send _ $:lstrip) $:rstrip)}
23
+ END
24
+
25
+ def on_send(node)
26
+ lstrip_rstrip(node) do |first_send, method_one, method_two|
27
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
28
+ first_send.loc.selector.begin_pos,
29
+ node.source_range.end_pos)
30
+ add_offense(node, range, format(MSG, method_one, method_two))
31
+ end
32
+ end
33
+
34
+ def autocorrect(node)
35
+ first_send, = *node
36
+ range = Parser::Source::Range.new(node.source_range.source_buffer,
37
+ first_send.loc.selector.begin_pos,
38
+ node.source_range.end_pos)
39
+ ->(corrector) { corrector.replace(range, 'strip') }
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies uses of `Range#include?`, which iterates over each
8
+ # item in a `Range` to see if a specified item is there. In contrast,
9
+ # `Range#cover?` simply compares the target item with the beginning and
10
+ # end points of the `Range`. In a great majority of cases, this is what
11
+ # is wanted.
12
+ #
13
+ # Here is an example of a case where `Range#cover?` may not provide the
14
+ # desired result:
15
+ #
16
+ # ('a'..'z').cover?('yellow') # => true
17
+ #
18
+ class RangeInclude < Cop
19
+ MSG = 'Use `Range#cover?` instead of `Range#include?`.'.freeze
20
+
21
+ # TODO: If we traced out assignments of variables to their uses, we
22
+ # might pick up on a few more instances of this issue
23
+ # Right now, we only detect direct calls on a Range literal
24
+ # (We don't even catch it if the Range is in double parens)
25
+
26
+ def_node_matcher :range_include, <<-END
27
+ (send {irange erange (begin {irange erange})} :include? ...)
28
+ END
29
+
30
+ def on_send(node)
31
+ add_offense(node, :selector, MSG) if range_include(node)
32
+ end
33
+
34
+ def autocorrect(node)
35
+ ->(corrector) { corrector.replace(node.loc.selector, 'cover?') }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies the use of a `&block` parameter and `block.call`
8
+ # where `yield` would do just as well.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # def method(&block)
13
+ # block.call
14
+ # end
15
+ # def another(&func)
16
+ # func.call 1, 2, 3
17
+ # end
18
+ #
19
+ # @good
20
+ # def method
21
+ # yield
22
+ # end
23
+ # def another
24
+ # yield 1, 2, 3
25
+ # end
26
+ class RedundantBlockCall < Cop
27
+ MSG = 'Use `yield` instead of `%s.call`.'.freeze
28
+
29
+ def_node_matcher :blockarg_def, <<-END
30
+ {(def _ (args ... (blockarg $_)) $_)
31
+ (defs _ _ (args ... (blockarg $_)) $_)}
32
+ END
33
+
34
+ def_node_search :blockarg_calls, <<-END
35
+ (send (lvar %1) :call ...)
36
+ END
37
+
38
+ def on_def(node)
39
+ blockarg_def(node) do |argname, body|
40
+ blockarg_calls(body, argname) do |blockcall|
41
+ add_offense(blockcall, :expression, format(MSG, argname))
42
+ end
43
+ end
44
+ end
45
+
46
+ # offenses are registered on the `block.call` nodes
47
+ def autocorrect(node)
48
+ _receiver, _method, *args = *node
49
+ new_source = 'yield'
50
+ new_source += ' ' unless args.empty?
51
+ new_source += args.map(&:source).join(', ')
52
+ ->(corrector) { corrector.replace(node.source_range, new_source) }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ module Cop
6
+ module Performance
7
+ # This cop identifies use of `Regexp#match` or `String#match in a context
8
+ # where the integral return value of `=~` would do just as well.
9
+ #
10
+ # @example
11
+ # @bad
12
+ # do_something if str.match(/regex/)
13
+ # while regex.match('str')
14
+ # do_something
15
+ # end
16
+ #
17
+ # @good
18
+ # method(str.match(/regex/))
19
+ # return regex.match('str')
20
+ class RedundantMatch < Cop
21
+ MSG = 'Use `=~` in places where the `MatchData` returned by ' \
22
+ '`#match` will not be used.'.freeze
23
+
24
+ # 'match' is a fairly generic name, so we don't flag it unless we see
25
+ # a string or regexp literal on one side or the other
26
+ def_node_matcher :match_call?, <<-END
27
+ {(send {str regexp} :match _)
28
+ (send !nil :match {str regexp})}
29
+ END
30
+
31
+ def_node_matcher :only_truthiness_matters?, <<-END
32
+ ^({if while until case while_post until_post} equal?(%0) ...)
33
+ END
34
+
35
+ def on_send(node)
36
+ return unless match_call?(node) &&
37
+ (!node.value_used? || only_truthiness_matters?(node))
38
+ add_offense(node, :expression, MSG)
39
+ end
40
+
41
+ def autocorrect(node)
42
+ # Regexp#match can take a second argument, but this cop doesn't
43
+ # register an offense in that case
44
+ receiver, _method, arg = *node
45
+ new_source = receiver.source + ' =~ ' + arg.source
46
+ ->(corrector) { corrector.replace(node.source_range, new_source) }
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end