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,24 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ class Node
5
+ # `RuboCop::Builder` is an AST builder that is utilized to let `Parser`
6
+ # generate ASTs with {RuboCop::Node}.
7
+ #
8
+ # @example
9
+ # buffer = Parser::Source::Buffer.new('(string)')
10
+ # buffer.source = 'puts :foo'
11
+ #
12
+ # builder = RuboCop::Builder.new
13
+ # parser = Parser::CurrentRuby.new(builder)
14
+ # root_node = parser.parse(buffer)
15
+ class Builder < Parser::Builders::Default
16
+ # Generates {Node} from the given information.
17
+ #
18
+ # @return [Node] the generated node
19
+ def n(type, children, source_map)
20
+ Node.new(type, children, location: source_map)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: utf-8
2
+
3
+ module RuboCop
4
+ # This module provides a shorthand method to create a {Node} like `AST::Sexp`.
5
+ #
6
+ # @see http://rubydoc.info/gems/ast/AST/Sexp
7
+ module Sexp
8
+ # Creates a {Node} with type `type` and children `children`.
9
+ def s(type, *children)
10
+ Node.new(type, children)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'json'
5
+
6
+ module RuboCop
7
+ # Converts RuboCop objects to and from the serialization format JSON.
8
+ class CachedData
9
+ def initialize(filename)
10
+ @filename = filename
11
+ end
12
+
13
+ def from_json(text)
14
+ deserialize_offenses(JSON.load(text))
15
+ end
16
+
17
+ def to_json(offenses)
18
+ JSON.dump(offenses.map { |o| serialize_offense(o) })
19
+ end
20
+
21
+ private
22
+
23
+ def serialize_offense(offense)
24
+ # JSON.dump will fail if the offense message contains text which is not
25
+ # valid UTF-8
26
+ message = offense.message
27
+ message = if message.respond_to?(:scrub)
28
+ message.scrub
29
+ else
30
+ message.chars.select(&:valid_encoding?).join
31
+ end
32
+
33
+ {
34
+ severity: offense.severity,
35
+ location: {
36
+ begin_pos: offense.location.begin_pos,
37
+ end_pos: offense.location.end_pos
38
+ },
39
+ message: message,
40
+ cop_name: offense.cop_name,
41
+ status: offense.status
42
+ }
43
+ end
44
+
45
+ # Restore an offense object loaded from a JSON file.
46
+ def deserialize_offenses(offenses)
47
+ source_buffer = Parser::Source::Buffer.new(@filename)
48
+ source_buffer.read
49
+ offenses.map! do |o|
50
+ location = Parser::Source::Range.new(source_buffer,
51
+ o['location']['begin_pos'],
52
+ o['location']['end_pos'])
53
+ Cop::Offense.new(o['severity'], location, o['message'], o['cop_name'],
54
+ o['status'].to_sym)
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
  # The CLI is a class responsible of handling all the command line interface
@@ -6,6 +7,8 @@ module RuboCop
6
7
  class CLI
7
8
  include Formatter::TextUtil
8
9
 
10
+ class Finished < Exception; end
11
+
9
12
  attr_reader :options, :config_store
10
13
 
11
14
  def initialize
@@ -20,22 +23,25 @@ module RuboCop
20
23
  def run(args = ARGV)
21
24
  @options, paths = Options.new.parse(args)
22
25
  act_on_options
26
+ apply_default_formatter
23
27
 
24
28
  runner = Runner.new(@options, @config_store)
25
29
  trap_interrupt(runner)
26
30
  all_passed = runner.run(paths)
27
31
  display_warning_summary(runner.warnings)
28
32
  display_error_summary(runner.errors)
33
+ maybe_print_corrected_source
29
34
 
30
35
  all_passed && !runner.aborting? && runner.errors.empty? ? 0 : 1
31
- rescue Cop::AmbiguousCopName => e
32
- $stderr.puts "Ambiguous cop name #{e.message} needs namespace " \
33
- 'qualifier.'
34
- return 1
36
+ rescue RuboCop::Error => e
37
+ $stderr.puts Rainbow("Error: #{e.message}").red
38
+ return 2
39
+ rescue Finished
40
+ return 0
35
41
  rescue StandardError, SyntaxError => e
36
42
  $stderr.puts e.message
37
43
  $stderr.puts e.backtrace
38
- return 1
44
+ return 2
39
45
  end
40
46
 
41
47
  def trap_interrupt(runner)
@@ -54,11 +60,16 @@ module RuboCop
54
60
 
55
61
  ConfigLoader.debug = @options[:debug]
56
62
  ConfigLoader.auto_gen_config = @options[:auto_gen_config]
57
- ConfigLoader.exclude_limit = @options[:exclude_limit]
58
63
 
59
64
  @config_store.options_config = @options[:config] if @options[:config]
60
65
 
61
- Rainbow.enabled = false unless @options[:color]
66
+ if @options[:color]
67
+ # color output explicitly forced on
68
+ Rainbow.enabled = true
69
+ elsif @options[:color] == false
70
+ # color output explicitly forced off
71
+ Rainbow.enabled = false
72
+ end
62
73
  end
63
74
 
64
75
  def handle_exiting_options
@@ -67,7 +78,22 @@ module RuboCop
67
78
  puts RuboCop::Version.version(false) if @options[:version]
68
79
  puts RuboCop::Version.version(true) if @options[:verbose_version]
69
80
  print_available_cops if @options[:show_cops]
70
- exit(0)
81
+ fail Finished
82
+ end
83
+
84
+ def apply_default_formatter
85
+ # This must be done after the options have already been processed,
86
+ # because they can affect how ConfigStore behaves
87
+ @options[:formatters] ||= begin
88
+ cfg = @config_store.for(Dir.pwd)['AllCops']
89
+ formatter = (cfg && cfg['DefaultFormatter']) || 'progress'
90
+ [[formatter, @options[:output_path]]]
91
+ end
92
+
93
+ if @options[:auto_gen_config]
94
+ @options[:formatters] << [Formatter::DisabledConfigFormatter,
95
+ ConfigLoader::AUTO_GENERATED_FILE]
96
+ end
71
97
  end
72
98
 
73
99
  def print_available_cops
@@ -95,8 +121,8 @@ module RuboCop
95
121
  selected_cops.each do |cop|
96
122
  puts '# Supports --auto-correct' if cop.new.support_autocorrect?
97
123
  puts "#{cop.cop_name}:"
98
- cnf = @config_store.for(Dir.pwd.to_s).for_cop(cop)
99
- puts cnf.to_yaml.lines.to_a[1..-1].map { |line| ' ' + line }
124
+ cnf = @config_store.for(Dir.pwd).for_cop(cop)
125
+ puts cnf.to_yaml.lines.to_a.butfirst.map { |line| ' ' + line }
100
126
  puts
101
127
  end
102
128
  end
@@ -123,5 +149,16 @@ module RuboCop
123
149
  #{RuboCop::Version.version(true)}
124
150
  END
125
151
  end
152
+
153
+ def maybe_print_corrected_source
154
+ # If we are asked to autocorrect source code read from stdin, the only
155
+ # reasonable place to write it is to stdout
156
+ # Unfortunately, we also write other information to stdout
157
+ # So a delimiter is needed for tools to easily identify where the
158
+ # autocorrected source begins
159
+ return unless @options[:stdin] && @options[:auto_correct]
160
+ puts '=' * 20
161
+ print @options[:stdin]
162
+ end
126
163
  end
127
164
  end
@@ -1,10 +1,11 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module RuboCop
4
5
  # This class parses the special `rubocop:disable` comments in a source
5
6
  # and provides a way to check if each cop is enabled at arbitrary line.
6
7
  class CommentConfig
7
- UNNEEDED_DISABLE = 'Lint/UnneededDisable'
8
+ UNNEEDED_DISABLE = 'Lint/UnneededDisable'.freeze
8
9
  COMMENT_DIRECTIVE_REGEXP = Regexp.new(
9
10
  '\A# rubocop : ((?:dis|en)able)\b ((?:[\w/]+,? )+)'.gsub(' ', '\s*')
10
11
  )
@@ -35,6 +36,12 @@ module RuboCop
35
36
  if single_line
36
37
  disabled_line_ranges[cop_name] << (line..line) if disabled
37
38
  elsif disabled
39
+ if disablement_start_line_numbers[cop_name]
40
+ # Cop already disabled on this line, so we end the current disabled
41
+ # range before we start a new range.
42
+ start_line = disablement_start_line_numbers.delete(cop_name)
43
+ disabled_line_ranges[cop_name] << (start_line..line)
44
+ end
38
45
  disablement_start_line_numbers[cop_name] = line
39
46
  else
40
47
  start_line = disablement_start_line_numbers.delete(cop_name)
@@ -66,7 +73,7 @@ module RuboCop
66
73
  single_line = !comment_only_line?(comment_line_number)
67
74
 
68
75
  cop_names.each do |cop_name|
69
- cop_name = Cop::Cop.qualified_cop_name(cop_name,
76
+ cop_name = Cop::Cop.qualified_cop_name(cop_name.strip,
70
77
  processed_source.buffer.name)
71
78
  yield cop_name, disabled, comment_line_number, single_line
72
79
  end
@@ -1,20 +1,22 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
- require 'delegate'
4
4
  require 'pathname'
5
5
 
6
+ # rubocop:disable Metrics/ClassLength
7
+
6
8
  module RuboCop
7
9
  # This class represents the configuration of the RuboCop application
8
10
  # and all its cops. A Config is associated with a YAML configuration
9
11
  # file from which it was read. Several different Configs can be used
10
12
  # during a run of the rubocop program, if files in several
11
13
  # directories are inspected.
12
- class Config < DelegateClass(Hash)
14
+ class Config < Hash
13
15
  include PathUtil
14
16
 
15
- class ValidationError < StandardError; end
16
-
17
- COMMON_PARAMS = %w(Exclude Include Severity AutoCorrect StyleGuide Details)
17
+ COMMON_PARAMS = %w(Exclude Include Severity
18
+ AutoCorrect StyleGuide Details).freeze
19
+ KNOWN_RUBIES = [1.9, 2.0, 2.1, 2.2, 2.3].freeze
18
20
 
19
21
  attr_reader :loaded_path
20
22
 
@@ -23,15 +25,11 @@ module RuboCop
23
25
  @for_cop = Hash.new do |h, cop|
24
26
  h[cop] = self[Cop::Cop.qualified_cop_name(cop, loaded_path)] || {}
25
27
  end
26
- super(hash)
27
- end
28
-
29
- def to_s
30
- @to_s ||= __getobj__.to_s
28
+ replace(hash)
31
29
  end
32
30
 
33
31
  def make_excludes_absolute
34
- keys.each do |key|
32
+ each_key do |key|
35
33
  validate_section_presence(key)
36
34
  next unless self[key]['Exclude']
37
35
 
@@ -61,8 +59,7 @@ module RuboCop
61
59
  end
62
60
 
63
61
  def deprecation_check
64
- all_cops = self['AllCops']
65
- return unless all_cops
62
+ return unless (all_cops = self['AllCops'])
66
63
 
67
64
  %w(Exclude Include).each do |key|
68
65
  plural = "#{key}s"
@@ -79,13 +76,17 @@ module RuboCop
79
76
  end
80
77
 
81
78
  def cop_enabled?(cop)
82
- for_cop(cop).empty? || for_cop(cop)['Enabled']
83
- end
79
+ department = if cop.respond_to?(:cop_type)
80
+ cop.cop_type.to_s.capitalize
81
+ else
82
+ cop.split('/')[-2]
83
+ end
84
+
85
+ if (dept_config = self[department])
86
+ return false if dept_config['Enabled'] == false
87
+ end
84
88
 
85
- def warn_unless_valid
86
- validate
87
- rescue Config::ValidationError => e
88
- warn Rainbow.new.wrap("Warning: #{e.message}").red
89
+ for_cop(cop).empty? || for_cop(cop)['Enabled']
89
90
  end
90
91
 
91
92
  def add_missing_namespaces
@@ -98,7 +99,6 @@ module RuboCop
98
99
  end
99
100
  end
100
101
 
101
- # TODO: This should be a private method
102
102
  def validate
103
103
  # Don't validate RuboCop's own files. Avoids infinite recursion.
104
104
  base_config_path = File.expand_path(File.join(ConfigLoader::RUBOCOP_HOME,
@@ -109,11 +109,12 @@ module RuboCop
109
109
  ConfigLoader.default_configuration.key?(key)
110
110
  end
111
111
 
112
- invalid_cop_names.each do |name|
113
- fail ValidationError, "unrecognized cop #{name} found in #{loaded_path}"
114
- end
115
-
112
+ reject_obsolete_cops
113
+ warn_about_unrecognized_cops(invalid_cop_names)
114
+ reject_obsolete_parameters
115
+ check_target_ruby
116
116
  validate_parameter_names(valid_cop_names)
117
+ validate_enforced_styles(valid_cop_names)
117
118
  end
118
119
 
119
120
  def file_to_include?(file)
@@ -136,12 +137,9 @@ module RuboCop
136
137
  # Returns true if there's a chance that an Include pattern matches hidden
137
138
  # files, false if that's definitely not possible.
138
139
  def possibly_include_hidden?
139
- if @possibly_include_hidden.nil?
140
- @possibly_include_hidden = patterns_to_include.any? do |s|
141
- s.is_a?(Regexp) || s.start_with?('.') || s.include?('/.')
142
- end
140
+ @possibly_include_hidden ||= patterns_to_include.any? do |s|
141
+ s.is_a?(Regexp) || s.start_with?('.') || s.include?('/.')
143
142
  end
144
- @possibly_include_hidden
145
143
  end
146
144
 
147
145
  def file_to_exclude?(file)
@@ -181,6 +179,22 @@ module RuboCop
181
179
 
182
180
  private
183
181
 
182
+ def warn_about_unrecognized_cops(invalid_cop_names)
183
+ invalid_cop_names.each do |name|
184
+ if name == 'Syntax'
185
+ fail ValidationError,
186
+ "configuration for Syntax cop found in #{loaded_path}\n" \
187
+ 'This cop cannot be configured.'
188
+ end
189
+
190
+ # There could be a custom cop with this name. If so, don't warn
191
+ next if Cop::Cop.all.any? { |c| c.match?([name]) }
192
+
193
+ warn Rainbow("Warning: unrecognized cop #{name} found in " \
194
+ "#{loaded_path}").yellow
195
+ end
196
+ end
197
+
184
198
  def validate_section_presence(name)
185
199
  return unless key?(name) && self[name].nil?
186
200
  fail ValidationError, "empty section #{name} found in #{loaded_path}"
@@ -193,10 +207,64 @@ module RuboCop
193
207
  next if COMMON_PARAMS.include?(param) ||
194
208
  ConfigLoader.default_configuration[name].key?(param)
195
209
 
196
- fail ValidationError,
197
- "unrecognized parameter #{name}:#{param} found in #{loaded_path}"
210
+ warn Rainbow("Warning: unrecognized parameter #{name}:#{param} " \
211
+ "found in #{loaded_path}").yellow
198
212
  end
199
213
  end
200
214
  end
215
+
216
+ def validate_enforced_styles(valid_cop_names)
217
+ valid_cop_names.each do |name|
218
+ next unless (style = self[name]['EnforcedStyle'])
219
+ valid = ConfigLoader.default_configuration[name]['SupportedStyles']
220
+ next if valid.include?(style)
221
+
222
+ msg = "invalid EnforcedStyle '#{style}' for #{name} found in " \
223
+ "#{loaded_path}\n" \
224
+ "Valid choices are: #{valid.join(', ')}"
225
+ fail ValidationError, msg
226
+ end
227
+ end
228
+
229
+ def reject_obsolete_parameters
230
+ check_obsolete_parameter('Style/SpaceAroundOperators',
231
+ 'MultiSpaceAllowedForOperators',
232
+ 'If your intention was to allow extra spaces ' \
233
+ 'for alignment, please use AllowForAlignment: ' \
234
+ 'true instead.')
235
+ check_obsolete_parameter('AllCops', 'RunRailsCops',
236
+ "Use the following configuration instead:\n" \
237
+ "Rails:\n Enabled: true")
238
+ end
239
+
240
+ def check_obsolete_parameter(cop, parameter, alternative = nil)
241
+ if key?(cop) && self[cop].key?(parameter)
242
+ fail ValidationError, "obsolete parameter #{parameter} (for #{cop}) " \
243
+ "found in #{loaded_path}" \
244
+ "#{"\n" if alternative}#{alternative}"
245
+ end
246
+ end
247
+
248
+ def reject_obsolete_cops
249
+ if key?('Style/TrailingComma')
250
+ fail ValidationError, 'The `Style/TrailingComma` cop no longer ' \
251
+ 'exists. Please use ' \
252
+ '`Style/TrailingCommaInLiteral` and/or ' \
253
+ "`Style/TrailingCommaInArguments` instead.\n" \
254
+ "(configuration found in #{loaded_path})"
255
+ end
256
+ end
257
+
258
+ def check_target_ruby
259
+ target = self['AllCops'] && self['AllCops']['TargetRubyVersion']
260
+ return unless target
261
+
262
+ unless KNOWN_RUBIES.include?(target)
263
+ fail ValidationError, "Unknown Ruby version #{target.inspect} found " \
264
+ 'in `TargetRubyVersion` parameter (in ' \
265
+ "#{loaded_path}).\nKnown versions: " \
266
+ "#{KNOWN_RUBIES.join(', ')}"
267
+ end
268
+ end
201
269
  end
202
270
  end