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,61 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'pathname'
5
+
6
+ module RuboCop
7
+ module Formatter
8
+ # This formatter displays the list of offensive files, sorted by number of
9
+ # offenses with the worst offenders first.
10
+ #
11
+ # Here's the format:
12
+ #
13
+ # 26 this/file/is/really/bad.rb
14
+ # 3 just/ok.rb
15
+ # --
16
+ # 29 Total
17
+ class WorstOffendersFormatter < BaseFormatter
18
+ attr_reader :offense_counts
19
+
20
+ def started(target_files)
21
+ super
22
+ @offense_counts = {}
23
+ end
24
+
25
+ def file_finished(file, offenses)
26
+ unless offenses.empty?
27
+ path = Pathname.new(file).relative_path_from(Pathname.new(Dir.pwd))
28
+ @offense_counts[path] = offenses.size
29
+ end
30
+ end
31
+
32
+ def finished(_inspected_files)
33
+ report_summary(@offense_counts)
34
+ end
35
+
36
+ def report_summary(offense_counts)
37
+ per_file_counts = ordered_offense_counts(offense_counts)
38
+ total_count = total_offense_count(offense_counts)
39
+
40
+ output.puts
41
+
42
+ per_file_counts.each do |file_name, count|
43
+ output.puts "#{count.to_s.ljust(total_count.to_s.length + 2)}" \
44
+ "#{file_name}\n"
45
+ end
46
+ output.puts '--'
47
+ output.puts "#{total_count} Total"
48
+
49
+ output.puts
50
+ end
51
+
52
+ def ordered_offense_counts(offense_counts)
53
+ Hash[offense_counts.sort_by { |k, v| [-v, k] }]
54
+ end
55
+
56
+ def total_offense_count(offense_counts)
57
+ offense_counts.values.inject(0, :+)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ module RuboCop
5
+ # Common functionality for finding names that are similar to a given name.
6
+ module NameSimilarity
7
+ MINIMUM_SIMILARITY_TO_SUGGEST = 0.9
8
+
9
+ def find_similar_name(target_name, scope)
10
+ names = collect_variable_like_names(scope)
11
+ names.delete(target_name)
12
+
13
+ scores = names.each_with_object({}) do |name, hash|
14
+ score = StringUtil.similarity(target_name, name)
15
+ hash[name] = score if score >= MINIMUM_SIMILARITY_TO_SUGGEST
16
+ end
17
+
18
+ most_similar_name, _max_score = scores.max_by { |_, score| score }
19
+ most_similar_name
20
+ end
21
+ end
22
+ end
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  # rubocop:disable Metrics/ClassLength
4
5
  # rubocop:disable Metrics/CyclomaticComplexity
@@ -44,20 +45,33 @@ module RuboCop
44
45
  # '(send $... int)' # capture all children but the last as an array
45
46
  # '(send _x :+ _x)' # unification is performed on named wildcards
46
47
  # # (like Prolog variables...)
48
+ # # (#== is used to see if values unify)
47
49
  # '(int odd?)' # words which end with a ? are predicate methods,
48
50
  # # are are called on the target to see if it matches
49
51
  # # any Ruby method which the matched object supports
50
52
  # # can be used
53
+ # # if a truthy value is returned, the match succeeds
51
54
  # '(int [!1 !2])' # [] contains multiple patterns, ALL of which must
52
55
  # # match in that position
53
- # # ({} is pattern union, [] is intersection)
56
+ # # in other words, while {} is pattern union (logical
57
+ # # OR), [] is intersection (logical AND)
54
58
  # '(send %1 _)' # % stands for a parameter which must be supplied to
55
59
  # # #match at matching time
56
60
  # # it will be compared to the corresponding value in
57
61
  # # the AST using #==
58
62
  # # a bare '%' is the same as '%1'
63
+ # # the number of extra parameters passed to #match
64
+ # # must equal the highest % value in the pattern
65
+ # # for consistency, %0 is the 'root node' which is
66
+ # # passed as the 1st argument to #match, where the
67
+ # # matching process starts
59
68
  # '^^send' # each ^ ascends one level in the AST
60
69
  # # so this matches against the grandparent node
70
+ # '#method' # we call this a 'funcall'; it calls a method in the
71
+ # # context where a pattern-matching method is defined
72
+ # # if that returns a truthy value, the match succeeds
73
+ # 'equal?(%1)' # predicates can be given 1 or more extra args
74
+ # '#method(%0, 1)' # funcalls can also be given 1 or more extra args
61
75
  #
62
76
  # You can nest arbitrarily deep:
63
77
  #
@@ -73,9 +87,10 @@ module RuboCop
73
87
  # `#prefix_type?` to the AST node class, then 'prefix' will become usable as
74
88
  # a pattern.
75
89
  #
76
- # Also node that if you need a "guard clause" to protect against possible nils
90
+ # Also note that if you need a "guard clause" to protect against possible nils
77
91
  # in a certain place in the AST, you can do it like this: `[!nil <pattern>]`
78
92
  #
93
+ # The compiler code is very simple; don't be afraid to read through it!
79
94
  class NodePattern
80
95
  # @private
81
96
  Invalid = Class.new(StandardError)
@@ -83,15 +98,18 @@ module RuboCop
83
98
  # @private
84
99
  # Builds Ruby code which implements a pattern
85
100
  class Compiler
86
- RSYM = %r{:(?:[\w+-@_*/?!<>~|%^]+|==|\[\]=?)}
87
- ID_CHAR = /[a-zA-Z_]/
88
- META_CHAR = /\(|\)|\{|\}|\[|\]|\$\.\.\.|\$|!|\^|\.\.\./
89
- TOKEN = /\G(?:\s+|#{META_CHAR}|#{ID_CHAR}+\??|%\d*|\d+|#{RSYM}|.)/
101
+ RSYM = %r{:(?:[\w+@_*/?!<>=~|%^-]+|\[\]=?)}
102
+ ID_CHAR = /[a-zA-Z_]/
103
+ META = /\(|\)|\{|\}|\[|\]|\$\.\.\.|\$|!|\^|\.\.\./
104
+ NUMBER = /-?\d+(?:\.\d+)?/
105
+ TOKEN =
106
+ /\G(?:[\s,]+|#{META}|\#?#{ID_CHAR}+[\!\?]?\(?|%\d*|#{NUMBER}|#{RSYM}|.)/
90
107
 
91
108
  NODE = /\A#{ID_CHAR}+\Z/
92
- PREDICATE = /\A#{ID_CHAR}+\?\Z/
93
- LITERAL = /\A(?:#{RSYM}|\d+|nil)\Z/
109
+ PREDICATE = /\A#{ID_CHAR}+\?\(?\Z/
94
110
  WILDCARD = /\A_#{ID_CHAR}*\Z/
111
+ FUNCALL = /\A\##{ID_CHAR}+[\!\?]?\(?\Z/
112
+ LITERAL = /\A(?:#{RSYM}|#{NUMBER}|nil)\Z/
95
113
  PARAM = /\A%\d*\Z/
96
114
  CLOSING = /\A(?:\)|\}|\])\Z/
97
115
 
@@ -99,6 +117,7 @@ module RuboCop
99
117
 
100
118
  def initialize(str, node_var = 'node0')
101
119
  @string = str
120
+ @root = node_var
102
121
 
103
122
  @temps = 0 # avoid name clashes between temp variables
104
123
  @captures = 0 # number of captures seen
@@ -110,12 +129,18 @@ module RuboCop
110
129
 
111
130
  def run(node_var)
112
131
  tokens = @string.scan(TOKEN)
113
- tokens.reject! { |token| token =~ /\A\s+\Z/ }
132
+ tokens.reject! { |token| token =~ /\A[\s,]+\Z/ } # drop whitespace
114
133
  @match_code = compile_expr(tokens, node_var, false)
115
134
  fail_due_to('unbalanced pattern') unless tokens.empty?
116
135
  end
117
136
 
118
137
  def compile_expr(tokens, cur_node, seq_head)
138
+ # read a single pattern-matching expression from the token stream,
139
+ # return Ruby code which performs the corresponding matching operation
140
+ # on 'cur_node' (which is Ruby code which evaluates to an AST node)
141
+ #
142
+ # the 'pattern-matching' expression may be a composite which
143
+ # contains an arbitrary number of sub-expressions
119
144
  token = tokens.shift
120
145
  case token
121
146
  when '(' then compile_seq(tokens, cur_node, seq_head)
@@ -125,8 +150,9 @@ module RuboCop
125
150
  when '$' then compile_capture(tokens, cur_node, seq_head)
126
151
  when '^' then compile_ascend(tokens, cur_node, seq_head)
127
152
  when WILDCARD then compile_wildcard(cur_node, token[1..-1], seq_head)
153
+ when FUNCALL then compile_funcall(tokens, cur_node, token, seq_head)
128
154
  when LITERAL then compile_literal(cur_node, token, seq_head)
129
- when PREDICATE then compile_predicate(cur_node, token, seq_head)
155
+ when PREDICATE then compile_predicate(tokens, cur_node, token, seq_head)
130
156
  when NODE then compile_nodetype(cur_node, token)
131
157
  when PARAM then compile_param(cur_node, token[1..-1], seq_head)
132
158
  when CLOSING then fail_due_to("#{token} in invalid position")
@@ -139,6 +165,10 @@ module RuboCop
139
165
  fail_due_to('empty parentheses') if tokens.first == ')'
140
166
  fail_due_to('parentheses at sequence head') if seq_head
141
167
 
168
+ # 'cur_node' is a Ruby expression which evaluates to an AST node,
169
+ # but we don't know how expensive it is
170
+ # to be safe, cache the node in a temp variable and then use the
171
+ # temp variable as 'cur_node'
142
172
  init = "temp#{@temps += 1} = #{cur_node}"
143
173
  cur_node = "temp#{@temps}"
144
174
  terms = compile_seq_terms(tokens, cur_node)
@@ -155,6 +185,9 @@ module RuboCop
155
185
  elsif tokens.first == '$...'
156
186
  return compile_capt_ellip(tokens, cur_node, terms, index || 0)
157
187
  elsif index.nil?
188
+ # in 'sequence head' position; some expressions are compiled
189
+ # differently at 'sequence head' (notably 'node type' expressions)
190
+ # grep for seq_head to see where it makes a difference
158
191
  terms << compile_expr(tokens, cur_node, true)
159
192
  index = 0
160
193
  else
@@ -210,6 +243,10 @@ module RuboCop
210
243
  cur_node = "temp#{@temps}"
211
244
 
212
245
  terms = []
246
+ # we need to ensure that each branch of the {} contains the same
247
+ # number of captures (since only one branch of the {} can actually
248
+ # match, the same variables are used to hold the captures for each
249
+ # branch)
213
250
  captures_before = @captures
214
251
  terms << compile_expr(tokens, cur_node, seq_head)
215
252
  captures_after = @captures
@@ -242,19 +279,17 @@ module RuboCop
242
279
  end
243
280
 
244
281
  def compile_capture(tokens, cur_node, seq_head)
245
- "(#{next_capture} = #{cur_node}#{'.type' if seq_head}; " <<
246
- compile_expr(tokens, cur_node, seq_head) <<
247
- ')'
282
+ "(#{next_capture} = #{cur_node}#{'.type' if seq_head}; " \
283
+ "#{compile_expr(tokens, cur_node, seq_head)})"
248
284
  end
249
285
 
250
286
  def compile_negation(tokens, cur_node, seq_head)
251
- '(!' << compile_expr(tokens, cur_node, seq_head) << ')'
287
+ "(!#{compile_expr(tokens, cur_node, seq_head)})"
252
288
  end
253
289
 
254
290
  def compile_ascend(tokens, cur_node, seq_head)
255
- "(#{cur_node}.parent && " <<
256
- compile_expr(tokens, "#{cur_node}.parent", seq_head) <<
257
- ')'
291
+ "(#{cur_node}.parent && " \
292
+ "#{compile_expr(tokens, "#{cur_node}.parent", seq_head)})"
258
293
  end
259
294
 
260
295
  def compile_wildcard(cur_node, name, seq_head)
@@ -275,8 +310,27 @@ module RuboCop
275
310
  "(#{cur_node}#{'.type' if seq_head} == #{literal})"
276
311
  end
277
312
 
278
- def compile_predicate(cur_node, predicate, seq_head)
279
- "(#{cur_node}#{'.type' if seq_head}.#{predicate})"
313
+ def compile_predicate(tokens, cur_node, predicate, seq_head)
314
+ if predicate.end_with?('(') # is there an arglist?
315
+ args = compile_args(tokens)
316
+ predicate = predicate[0..-2] # drop the trailing (
317
+ "(#{cur_node}#{'.type' if seq_head}.#{predicate}(#{args.join(',')}))"
318
+ else
319
+ "(#{cur_node}#{'.type' if seq_head}.#{predicate})"
320
+ end
321
+ end
322
+
323
+ def compile_funcall(tokens, cur_node, method, seq_head)
324
+ # call a method in the context which this pattern-matching
325
+ # code is used in. pass target value as an argument
326
+ method = method[1..-1] # drop the leading #
327
+ if method.end_with?('(') # is there an arglist?
328
+ args = compile_args(tokens)
329
+ method = method[0..-2] # drop the trailing (
330
+ "(#{method}(#{cur_node}#{'.type' if seq_head}),#{args.join(',')})"
331
+ else
332
+ "(#{method}(#{cur_node}#{'.type' if seq_head}))"
333
+ end
280
334
  end
281
335
 
282
336
  def compile_nodetype(cur_node, type)
@@ -284,17 +338,42 @@ module RuboCop
284
338
  end
285
339
 
286
340
  def compile_param(cur_node, number, seq_head)
287
- number = number.empty? ? 1 : Integer(number)
288
- @params = number if number > @params
289
- "(#{cur_node}#{'.type' if seq_head} == param#{number})"
341
+ "(#{cur_node}#{'.type' if seq_head} == #{get_param(number)})"
342
+ end
343
+
344
+ def compile_args(tokens)
345
+ args = []
346
+ args << compile_arg(tokens.shift) until tokens.first == ')'
347
+ tokens.shift # drop the )
348
+ args
349
+ end
350
+
351
+ def compile_arg(token)
352
+ case token
353
+ when WILDCARD then
354
+ name = token[1..-1]
355
+ number = @unify[name] || fail_due_to('invalid in arglist: ' + token)
356
+ "temp#{number}"
357
+ when LITERAL then token
358
+ when PARAM then get_param(token[1..-1])
359
+ when CLOSING then fail_due_to("#{token} in invalid position")
360
+ when nil then fail_due_to('pattern ended prematurely')
361
+ else fail_due_to("invalid token in arglist: #{token.inspect}")
362
+ end
290
363
  end
291
364
 
292
365
  def next_capture
293
366
  "capture#{@captures += 1}"
294
367
  end
295
368
 
369
+ def get_param(number)
370
+ number = number.empty? ? 1 : Integer(number)
371
+ @params = number if number > @params
372
+ number.zero? ? @root : "param#{number}"
373
+ end
374
+
296
375
  def join_terms(init, terms, operator)
297
- '(' << init << ';' << terms.join(operator) << ')'
376
+ "(#{init};#{terms.join(operator)})"
298
377
  end
299
378
 
300
379
  def emit_capture_list
@@ -315,9 +394,9 @@ module RuboCop
315
394
  (1..@params).map { |n| "param#{n}" }.join(',')
316
395
  end
317
396
 
318
- def emit_trailing_param_list
397
+ def emit_trailing_params
319
398
  params = emit_param_list
320
- params.empty? ? '' : ',' << params
399
+ params.empty? ? '' : ",#{params}"
321
400
  end
322
401
 
323
402
  def emit_method_code
@@ -343,9 +422,12 @@ module RuboCop
343
422
  # return the captures, or `true` if there were none.
344
423
  def def_node_matcher(method_name, pattern_str)
345
424
  compiler = RuboCop::NodePattern::Compiler.new(pattern_str, 'node')
346
- src = "def #{method_name}(node" << compiler.emit_trailing_param_list <<
347
- ');' << compiler.emit_method_code << ';end'
348
- class_eval(src)
425
+ src = "def #{method_name}(node" \
426
+ "#{compiler.emit_trailing_params});" \
427
+ "#{compiler.emit_method_code};end"
428
+
429
+ file, lineno = *caller.first.split(':')
430
+ class_eval(src, file, lineno.to_i)
349
431
  end
350
432
 
351
433
  # Define a method which recurses over the descendants of an AST node,
@@ -363,27 +445,36 @@ module RuboCop
363
445
  yieldval = compiler.emit_capture_list
364
446
  yieldval = 'node' if yieldval.empty?
365
447
  on_match = "yield(#{yieldval})"
366
- prelude = "return enum_for(:#{method_name},node0) unless block_given?"
448
+ prelude = "return enum_for(:#{method_name}, node0" \
449
+ "#{compiler.emit_trailing_params}) unless block_given?"
367
450
  end
368
- src = <<-END
369
- def #{method_name}(node0#{compiler.emit_trailing_param_list})
451
+
452
+ src = node_search_body(method_name, compiler.emit_trailing_params,
453
+ prelude, compiler.match_code, on_match)
454
+ filename, lineno = *caller.first.split(':')
455
+ class_eval(src, filename, lineno.to_i)
456
+ end
457
+
458
+ def node_search_body(method_name, trailing_params, prelude, match_code,
459
+ on_match)
460
+ <<-END
461
+ def #{method_name}(node0#{trailing_params})
370
462
  #{prelude}
371
463
  node0.each_node do |node|
372
- if #{compiler.match_code}
464
+ if #{match_code}
373
465
  #{on_match}
374
466
  end
375
467
  end
376
468
  nil
377
469
  end
378
470
  END
379
- class_eval(src)
380
471
  end
381
472
  end
382
473
 
383
474
  def initialize(str)
384
475
  compiler = Compiler.new(str)
385
- src = 'def match(node0' << compiler.emit_trailing_param_list << ');' <<
386
- compiler.emit_method_code << 'end'
476
+ src = "def match(node0#{compiler.emit_trailing_params});" \
477
+ "#{compiler.emit_method_code}end"
387
478
  instance_eval(src)
388
479
  end
389
480
  end
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'optparse'
4
5
 
5
6
  module RuboCop
6
7
  # This class handles command line options.
7
8
  class Options
8
- DEFAULT_FORMATTER = 'progress'
9
- EXITING_OPTIONS = [:version, :verbose_version, :show_cops]
9
+ EXITING_OPTIONS = [:version, :verbose_version, :show_cops].freeze
10
10
  DEFAULT_MAXIMUM_EXCLUSION_ITEMS = 15
11
11
 
12
12
  def initialize
@@ -70,17 +70,17 @@ module RuboCop
70
70
  def add_configuration_options(opts, args)
71
71
  option(opts, '-c', '--config FILE')
72
72
 
73
- option(opts, '--auto-gen-config') do
74
- @options[:formatters] = [[DEFAULT_FORMATTER],
75
- [Formatter::DisabledConfigFormatter,
76
- ConfigLoader::AUTO_GENERATED_FILE]]
77
- end
73
+ option(opts, '--auto-gen-config')
78
74
 
79
75
  option(opts, '--exclude-limit COUNT') do
80
76
  @validator.validate_exclude_limit_option(args)
81
77
  end
82
78
 
83
79
  option(opts, '--force-exclusion')
80
+
81
+ option(opts, '--no-offense-counts') do
82
+ @options[:no_offense_counts] = true
83
+ end
84
84
  end
85
85
 
86
86
  def add_formatting_options(opts)
@@ -90,8 +90,11 @@ module RuboCop
90
90
  end
91
91
 
92
92
  option(opts, '-o', '--out FILE') do |path|
93
- @options[:formatters] ||= [[DEFAULT_FORMATTER]]
94
- @options[:formatters].last << path
93
+ if @options[:formatters]
94
+ @options[:formatters].last << path
95
+ else
96
+ @options[:output_path] = path
97
+ end
95
98
  end
96
99
  end
97
100
 
@@ -124,8 +127,7 @@ module RuboCop
124
127
  end
125
128
  option(opts, '-a', '--auto-correct')
126
129
 
127
- @options[:color] = true
128
- option(opts, '-n', '--no-color') { @options[:color] = false }
130
+ option(opts, '-n', '--[no-]color') { |c| @options[:color] = c }
129
131
 
130
132
  option(opts, '-v', '--version')
131
133
  option(opts, '-V', '--verbose-version')
@@ -151,16 +153,12 @@ module RuboCop
151
153
  # e.g. [..., '--auto-correct', ...] to :auto_correct.
152
154
  def long_opt_symbol(args)
153
155
  long_opt = args.find { |arg| arg.start_with?('--') }
154
- long_opt[2..-1].sub(/ .*/, '').tr('-', '_').to_sym
156
+ long_opt[2..-1].sub(/ .*/, '').tr('-', '_').gsub(/[\[\]]/, '').to_sym
155
157
  end
156
158
  end
157
159
 
158
- # Validates option arguments and the options' compatibilty with each other.
160
+ # Validates option arguments and the options' compatibility with each other.
159
161
  class OptionsValidator
160
- def initialize(options)
161
- @options = options
162
- end
163
-
164
162
  # Cop name validation must be done later than option parsing, so it's not
165
163
  # called from within Options.
166
164
  def self.validate_cop_list(names)
@@ -176,6 +174,10 @@ module RuboCop
176
174
  end
177
175
  end
178
176
 
177
+ def initialize(options)
178
+ @options = options
179
+ end
180
+
179
181
  def validate_compatibility
180
182
  if @options.key?(:only) &&
181
183
  (@options[:only] & %w(Lint/UnneededDisable UnneededDisable)).any?
@@ -188,6 +190,10 @@ module RuboCop
188
190
  if @options.key?(:cache) && !%w(true false).include?(@options[:cache])
189
191
  fail ArgumentError, '-C/--cache argument must be true or false'
190
192
  end
193
+ if @options.key?(:no_offense_counts) && !@options.key?(:auto_gen_config)
194
+ fail ArgumentError, '--no-offense-counts can only be used together ' \
195
+ 'with --auto-gen-config.'
196
+ end
191
197
  return if (incompat = @options.keys & Options::EXITING_OPTIONS).size <= 1
192
198
  fail ArgumentError, "Incompatible cli options: #{incompat.inspect}"
193
199
  end
@@ -220,6 +226,8 @@ module RuboCop
220
226
  config: 'Specify configuration file.',
221
227
  auto_gen_config: ['Generate a configuration file acting as a',
222
228
  'TODO list.'],
229
+ no_offense_counts: ['Do not include offense counts in configuration',
230
+ 'file generated by --auto-gen-config.'],
223
231
  exclude_limit: ['Used together with --auto-gen-config to',
224
232
  'set the limit for how many Exclude',
225
233
  "properties to generate. Default is #{MAX_EXCL}."],
@@ -239,6 +247,7 @@ module RuboCop
239
247
  ' [h]tml',
240
248
  ' [fi]les',
241
249
  ' [o]ffenses',
250
+ ' [w]orst',
242
251
  ' custom formatter class name'],
243
252
  out: ['Write output to a file instead of STDOUT.',
244
253
  'This option applies to the previously',
@@ -263,11 +272,11 @@ module RuboCop
263
272
  lint: 'Run only lint cops.',
264
273
  list_target_files: 'List all files RuboCop will inspect.',
265
274
  auto_correct: 'Auto-correct offenses.',
266
- no_color: 'Disable color output.',
275
+ no_color: 'Force color output on or off.',
267
276
  version: 'Display version.',
268
277
  verbose_version: 'Display verbose version.',
269
278
  stdin: ['Pipe source from STDIN.',
270
279
  'This is useful for editor integration.']
271
- }
280
+ }.freeze
272
281
  end
273
282
  end