rubocop 0.83.0 → 0.87.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -18
  3. data/config/default.yml +128 -23
  4. data/lib/rubocop.rb +21 -59
  5. data/lib/rubocop/ast_aliases.rb +8 -0
  6. data/lib/rubocop/cli.rb +2 -4
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +42 -7
  8. data/lib/rubocop/cli/command/init_dotfile.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +2 -6
  10. data/lib/rubocop/comment_config.rb +1 -1
  11. data/lib/rubocop/config.rb +1 -1
  12. data/lib/rubocop/config_loader.rb +24 -70
  13. data/lib/rubocop/config_loader_resolver.rb +21 -9
  14. data/lib/rubocop/config_obsoletion.rb +0 -1
  15. data/lib/rubocop/config_store.rb +12 -2
  16. data/lib/rubocop/cop/autocorrect_logic.rb +14 -25
  17. data/lib/rubocop/cop/base.rb +399 -0
  18. data/lib/rubocop/cop/bundler/gem_comment.rb +70 -1
  19. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +10 -20
  20. data/lib/rubocop/cop/commissioner.rb +48 -71
  21. data/lib/rubocop/cop/cop.rb +91 -227
  22. data/lib/rubocop/cop/corrector.rb +38 -115
  23. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -6
  24. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +1 -1
  25. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  26. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -3
  27. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  28. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  29. data/lib/rubocop/cop/generator.rb +2 -2
  30. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  31. data/lib/rubocop/cop/ignored_node.rb +1 -3
  32. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +11 -14
  33. data/lib/rubocop/cop/layout/case_indentation.rb +21 -22
  34. data/lib/rubocop/cop/layout/class_structure.rb +19 -16
  35. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
  36. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  37. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -6
  38. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +57 -4
  39. data/lib/rubocop/cop/layout/end_of_line.rb +3 -3
  40. data/lib/rubocop/cop/layout/first_argument_indentation.rb +6 -4
  41. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -3
  42. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  43. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -3
  44. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  45. data/lib/rubocop/cop/layout/hash_alignment.rb +8 -9
  46. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -7
  47. data/lib/rubocop/cop/layout/heredoc_indentation.rb +20 -103
  48. data/lib/rubocop/cop/layout/indentation_width.rb +1 -3
  49. data/lib/rubocop/cop/layout/line_length.rb +17 -17
  50. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -2
  51. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -3
  52. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  53. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +19 -25
  54. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  55. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -3
  56. data/lib/rubocop/cop/layout/space_around_operators.rb +1 -1
  57. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  58. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  59. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
  60. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  61. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  62. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -3
  63. data/lib/rubocop/cop/legacy/corrections_proxy.rb +49 -0
  64. data/lib/rubocop/cop/legacy/corrector.rb +29 -0
  65. data/lib/rubocop/cop/lint/ambiguous_operator.rb +5 -2
  66. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  67. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +137 -0
  68. data/lib/rubocop/cop/lint/ensure_return.rb +1 -1
  69. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -3
  70. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  71. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
  72. data/lib/rubocop/cop/lint/interpolation_check.rb +13 -0
  73. data/lib/rubocop/cop/lint/loop.rb +1 -1
  74. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +69 -0
  75. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  76. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  77. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +2 -2
  78. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +7 -7
  79. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +20 -5
  80. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -4
  81. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  82. data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
  83. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  84. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +31 -25
  85. data/lib/rubocop/cop/lint/redundant_require_statement.rb +3 -3
  86. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +2 -2
  87. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  88. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  89. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +9 -1
  90. data/lib/rubocop/cop/lint/suppressed_exception.rb +15 -2
  91. data/lib/rubocop/cop/lint/syntax.rb +11 -28
  92. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  93. data/lib/rubocop/cop/lint/unused_method_argument.rb +1 -1
  94. data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -4
  95. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +1 -1
  96. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  97. data/lib/rubocop/cop/metrics/block_length.rb +22 -0
  98. data/lib/rubocop/cop/metrics/class_length.rb +25 -2
  99. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
  100. data/lib/rubocop/cop/metrics/method_length.rb +23 -0
  101. data/lib/rubocop/cop/metrics/module_length.rb +25 -2
  102. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  103. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +129 -0
  104. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  105. data/lib/rubocop/cop/migration/department_name.rb +7 -7
  106. data/lib/rubocop/cop/mixin/alignment.rb +1 -3
  107. data/lib/rubocop/cop/mixin/allowed_methods.rb +19 -0
  108. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -3
  109. data/lib/rubocop/cop/mixin/auto_corrector.rb +12 -0
  110. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -9
  111. data/lib/rubocop/cop/mixin/code_length.rb +4 -0
  112. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -3
  113. data/lib/rubocop/cop/mixin/configurable_formatting.rb +3 -5
  114. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  115. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  116. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  117. data/lib/rubocop/cop/mixin/enforce_superclass.rb +3 -1
  118. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  119. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  120. data/lib/rubocop/cop/mixin/line_length_help.rb +1 -1
  121. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  122. data/lib/rubocop/cop/mixin/nil_methods.rb +3 -5
  123. data/lib/rubocop/cop/mixin/ordered_gem_node.rb +6 -1
  124. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  125. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  126. data/lib/rubocop/cop/mixin/range_help.rb +1 -1
  127. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +43 -0
  128. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  129. data/lib/rubocop/cop/mixin/surrounding_space.rb +10 -5
  130. data/lib/rubocop/cop/mixin/too_many_lines.rb +3 -13
  131. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
  132. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +7 -5
  133. data/lib/rubocop/cop/naming/ascii_identifiers.rb +27 -4
  134. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +3 -3
  135. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +11 -1
  136. data/lib/rubocop/cop/naming/file_name.rb +28 -17
  137. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
  138. data/lib/rubocop/cop/naming/method_name.rb +1 -1
  139. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  140. data/lib/rubocop/cop/naming/predicate_name.rb +4 -6
  141. data/lib/rubocop/cop/naming/variable_name.rb +1 -1
  142. data/lib/rubocop/cop/naming/variable_number.rb +1 -1
  143. data/lib/rubocop/cop/offense.rb +16 -2
  144. data/lib/rubocop/cop/registry.rb +63 -10
  145. data/lib/rubocop/cop/severity.rb +1 -3
  146. data/lib/rubocop/cop/style/accessor_grouping.rb +136 -0
  147. data/lib/rubocop/cop/style/and_or.rb +2 -2
  148. data/lib/rubocop/cop/style/array_join.rb +1 -1
  149. data/lib/rubocop/cop/style/attr.rb +1 -3
  150. data/lib/rubocop/cop/style/bare_percent_literals.rb +2 -2
  151. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +121 -0
  152. data/lib/rubocop/cop/style/block_delimiters.rb +4 -12
  153. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  154. data/lib/rubocop/cop/style/class_vars.rb +21 -0
  155. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  156. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  157. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -4
  158. data/lib/rubocop/cop/style/copyright.rb +5 -5
  159. data/lib/rubocop/cop/style/date_time.rb +1 -1
  160. data/lib/rubocop/cop/style/dir.rb +2 -2
  161. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  162. data/lib/rubocop/cop/style/documentation.rb +2 -2
  163. data/lib/rubocop/cop/style/double_negation.rb +41 -4
  164. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
  165. data/lib/rubocop/cop/style/empty_literal.rb +6 -8
  166. data/lib/rubocop/cop/style/empty_method.rb +1 -1
  167. data/lib/rubocop/cop/style/encoding.rb +1 -1
  168. data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -2
  169. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  170. data/lib/rubocop/cop/style/format_string_token.rb +2 -3
  171. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -6
  172. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
  173. data/lib/rubocop/cop/style/hash_syntax.rb +16 -7
  174. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  175. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  176. data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -0
  177. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  178. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  179. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  180. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -3
  181. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -3
  182. data/lib/rubocop/cop/style/multiline_block_chain.rb +10 -1
  183. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  184. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  185. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
  186. data/lib/rubocop/cop/style/mutable_constant.rb +4 -4
  187. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  188. data/lib/rubocop/cop/style/negated_unless.rb +3 -3
  189. data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +2 -5
  190. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  191. data/lib/rubocop/cop/style/next.rb +2 -2
  192. data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
  193. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  194. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -6
  195. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  196. data/lib/rubocop/cop/style/proc.rb +1 -1
  197. data/lib/rubocop/cop/style/random_with_offset.rb +4 -10
  198. data/lib/rubocop/cop/style/redundant_assignment.rb +117 -0
  199. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  200. data/lib/rubocop/cop/style/redundant_exception.rb +14 -10
  201. data/lib/rubocop/cop/style/redundant_fetch_block.rb +122 -0
  202. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  203. data/lib/rubocop/cop/style/redundant_parentheses.rb +10 -8
  204. data/lib/rubocop/cop/style/redundant_percent_q.rb +3 -3
  205. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +90 -0
  206. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +121 -0
  207. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  208. data/lib/rubocop/cop/style/rescue_standard_error.rb +1 -1
  209. data/lib/rubocop/cop/style/safe_navigation.rb +2 -6
  210. data/lib/rubocop/cop/style/sample.rb +1 -1
  211. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  212. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  213. data/lib/rubocop/cop/style/slicing_with_range.rb +1 -1
  214. data/lib/rubocop/cop/style/special_global_vars.rb +2 -6
  215. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  216. data/lib/rubocop/cop/style/struct_inheritance.rb +23 -2
  217. data/lib/rubocop/cop/style/symbol_array.rb +5 -5
  218. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  219. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -4
  220. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +3 -3
  221. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +3 -3
  222. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +13 -13
  223. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +3 -3
  224. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -3
  225. data/lib/rubocop/cop/style/trivial_accessors.rb +8 -7
  226. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  227. data/lib/rubocop/cop/style/when_then.rb +1 -1
  228. data/lib/rubocop/cop/style/word_array.rb +1 -1
  229. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  230. data/lib/rubocop/cop/style/zero_length_predicate.rb +2 -2
  231. data/lib/rubocop/cop/team.rb +141 -81
  232. data/lib/rubocop/cop/util.rb +3 -3
  233. data/lib/rubocop/cop/utils/format_string.rb +19 -2
  234. data/lib/rubocop/cop/variable_force.rb +3 -9
  235. data/lib/rubocop/cop/variable_force/branch.rb +1 -3
  236. data/lib/rubocop/cop/variable_force/variable.rb +2 -6
  237. data/lib/rubocop/ext/processed_source.rb +18 -0
  238. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  239. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -13
  240. data/lib/rubocop/formatter/formatter_set.rb +2 -4
  241. data/lib/rubocop/formatter/junit_formatter.rb +14 -4
  242. data/lib/rubocop/magic_comment.rb +1 -1
  243. data/lib/rubocop/name_similarity.rb +7 -3
  244. data/lib/rubocop/options.rb +30 -15
  245. data/lib/rubocop/path_util.rb +2 -2
  246. data/lib/rubocop/platform.rb +1 -1
  247. data/lib/rubocop/rake_task.rb +6 -9
  248. data/lib/rubocop/remote_config.rb +1 -3
  249. data/lib/rubocop/result_cache.rb +5 -7
  250. data/lib/rubocop/rspec/cop_helper.rb +5 -28
  251. data/lib/rubocop/rspec/expect_offense.rb +60 -23
  252. data/lib/rubocop/rspec/shared_contexts.rb +55 -17
  253. data/lib/rubocop/runner.rb +42 -38
  254. data/lib/rubocop/target_finder.rb +2 -4
  255. data/lib/rubocop/target_ruby.rb +5 -2
  256. data/lib/rubocop/version.rb +5 -3
  257. metadata +60 -62
  258. data/lib/rubocop/ast/builder.rb +0 -85
  259. data/lib/rubocop/ast/node.rb +0 -637
  260. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  261. data/lib/rubocop/ast/node/and_node.rb +0 -29
  262. data/lib/rubocop/ast/node/args_node.rb +0 -29
  263. data/lib/rubocop/ast/node/array_node.rb +0 -70
  264. data/lib/rubocop/ast/node/block_node.rb +0 -121
  265. data/lib/rubocop/ast/node/break_node.rb +0 -17
  266. data/lib/rubocop/ast/node/case_match_node.rb +0 -56
  267. data/lib/rubocop/ast/node/case_node.rb +0 -56
  268. data/lib/rubocop/ast/node/class_node.rb +0 -31
  269. data/lib/rubocop/ast/node/def_node.rb +0 -82
  270. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  271. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  272. data/lib/rubocop/ast/node/float_node.rb +0 -12
  273. data/lib/rubocop/ast/node/for_node.rb +0 -53
  274. data/lib/rubocop/ast/node/forward_args_node.rb +0 -18
  275. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  276. data/lib/rubocop/ast/node/if_node.rb +0 -175
  277. data/lib/rubocop/ast/node/int_node.rb +0 -12
  278. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  279. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  280. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  281. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  282. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  283. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  284. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -269
  285. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  286. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  287. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  288. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  289. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  290. data/lib/rubocop/ast/node/module_node.rb +0 -24
  291. data/lib/rubocop/ast/node/or_node.rb +0 -29
  292. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  293. data/lib/rubocop/ast/node/range_node.rb +0 -18
  294. data/lib/rubocop/ast/node/regexp_node.rb +0 -33
  295. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  296. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  297. data/lib/rubocop/ast/node/return_node.rb +0 -24
  298. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  299. data/lib/rubocop/ast/node/send_node.rb +0 -17
  300. data/lib/rubocop/ast/node/str_node.rb +0 -16
  301. data/lib/rubocop/ast/node/super_node.rb +0 -21
  302. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  303. data/lib/rubocop/ast/node/until_node.rb +0 -35
  304. data/lib/rubocop/ast/node/when_node.rb +0 -53
  305. data/lib/rubocop/ast/node/while_node.rb +0 -35
  306. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  307. data/lib/rubocop/ast/sexp.rb +0 -16
  308. data/lib/rubocop/ast/traversal.rb +0 -202
  309. data/lib/rubocop/cop/mixin/classish_length.rb +0 -37
  310. data/lib/rubocop/node_pattern.rb +0 -887
  311. data/lib/rubocop/processed_source.rb +0 -213
  312. data/lib/rubocop/token.rb +0 -114
@@ -5,7 +5,25 @@ module RuboCop
5
5
  module Bundler
6
6
  # Add a comment describing each gem in your Gemfile.
7
7
  #
8
- # @example
8
+ # Optionally, the "OnlyFor" configuration
9
+ # can be used to only register offenses when the gems
10
+ # use certain options or have version specifiers.
11
+ # Add "version_specifiers" and/or the gem option names
12
+ # you want to check.
13
+ #
14
+ # A useful use-case is to enforce a comment when using
15
+ # options that change the source of a gem:
16
+ #
17
+ # - `bitbucket`
18
+ # - `gist`
19
+ # - `git`
20
+ # - `github`
21
+ # - `source`
22
+ #
23
+ # For a full list of options supported by bundler,
24
+ # you can check the https://bundler.io/man/gemfile.5.html[official documentation].
25
+ #
26
+ # @example OnlyFor: [] (default)
9
27
  # # bad
10
28
  #
11
29
  # gem 'foo'
@@ -15,10 +33,37 @@ module RuboCop
15
33
  # # Helpers for the foo things.
16
34
  # gem 'foo'
17
35
  #
36
+ # @example OnlyFor: ['version_specifiers']
37
+ # # bad
38
+ #
39
+ # gem 'foo', '< 2.1'
40
+ #
41
+ # # good
42
+ #
43
+ # # Version 2.1 introduces breaking change baz
44
+ # gem 'foo', '< 2.1'
45
+ #
46
+ # @example OnlyFor: ['version_specifiers', 'github']
47
+ # # bad
48
+ #
49
+ # gem 'foo', github: 'some_account/some_fork_of_foo'
50
+ #
51
+ # gem 'bar', '< 2.1'
52
+ #
53
+ # # good
54
+ #
55
+ # # Using this fork because baz
56
+ # gem 'foo', github: 'some_account/some_fork_of_foo'
57
+ #
58
+ # # Version 2.1 introduces breaking change baz
59
+ # gem 'bar', '< 2.1'
60
+ #
18
61
  class GemComment < Cop
19
62
  include DefNode
20
63
 
21
64
  MSG = 'Missing gem description comment.'
65
+ CHECKED_OPTIONS_CONFIG = 'OnlyFor'
66
+ VERSION_SPECIFIERS_OPTION = 'version_specifiers'
22
67
 
23
68
  def_node_matcher :gem_declaration?, '(send nil? :gem str ...)'
24
69
 
@@ -26,6 +71,7 @@ module RuboCop
26
71
  return unless gem_declaration?(node)
27
72
  return if ignored_gem?(node)
28
73
  return if commented?(node)
74
+ return if cop_config[CHECKED_OPTIONS_CONFIG].any? && !checked_options_present?(node)
29
75
 
30
76
  add_offense(node)
31
77
  end
@@ -58,6 +104,29 @@ module RuboCop
58
104
  ignored_gems = Array(cop_config['IgnoredGems'])
59
105
  ignored_gems.include?(node.first_argument.value)
60
106
  end
107
+
108
+ def checked_options_present?(node)
109
+ (cop_config[CHECKED_OPTIONS_CONFIG].include?(VERSION_SPECIFIERS_OPTION) &&
110
+ version_specified_gem?(node)) ||
111
+ contains_checked_options?(node)
112
+ end
113
+
114
+ # Besides the gem name, all other *positional* arguments to `gem` are version specifiers,
115
+ # as long as it has one we know there's at least one version specifier.
116
+ def version_specified_gem?(node)
117
+ # arguments[0] is the gem name
118
+ node.arguments[1]&.str_type?
119
+ end
120
+
121
+ def contains_checked_options?(node)
122
+ (Array(cop_config[CHECKED_OPTIONS_CONFIG]) & gem_options(node).map(&:to_s)).any?
123
+ end
124
+
125
+ def gem_options(node)
126
+ return [] unless node.arguments.last&.type == :hash
127
+
128
+ node.arguments.last.keys.map(&:value)
129
+ end
61
130
  end
62
131
  end
63
132
  end
@@ -25,8 +25,9 @@ module RuboCop
25
25
  # # good
26
26
  # source 'https://rubygems.org' # strongly recommended
27
27
  # source 'http://rubygems.org'
28
- class InsecureProtocolSource < Cop
28
+ class InsecureProtocolSource < Base
29
29
  include RangeHelp
30
+ extend AutoCorrector
30
31
 
31
32
  MSG = 'The source `:%<source>s` is deprecated because HTTP requests ' \
32
33
  'are insecure. ' \
@@ -35,34 +36,23 @@ module RuboCop
35
36
 
36
37
  def_node_matcher :insecure_protocol_source?, <<~PATTERN
37
38
  (send nil? :source
38
- (sym ${:gemcutter :rubygems :rubyforge}))
39
+ $(sym ${:gemcutter :rubygems :rubyforge}))
39
40
  PATTERN
40
41
 
41
42
  def on_send(node)
42
- insecure_protocol_source?(node) do |source|
43
+ insecure_protocol_source?(node) do |source_node, source|
43
44
  message = format(MSG, source: source)
44
45
 
45
46
  add_offense(
46
- node,
47
- location: range(node.first_argument.loc.expression),
47
+ source_node,
48
48
  message: message
49
- )
49
+ ) do |corrector|
50
+ corrector.replace(
51
+ source_node, "'https://rubygems.org'"
52
+ )
53
+ end
50
54
  end
51
55
  end
52
-
53
- def autocorrect(node)
54
- lambda do |corrector|
55
- corrector.replace(
56
- node.first_argument, "'https://rubygems.org'"
57
- )
58
- end
59
- end
60
-
61
- private
62
-
63
- def range(node)
64
- range_between(node.begin_pos, node.end_pos)
65
- end
66
56
  end
67
57
  end
68
58
  end
@@ -7,6 +7,35 @@ module RuboCop
7
7
  class Commissioner
8
8
  include RuboCop::AST::Traversal
9
9
 
10
+ # How a Commissioner returns the results of the investigation
11
+ # as a list of Cop::InvestigationReport and any errors caught
12
+ # during the investigation.
13
+ # Immutable
14
+ # Consider creation API private
15
+ InvestigationReport = Struct.new(:processed_source, :cop_reports, :errors) do
16
+ def cops
17
+ @cops ||= cop_reports.map(&:cop)
18
+ end
19
+
20
+ def offenses_per_cop
21
+ @offenses_per_cop ||= cop_reports.map(&:offenses)
22
+ end
23
+
24
+ def correctors
25
+ @correctors ||= cop_reports.map(&:corrector)
26
+ end
27
+
28
+ def offenses
29
+ @offenses ||= offenses_per_cop.flatten(1)
30
+ end
31
+
32
+ def merge(investigation)
33
+ InvestigationReport.new(processed_source,
34
+ cop_reports + investigation.cop_reports,
35
+ errors + investigation.errors)
36
+ end
37
+ end
38
+
10
39
  attr_reader :errors
11
40
 
12
41
  def initialize(cops, forces = [], options = {})
@@ -15,7 +44,7 @@ module RuboCop
15
44
  @options = options
16
45
  @callbacks = {}
17
46
 
18
- reset_errors
47
+ reset
19
48
  end
20
49
 
21
50
  # Create methods like :on_send, :on_super, etc. They will be called
@@ -34,16 +63,21 @@ module RuboCop
34
63
  end
35
64
  end
36
65
 
66
+ # @return [InvestigationReport]
37
67
  def investigate(processed_source)
38
- reset_errors
39
- remove_irrelevant_cops(processed_source.file_path)
40
- reset_callbacks
41
- prepare(processed_source)
42
- invoke_custom_processing(@cops, processed_source)
43
- invoke_custom_processing(@forces, processed_source)
44
- walk(processed_source.ast) unless processed_source.blank?
45
- invoke_custom_post_walk_processing(@cops, processed_source)
46
- @cops.flat_map(&:offenses)
68
+ reset
69
+
70
+ @cops.each { |cop| cop.send :begin_investigation, processed_source }
71
+ if processed_source.valid_syntax?
72
+ invoke(:on_new_investigation, @cops)
73
+ invoke(:investigate, @forces, processed_source)
74
+ walk(processed_source.ast) unless @cops.empty?
75
+ invoke(:on_investigation_end, @cops)
76
+ else
77
+ invoke(:on_other_file, @cops)
78
+ end
79
+ reports = @cops.map { |cop| cop.send(:complete_investigation) }
80
+ InvestigationReport.new(processed_source, reports, @errors)
47
81
  end
48
82
 
49
83
  private
@@ -59,72 +93,15 @@ module RuboCop
59
93
  end
60
94
  end
61
95
 
62
- def reset_errors
96
+ def reset
63
97
  @errors = []
98
+ @callbacks = {}
64
99
  end
65
100
 
66
- def remove_irrelevant_cops(filename)
67
- @cops.reject! do |cop|
68
- cop.excluded_file?(filename) ||
69
- !support_target_ruby_version?(cop) ||
70
- !support_target_rails_version?(cop)
71
- end
72
- end
73
-
74
- def support_target_ruby_version?(cop)
75
- return true unless cop.class.respond_to?(:support_target_ruby_version?)
76
-
77
- cop.class.support_target_ruby_version?(cop.target_ruby_version)
78
- end
79
-
80
- def support_target_rails_version?(cop)
81
- return true unless cop.class.respond_to?(:support_target_rails_version?)
82
-
83
- cop.class.support_target_rails_version?(cop.target_rails_version)
84
- end
85
-
86
- def reset_callbacks
87
- @callbacks.clear
88
- end
89
-
90
- # TODO: Bad design.
91
- def prepare(processed_source)
92
- @cops.each { |cop| cop.processed_source = processed_source }
93
- end
94
-
95
- # There are cops/forces that require their own custom processing.
96
- # If they define the #investigate method, all input parameters passed
97
- # to the commissioner will be passed to the cop too in order to do
98
- # its own processing.
99
- #
100
- # These custom processors are invoked before the AST traversal,
101
- # so they can build initial state that is later used by callbacks
102
- # during the AST traversal.
103
- def invoke_custom_processing(cops_or_forces, processed_source)
104
- cops_or_forces.each do |cop|
105
- next unless cop.respond_to?(:investigate)
106
-
107
- with_cop_error_handling(cop) do
108
- cop.investigate(processed_source)
109
- end
110
- end
111
- end
112
-
113
- # There are cops that require their own custom processing **after**
114
- # the AST traversal. By performing the walk before invoking these
115
- # custom processors, we allow these cops to build their own
116
- # state during the primary AST traversal instead of performing their
117
- # own AST traversals. Minimizing the number of walks is more efficient.
118
- #
119
- # If they define the #investigate_post_walk method, all input parameters
120
- # passed to the commissioner will be passed to the cop too in order to do
121
- # its own processing.
122
- def invoke_custom_post_walk_processing(cops, processed_source)
101
+ def invoke(callback, cops, *args)
123
102
  cops.each do |cop|
124
- next unless cop.respond_to?(:investigate_post_walk)
125
-
126
103
  with_cop_error_handling(cop) do
127
- cop.investigate_post_walk(processed_source)
104
+ cop.send(callback, *args)
128
105
  end
129
106
  end
130
107
  end
@@ -1,36 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'uri'
4
+ require_relative 'legacy/corrections_proxy.rb'
4
5
 
5
6
  module RuboCop
6
7
  module Cop
7
- # A scaffold for concrete cops.
8
- #
9
- # The Cop class is meant to be extended.
10
- #
11
- # Cops track offenses and can autocorrect them on the fly.
12
- #
13
- # A commissioner object is responsible for traversing the AST and invoking
14
- # the specific callbacks on each cop.
15
- # If a cop needs to do its own processing of the AST or depends on
16
- # something else, it should define the `#investigate` method and do
17
- # the processing there.
18
- #
19
- # @example
20
- #
21
- # class CustomCop < Cop
22
- # def investigate(processed_source)
23
- # # Do custom processing
24
- # end
25
- # end
26
- class Cop
27
- extend RuboCop::AST::Sexp
28
- extend NodePattern::Macros
29
- include RuboCop::AST::Sexp
30
- include Util
31
- include IgnoredNode
32
- include AutocorrectLogic
8
+ # @deprecated Use Cop::Base instead
9
+ # Legacy scaffold for Cops.
10
+ # See https://docs.rubocop.org/rubocop/cop_api_v1_changelog.html
11
+ class Cop < Base
12
+ attr_reader :offenses
33
13
 
14
+ exclude_from_registry
15
+
16
+ # @deprecated
34
17
  Correction = Struct.new(:lambda, :node, :cop) do
35
18
  def call(corrector)
36
19
  lambda.call(corrector)
@@ -41,100 +24,16 @@ module RuboCop
41
24
  end
42
25
  end
43
26
 
44
- attr_reader :config, :offenses, :corrections
45
- attr_accessor :processed_source # TODO: Bad design.
46
-
47
- @registry = Registry.new
48
-
49
- class << self
50
- attr_reader :registry
51
- end
52
-
53
- def self.all
54
- registry.without_department(:Test).cops
55
- end
56
-
57
- def self.qualified_cop_name(name, origin)
58
- registry.qualified_cop_name(name, origin)
59
- end
60
-
61
- def self.inherited(subclass)
62
- registry.enlist(subclass)
63
- end
64
-
65
- def self.badge
66
- @badge ||= Badge.for(name)
67
- end
68
-
69
- def self.cop_name
70
- badge.to_s
71
- end
72
-
73
- def self.department
74
- badge.department
75
- end
76
-
77
- def self.lint?
78
- department == :Lint
79
- end
80
-
81
- # Returns true if the cop name or the cop namespace matches any of the
82
- # given names.
83
- def self.match?(given_names)
84
- return false unless given_names
85
-
86
- given_names.include?(cop_name) ||
87
- given_names.include?(department.to_s)
88
- end
89
-
90
- # List of cops that should not try to autocorrect at the same
91
- # time as this cop
92
- #
93
- # @return [Array<RuboCop::Cop::Cop>]
94
- #
95
- # @api public
96
- def self.autocorrect_incompatible_with
97
- []
98
- end
99
-
100
- def initialize(config = nil, options = nil)
101
- @config = config || Config.new
102
- @options = options || { debug: false }
103
-
104
- @offenses = []
105
- @corrections = []
106
- @corrected_nodes = {}
107
- @corrected_nodes.compare_by_identity
108
- @processed_source = nil
109
- end
110
-
111
- def join_force?(_force_class)
112
- false
113
- end
114
-
115
- def cop_config
116
- # Use department configuration as basis, but let individual cop
117
- # configuration override.
118
- @cop_config ||= @config.for_cop(self.class.department.to_s)
119
- .merge(@config.for_cop(self))
120
- end
121
-
122
- def message(_node = nil)
123
- self.class::MSG
124
- end
125
-
126
- def add_offense(node, location: :expression, message: nil, severity: nil)
127
- loc = find_location(node, location)
128
-
129
- return if duplicate_location?(loc)
130
-
131
- severity = find_severity(node, severity)
132
- message = find_message(node, message)
133
-
134
- status = enabled_line?(loc.line) ? correct(node) : :disabled
135
-
136
- @offenses << Offense.new(severity, loc, message, name, status)
137
- yield if block_given? && status != :disabled
27
+ def add_offense(node_or_range, location: :expression, message: nil, severity: nil, &block)
28
+ @v0_argument = node_or_range
29
+ range = find_location(node_or_range, location)
30
+ if block.nil? && !autocorrect?
31
+ super(range, message: message, severity: severity)
32
+ else
33
+ super(range, message: message, severity: severity) do |corrector|
34
+ emulate_v0_callsequence(corrector, &block)
35
+ end
36
+ end
138
37
  end
139
38
 
140
39
  def find_location(node, loc)
@@ -142,154 +41,119 @@ module RuboCop
142
41
  loc.is_a?(Symbol) ? node.loc.public_send(loc) : loc
143
42
  end
144
43
 
145
- def duplicate_location?(location)
146
- @offenses.any? { |o| o.location == location }
44
+ # @deprecated Use class method
45
+ def support_autocorrect?
46
+ # warn 'deprecated, use cop.class.support_autocorrect?' TODO
47
+ self.class.support_autocorrect?
147
48
  end
148
49
 
149
- def correct(node)
150
- reason = reason_to_not_correct(node)
151
- return reason if reason
50
+ def self.support_autocorrect?
51
+ method_defined?(:autocorrect)
52
+ end
152
53
 
153
- @corrected_nodes[node] = true
154
- if support_autocorrect?
155
- correction = autocorrect(node)
156
- return :uncorrected unless correction
54
+ def self.joining_forces
55
+ return unless method_defined?(:join_force?)
157
56
 
158
- @corrections << Correction.new(correction, node, self)
159
- :corrected
160
- elsif disable_uncorrectable?
161
- disable_uncorrectable(node)
162
- :corrected_with_todo
57
+ cop = new
58
+ Force.all.select do |force_class|
59
+ cop.join_force?(force_class)
163
60
  end
164
61
  end
165
62
 
166
- def reason_to_not_correct(node)
167
- return :unsupported unless correctable?
168
- return :uncorrected unless autocorrect?
169
- return :already_corrected if @corrected_nodes.key?(node)
63
+ # @deprecated
64
+ def corrections
65
+ # warn 'Cop#corrections is deprecated' TODO
66
+ return [] unless @last_corrector
170
67
 
171
- nil
68
+ Legacy::CorrectionsProxy.new(@last_corrector)
172
69
  end
173
70
 
174
- def disable_uncorrectable(node)
175
- return unless node
176
-
177
- @disabled_lines ||= {}
178
- line = node.location.line
179
- return if @disabled_lines.key?(line)
180
-
181
- @disabled_lines[line] = true
182
- @corrections << Correction.new(disable_offense(node), node, self)
71
+ # Called before all on_... have been called
72
+ def on_new_investigation
73
+ investigate(processed_source) if respond_to?(:investigate)
74
+ super
183
75
  end
184
76
 
185
- def config_to_allow_offenses
186
- Formatter::DisabledConfigFormatter
187
- .config_to_allow_offenses[cop_name] ||= {}
77
+ # Called after all on_... have been called
78
+ def on_investigation_end
79
+ investigate_post_walk(processed_source) if respond_to?(:investigate_post_walk)
80
+ super
188
81
  end
189
82
 
190
- def config_to_allow_offenses=(hash)
191
- Formatter::DisabledConfigFormatter.config_to_allow_offenses[cop_name] =
192
- hash
83
+ ### Deprecated registry access
84
+
85
+ # @deprecated Use Registry.global
86
+ def self.registry
87
+ Registry.global
193
88
  end
194
89
 
195
- def target_ruby_version
196
- @config.target_ruby_version
90
+ # @deprecated Use Registry.all
91
+ def self.all
92
+ Registry.all
197
93
  end
198
94
 
199
- def target_rails_version
200
- @config.target_rails_version
95
+ # @deprecated Use Registry.qualified_cop_name
96
+ def self.qualified_cop_name(name, origin)
97
+ Registry.qualified_cop_name(name, origin)
201
98
  end
202
99
 
100
+ # @deprecated
101
+ # Open issue if there's a valid use case to include this in Base
203
102
  def parse(source, path = nil)
204
103
  ProcessedSource.new(source, target_ruby_version, path)
205
104
  end
206
105
 
207
- def cop_name
208
- @cop_name ||= self.class.cop_name
209
- end
210
-
211
- alias name cop_name
212
-
213
- def relevant_file?(file)
214
- file_name_matches_any?(file, 'Include', true) &&
215
- !file_name_matches_any?(file, 'Exclude', false)
216
- end
217
-
218
- def excluded_file?(file)
219
- !relevant_file?(file)
220
- end
106
+ private
221
107
 
222
- # This method should be overridden when a cop's behavior depends
223
- # on state that lives outside of these locations:
224
- #
225
- # (1) the file under inspection
226
- # (2) the cop's source code
227
- # (3) the config (eg a .rubocop.yml file)
228
- #
229
- # For example, some cops may want to look at other parts of
230
- # the codebase being inspected to find violations. A cop may
231
- # use the presence or absence of file `foo.rb` to determine
232
- # whether a certain violation exists in `bar.rb`.
233
- #
234
- # Overriding this method allows the cop to indicate to RuboCop's
235
- # ResultCache system when those external dependencies change,
236
- # ie when the ResultCache should be invalidated.
237
- def external_dependency_checksum
238
- nil
108
+ def begin_investigation(processed_source)
109
+ super
110
+ @offenses = @current_offenses
111
+ @last_corrector = @current_corrector
239
112
  end
240
113
 
241
- private
242
-
243
- def find_message(node, message)
244
- annotate(message || message(node))
114
+ # Override Base
115
+ def callback_argument(_range)
116
+ @v0_argument
245
117
  end
246
118
 
247
- def annotate(message)
248
- RuboCop::Cop::MessageAnnotator.new(
249
- config, cop_name, cop_config, @options
250
- ).annotate(message)
119
+ def apply_correction(corrector)
120
+ suppress_clobbering { super }
251
121
  end
252
122
 
253
- def file_name_matches_any?(file, parameter, default_result)
254
- patterns = cop_config[parameter]
255
- return default_result unless patterns
123
+ # Just for legacy
124
+ def emulate_v0_callsequence(corrector)
125
+ lambda = correction_lambda
126
+ yield corrector if block_given?
127
+ unless corrector.empty?
128
+ raise 'Your cop must inherit from Cop::Base and extend AutoCorrector'
129
+ end
256
130
 
257
- path = nil
258
- patterns.any? do |pattern|
259
- # Try to match the absolute path, as Exclude properties are absolute.
260
- next true if match_path?(pattern, file)
131
+ return unless lambda
261
132
 
262
- # Try with relative path.
263
- path ||= config.path_relative_to_config(file)
264
- match_path?(pattern, path)
133
+ suppress_clobbering do
134
+ lambda.call(corrector)
265
135
  end
266
136
  end
267
137
 
268
- def enabled_line?(line_number)
269
- return true if @options[:ignore_disable_comments] || !@processed_source
270
-
271
- @processed_source.comment_config.cop_enabled_at_line?(self, line_number)
272
- end
138
+ def correction_lambda
139
+ return unless correction_strategy == :attempt_correction && support_autocorrect?
273
140
 
274
- def find_severity(_node, severity)
275
- custom_severity || severity || default_severity
141
+ dedup_on_node(@v0_argument) do
142
+ autocorrect(@v0_argument)
143
+ end
276
144
  end
277
145
 
278
- def default_severity
279
- self.class.lint? ? :warning : :convention
146
+ def dedup_on_node(node)
147
+ @corrected_nodes ||= {}.compare_by_identity
148
+ yield unless @corrected_nodes.key?(node)
149
+ ensure
150
+ @corrected_nodes[node] = true
280
151
  end
281
152
 
282
- def custom_severity
283
- severity = cop_config['Severity']
284
- return unless severity
285
-
286
- if Severity::NAMES.include?(severity.to_sym)
287
- severity.to_sym
288
- else
289
- message = "Warning: Invalid severity '#{severity}'. " \
290
- "Valid severities are #{Severity::NAMES.join(', ')}."
291
- warn(Rainbow(message).red)
292
- end
153
+ def suppress_clobbering
154
+ yield
155
+ rescue ::Parser::ClobberingError
156
+ # ignore Clobbering errors
293
157
  end
294
158
  end
295
159
  end