rubocop 0.82.0 → 0.86.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 (280) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +27 -19
  3. data/config/default.yml +111 -23
  4. data/lib/rubocop.rb +16 -59
  5. data/lib/rubocop/ast_aliases.rb +8 -0
  6. data/lib/rubocop/cli.rb +3 -3
  7. data/lib/rubocop/cli/command/auto_genenerate_config.rb +2 -2
  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 +6 -2
  12. data/lib/rubocop/config_loader.rb +19 -24
  13. data/lib/rubocop/config_loader_resolver.rb +45 -6
  14. data/lib/rubocop/config_store.rb +12 -2
  15. data/lib/rubocop/config_validator.rb +2 -1
  16. data/lib/rubocop/cop/autocorrect_logic.rb +1 -2
  17. data/lib/rubocop/cop/bundler/gem_comment.rb +70 -1
  18. data/lib/rubocop/cop/commissioner.rb +0 -21
  19. data/lib/rubocop/cop/cop.rb +36 -21
  20. data/lib/rubocop/cop/correctors/alignment_corrector.rb +2 -6
  21. data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/space_corrector.rb +1 -3
  23. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -3
  24. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  25. data/lib/rubocop/cop/generator.rb +4 -3
  26. data/lib/rubocop/cop/generator/configuration_injector.rb +1 -1
  27. data/lib/rubocop/cop/ignored_node.rb +1 -3
  28. data/lib/rubocop/cop/layout/case_indentation.rb +3 -3
  29. data/lib/rubocop/cop/layout/class_structure.rb +19 -16
  30. data/lib/rubocop/cop/layout/comment_indentation.rb +3 -3
  31. data/lib/rubocop/cop/layout/condition_position.rb +12 -2
  32. data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +2 -6
  34. data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +128 -0
  35. data/lib/rubocop/cop/layout/end_of_line.rb +3 -3
  36. data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -4
  37. data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -3
  38. data/lib/rubocop/cop/layout/first_array_element_line_break.rb +1 -1
  39. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -3
  40. data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
  41. data/lib/rubocop/cop/layout/hash_alignment.rb +7 -7
  42. data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +3 -7
  43. data/lib/rubocop/cop/layout/heredoc_indentation.rb +20 -103
  44. data/lib/rubocop/cop/layout/indentation_width.rb +1 -3
  45. data/lib/rubocop/cop/layout/line_length.rb +21 -18
  46. data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
  47. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -3
  48. data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +13 -4
  49. data/lib/rubocop/cop/layout/space_after_colon.rb +1 -1
  50. data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
  51. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -3
  52. data/lib/rubocop/cop/layout/space_around_operators.rb +19 -2
  53. data/lib/rubocop/cop/layout/space_before_block_braces.rb +14 -0
  54. data/lib/rubocop/cop/layout/space_before_comment.rb +1 -3
  55. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +2 -4
  56. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -1
  57. data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
  58. data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -3
  59. data/lib/rubocop/cop/layout/trailing_whitespace.rb +2 -2
  60. data/lib/rubocop/cop/lint/ambiguous_operator.rb +41 -0
  61. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +14 -0
  62. data/lib/rubocop/cop/lint/constant_resolution.rb +89 -0
  63. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +137 -0
  64. data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -5
  65. data/lib/rubocop/cop/lint/empty_when.rb +29 -6
  66. data/lib/rubocop/cop/lint/ensure_return.rb +19 -2
  67. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -3
  68. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  69. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +38 -2
  70. data/lib/rubocop/cop/lint/literal_as_condition.rb +10 -13
  71. data/lib/rubocop/cop/lint/loop.rb +1 -1
  72. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +69 -0
  73. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  74. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +7 -7
  75. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +33 -11
  76. data/lib/rubocop/cop/lint/percent_string_array.rb +2 -4
  77. data/lib/rubocop/cop/lint/percent_symbol_array.rb +1 -1
  78. data/lib/rubocop/cop/lint/raise_exception.rb +12 -4
  79. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +5 -8
  80. data/lib/rubocop/cop/lint/redundant_require_statement.rb +3 -3
  81. data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
  82. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  83. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  84. data/lib/rubocop/cop/lint/suppressed_exception.rb +11 -4
  85. data/lib/rubocop/cop/lint/syntax.rb +1 -3
  86. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  87. data/lib/rubocop/cop/lint/useless_access_modifier.rb +13 -3
  88. data/lib/rubocop/cop/lint/useless_assignment.rb +3 -2
  89. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -1
  90. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  91. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +35 -3
  92. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
  93. data/lib/rubocop/cop/metrics/utils/iterating_block.rb +61 -0
  94. data/lib/rubocop/cop/migration/department_name.rb +7 -7
  95. data/lib/rubocop/cop/mixin/alignment.rb +1 -3
  96. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -3
  97. data/lib/rubocop/cop/mixin/check_line_breakable.rb +3 -9
  98. data/lib/rubocop/cop/mixin/configurable_enforced_style.rb +1 -3
  99. data/lib/rubocop/cop/mixin/configurable_formatting.rb +2 -4
  100. data/lib/rubocop/cop/mixin/configurable_naming.rb +1 -1
  101. data/lib/rubocop/cop/mixin/documentation_comment.rb +2 -2
  102. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  103. data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
  104. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +10 -1
  105. data/lib/rubocop/cop/mixin/hash_transform_method.rb +8 -1
  106. data/lib/rubocop/cop/mixin/ignored_pattern.rb +1 -1
  107. data/lib/rubocop/cop/mixin/line_length_help.rb +3 -2
  108. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
  109. data/lib/rubocop/cop/mixin/parentheses.rb +1 -2
  110. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +1 -1
  111. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
  112. data/lib/rubocop/cop/mixin/range_help.rb +1 -1
  113. data/lib/rubocop/cop/mixin/regexp_literal_help.rb +43 -0
  114. data/lib/rubocop/cop/mixin/statement_modifier.rb +7 -23
  115. data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
  116. data/lib/rubocop/cop/mixin/surrounding_space.rb +3 -3
  117. data/lib/rubocop/cop/mixin/target_ruby_version.rb +5 -1
  118. data/lib/rubocop/cop/mixin/trailing_comma.rb +2 -4
  119. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +3 -3
  120. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  121. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +11 -1
  122. data/lib/rubocop/cop/naming/file_name.rb +28 -17
  123. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +1 -1
  124. data/lib/rubocop/cop/naming/method_name.rb +1 -5
  125. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  126. data/lib/rubocop/cop/registry.rb +63 -10
  127. data/lib/rubocop/cop/severity.rb +1 -3
  128. data/lib/rubocop/cop/style/and_or.rb +2 -2
  129. data/lib/rubocop/cop/style/array_join.rb +1 -1
  130. data/lib/rubocop/cop/style/attr.rb +1 -3
  131. data/lib/rubocop/cop/style/bare_percent_literals.rb +2 -2
  132. data/lib/rubocop/cop/style/block_delimiters.rb +4 -12
  133. data/lib/rubocop/cop/style/case_equality.rb +1 -1
  134. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  135. data/lib/rubocop/cop/style/command_literal.rb +1 -1
  136. data/lib/rubocop/cop/style/commented_keyword.rb +2 -2
  137. data/lib/rubocop/cop/style/conditional_assignment.rb +2 -4
  138. data/lib/rubocop/cop/style/copyright.rb +5 -5
  139. data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +1 -1
  140. data/lib/rubocop/cop/style/documentation.rb +2 -2
  141. data/lib/rubocop/cop/style/double_negation.rb +41 -4
  142. data/lib/rubocop/cop/style/empty_case_condition.rb +8 -6
  143. data/lib/rubocop/cop/style/empty_literal.rb +1 -3
  144. data/lib/rubocop/cop/style/empty_method.rb +1 -5
  145. data/lib/rubocop/cop/style/encoding.rb +1 -1
  146. data/lib/rubocop/cop/style/exponential_notation.rb +5 -5
  147. data/lib/rubocop/cop/style/format_string_token.rb +2 -3
  148. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -6
  149. data/lib/rubocop/cop/style/guard_clause.rb +25 -2
  150. data/lib/rubocop/cop/style/hash_each_methods.rb +1 -1
  151. data/lib/rubocop/cop/style/hash_syntax.rb +16 -7
  152. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  153. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  154. data/lib/rubocop/cop/style/if_with_semicolon.rb +16 -0
  155. data/lib/rubocop/cop/style/inline_comment.rb +1 -1
  156. data/lib/rubocop/cop/style/inverse_methods.rb +1 -1
  157. data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
  158. data/lib/rubocop/cop/style/lambda_call.rb +0 -20
  159. data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +1 -3
  160. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -3
  161. data/lib/rubocop/cop/style/multiline_if_then.rb +1 -1
  162. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  163. data/lib/rubocop/cop/style/multiline_ternary_operator.rb +17 -6
  164. data/lib/rubocop/cop/style/multiline_when_then.rb +16 -1
  165. data/lib/rubocop/cop/style/negated_if.rb +3 -3
  166. data/lib/rubocop/cop/style/negated_unless.rb +3 -3
  167. data/lib/rubocop/cop/style/nested_ternary_operator.rb +27 -0
  168. data/lib/rubocop/cop/style/next.rb +2 -2
  169. data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
  170. data/lib/rubocop/cop/style/numeric_literal_prefix.rb +2 -2
  171. data/lib/rubocop/cop/style/one_line_conditional.rb +2 -6
  172. data/lib/rubocop/cop/style/optional_arguments.rb +1 -1
  173. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
  174. data/lib/rubocop/cop/style/redundant_conditional.rb +4 -3
  175. data/lib/rubocop/cop/style/redundant_fetch_block.rb +103 -0
  176. data/lib/rubocop/cop/style/redundant_parentheses.rb +3 -7
  177. data/lib/rubocop/cop/style/redundant_percent_q.rb +3 -3
  178. data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +89 -0
  179. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +121 -0
  180. data/lib/rubocop/cop/style/redundant_self.rb +6 -9
  181. data/lib/rubocop/cop/style/safe_navigation.rb +2 -6
  182. data/lib/rubocop/cop/style/sample.rb +1 -1
  183. data/lib/rubocop/cop/style/semicolon.rb +1 -1
  184. data/lib/rubocop/cop/style/slicing_with_range.rb +39 -0
  185. data/lib/rubocop/cop/style/special_global_vars.rb +2 -6
  186. data/lib/rubocop/cop/style/struct_inheritance.rb +21 -0
  187. data/lib/rubocop/cop/style/symbol_array.rb +5 -5
  188. data/lib/rubocop/cop/style/ternary_parentheses.rb +2 -4
  189. data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +3 -3
  190. data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +3 -3
  191. data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +13 -13
  192. data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +3 -3
  193. data/lib/rubocop/cop/style/trailing_underscore_variable.rb +1 -3
  194. data/lib/rubocop/cop/style/unless_else.rb +1 -1
  195. data/lib/rubocop/cop/style/when_then.rb +1 -1
  196. data/lib/rubocop/cop/style/word_array.rb +1 -1
  197. data/lib/rubocop/cop/style/yoda_condition.rb +18 -1
  198. data/lib/rubocop/cop/team.rb +69 -25
  199. data/lib/rubocop/cop/util.rb +27 -3
  200. data/lib/rubocop/cop/utils/format_string.rb +18 -0
  201. data/lib/rubocop/cop/variable_force.rb +3 -9
  202. data/lib/rubocop/cop/variable_force/assignment.rb +1 -0
  203. data/lib/rubocop/cop/variable_force/branch.rb +1 -3
  204. data/lib/rubocop/cop/variable_force/scope.rb +1 -0
  205. data/lib/rubocop/cop/variable_force/variable.rb +3 -6
  206. data/lib/rubocop/ext/processed_source.rb +18 -0
  207. data/lib/rubocop/formatter/base_formatter.rb +0 -4
  208. data/lib/rubocop/formatter/disabled_config_formatter.rb +5 -13
  209. data/lib/rubocop/formatter/formatter_set.rb +2 -4
  210. data/lib/rubocop/formatter/junit_formatter.rb +14 -4
  211. data/lib/rubocop/magic_comment.rb +1 -1
  212. data/lib/rubocop/name_similarity.rb +18 -9
  213. data/lib/rubocop/options.rb +26 -11
  214. data/lib/rubocop/path_util.rb +2 -2
  215. data/lib/rubocop/platform.rb +1 -1
  216. data/lib/rubocop/remote_config.rb +1 -3
  217. data/lib/rubocop/result_cache.rb +5 -7
  218. data/lib/rubocop/rspec/cop_helper.rb +2 -25
  219. data/lib/rubocop/rspec/expect_offense.rb +58 -15
  220. data/lib/rubocop/rspec/shared_contexts.rb +54 -16
  221. data/lib/rubocop/runner.rb +20 -13
  222. data/lib/rubocop/target_finder.rb +8 -8
  223. data/lib/rubocop/target_ruby.rb +4 -1
  224. data/lib/rubocop/version.rb +5 -3
  225. metadata +51 -74
  226. data/lib/rubocop/ast/builder.rb +0 -85
  227. data/lib/rubocop/ast/node.rb +0 -637
  228. data/lib/rubocop/ast/node/alias_node.rb +0 -24
  229. data/lib/rubocop/ast/node/and_node.rb +0 -29
  230. data/lib/rubocop/ast/node/args_node.rb +0 -29
  231. data/lib/rubocop/ast/node/array_node.rb +0 -70
  232. data/lib/rubocop/ast/node/block_node.rb +0 -121
  233. data/lib/rubocop/ast/node/break_node.rb +0 -17
  234. data/lib/rubocop/ast/node/case_match_node.rb +0 -56
  235. data/lib/rubocop/ast/node/case_node.rb +0 -56
  236. data/lib/rubocop/ast/node/class_node.rb +0 -31
  237. data/lib/rubocop/ast/node/def_node.rb +0 -82
  238. data/lib/rubocop/ast/node/defined_node.rb +0 -17
  239. data/lib/rubocop/ast/node/ensure_node.rb +0 -17
  240. data/lib/rubocop/ast/node/float_node.rb +0 -12
  241. data/lib/rubocop/ast/node/for_node.rb +0 -53
  242. data/lib/rubocop/ast/node/forward_args_node.rb +0 -18
  243. data/lib/rubocop/ast/node/hash_node.rb +0 -109
  244. data/lib/rubocop/ast/node/if_node.rb +0 -175
  245. data/lib/rubocop/ast/node/int_node.rb +0 -12
  246. data/lib/rubocop/ast/node/keyword_splat_node.rb +0 -45
  247. data/lib/rubocop/ast/node/mixin/basic_literal_node.rb +0 -16
  248. data/lib/rubocop/ast/node/mixin/binary_operator_node.rb +0 -43
  249. data/lib/rubocop/ast/node/mixin/collection_node.rb +0 -15
  250. data/lib/rubocop/ast/node/mixin/conditional_node.rb +0 -45
  251. data/lib/rubocop/ast/node/mixin/hash_element_node.rb +0 -125
  252. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +0 -269
  253. data/lib/rubocop/ast/node/mixin/method_identifier_predicates.rb +0 -114
  254. data/lib/rubocop/ast/node/mixin/modifier_node.rb +0 -17
  255. data/lib/rubocop/ast/node/mixin/numeric_node.rb +0 -21
  256. data/lib/rubocop/ast/node/mixin/parameterized_node.rb +0 -61
  257. data/lib/rubocop/ast/node/mixin/predicate_operator_node.rb +0 -35
  258. data/lib/rubocop/ast/node/module_node.rb +0 -24
  259. data/lib/rubocop/ast/node/or_node.rb +0 -29
  260. data/lib/rubocop/ast/node/pair_node.rb +0 -63
  261. data/lib/rubocop/ast/node/range_node.rb +0 -18
  262. data/lib/rubocop/ast/node/regexp_node.rb +0 -33
  263. data/lib/rubocop/ast/node/resbody_node.rb +0 -24
  264. data/lib/rubocop/ast/node/retry_node.rb +0 -17
  265. data/lib/rubocop/ast/node/return_node.rb +0 -24
  266. data/lib/rubocop/ast/node/self_class_node.rb +0 -24
  267. data/lib/rubocop/ast/node/send_node.rb +0 -13
  268. data/lib/rubocop/ast/node/str_node.rb +0 -16
  269. data/lib/rubocop/ast/node/super_node.rb +0 -21
  270. data/lib/rubocop/ast/node/symbol_node.rb +0 -12
  271. data/lib/rubocop/ast/node/until_node.rb +0 -35
  272. data/lib/rubocop/ast/node/when_node.rb +0 -53
  273. data/lib/rubocop/ast/node/while_node.rb +0 -35
  274. data/lib/rubocop/ast/node/yield_node.rb +0 -21
  275. data/lib/rubocop/ast/sexp.rb +0 -16
  276. data/lib/rubocop/ast/traversal.rb +0 -202
  277. data/lib/rubocop/node_pattern.rb +0 -887
  278. data/lib/rubocop/processed_source.rb +0 -213
  279. data/lib/rubocop/string_util.rb +0 -14
  280. data/lib/rubocop/token.rb +0 -114
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Algorithmic constants for `OpenSSL::Cipher` and `OpenSSL::Digest`
7
+ # deprecated since OpenSSL version 2.2.0. Prefer passing a string
8
+ # instead.
9
+ #
10
+ # @example
11
+ #
12
+ # # Example for OpenSSL::Cipher instantiation.
13
+ #
14
+ # # bad
15
+ # OpenSSL::Cipher::AES.new(128, :GCM)
16
+ #
17
+ # # good
18
+ # OpenSSL::Cipher.new('AES-128-GCM')
19
+ #
20
+ # @example
21
+ #
22
+ # # Example for OpenSSL::Digest instantiation.
23
+ #
24
+ # # bad
25
+ # OpenSSL::Digest::SHA256.new
26
+ #
27
+ # # good
28
+ # OpenSSL::Digest.new('SHA256')
29
+ #
30
+ # @example
31
+ #
32
+ # # Example for ::Digest inherited class methods.
33
+ #
34
+ # # bad
35
+ # OpenSSL::Digest::SHA256.digest('foo')
36
+ #
37
+ # # good
38
+ # OpenSSL::Digest.digest('SHA256', 'foo')
39
+ #
40
+ class DeprecatedOpenSSLConstant < Cop
41
+ include RangeHelp
42
+
43
+ MSG = 'Use `%<constant>s.%<method>s(%<replacement_args>s)`' \
44
+ ' instead of `%<original>s`.'
45
+
46
+ def_node_matcher :algorithm_const, <<~PATTERN
47
+ (send
48
+ $(const
49
+ (const
50
+ (const {nil? cbase} :OpenSSL) {:Cipher :Digest})
51
+ _)
52
+ ...)
53
+ PATTERN
54
+
55
+ def on_send(node)
56
+ return if node.arguments.any? { |arg| arg.variable? || arg.send_type? || arg.const_type? }
57
+
58
+ add_offense(node) if algorithm_const(node)
59
+ end
60
+
61
+ def autocorrect(node)
62
+ algorithm_constant, = algorithm_const(node)
63
+
64
+ lambda do |corrector|
65
+ corrector.remove(algorithm_constant.loc.double_colon)
66
+ corrector.remove(algorithm_constant.loc.name)
67
+
68
+ corrector.replace(
69
+ correction_range(node),
70
+ "#{node.loc.selector.source}(#{replacement_args(node)})"
71
+ )
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def message(node)
78
+ algorithm_constant, = algorithm_const(node)
79
+ parent_constant = openssl_class(algorithm_constant)
80
+ replacement_args = replacement_args(node)
81
+ method = node.loc.selector.source
82
+
83
+ format(
84
+ MSG,
85
+ constant: parent_constant,
86
+ method: method,
87
+ replacement_args: replacement_args,
88
+ original: node.source
89
+ )
90
+ end
91
+
92
+ def correction_range(node)
93
+ range_between(node.loc.dot.end_pos, node.loc.expression.end_pos)
94
+ end
95
+
96
+ def openssl_class(node)
97
+ node.children.first.source
98
+ end
99
+
100
+ def algorithm_name(node)
101
+ name = node.loc.name.source
102
+
103
+ if openssl_class(node) == 'OpenSSL::Cipher'
104
+ name.scan(/.{3}/).join('-')
105
+ else
106
+ name
107
+ end
108
+ end
109
+
110
+ def sanitize_arguments(arguments)
111
+ arguments.flat_map do |arg|
112
+ argument = arg.str_type? ? arg.value : arg.source
113
+
114
+ argument.tr(":'", '').split('-')
115
+ end
116
+ end
117
+
118
+ def replacement_args(node)
119
+ algorithm_constant, = algorithm_const(node)
120
+ algorithm_name = algorithm_name(algorithm_constant)
121
+
122
+ if openssl_class(algorithm_constant) == 'OpenSSL::Cipher'
123
+ build_cipher_arguments(node, algorithm_name)
124
+ else
125
+ (["'#{algorithm_name}'"] + node.arguments.map(&:source)).join(', ')
126
+ end
127
+ end
128
+
129
+ def build_cipher_arguments(node, algorithm_name)
130
+ algorithm_parts = algorithm_name.split('-')
131
+ size_and_mode = sanitize_arguments(node.arguments)
132
+ "'#{(algorithm_parts + size_and_mode + ['CBC']).take(3).join('-')}'"
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -95,10 +95,6 @@ module RuboCop
95
95
  (send nil? :alias_method (sym $_name) _)
96
96
  PATTERN
97
97
 
98
- def_node_matcher :attr?, <<~PATTERN
99
- (send nil? ${:attr_reader :attr_writer :attr_accessor :attr} $...)
100
- PATTERN
101
-
102
98
  def_node_matcher :sym_name, '(sym $_name)'
103
99
 
104
100
  def on_send(node)
@@ -108,7 +104,7 @@ module RuboCop
108
104
  return if possible_dsl?(node)
109
105
 
110
106
  found_instance_method(node, name)
111
- elsif (attr = attr?(node))
107
+ elsif (attr = node.attribute_accessor?)
112
108
  on_attr(node, *attr)
113
109
  end
114
110
  end
@@ -8,26 +8,49 @@ module RuboCop
8
8
  # @example
9
9
  #
10
10
  # # bad
11
- #
12
11
  # case foo
13
- # when bar then 1
14
- # when baz then # nothing
12
+ # when bar
13
+ # do_something
14
+ # when baz
15
15
  # end
16
16
  #
17
17
  # @example
18
18
  #
19
19
  # # good
20
+ # case condition
21
+ # when foo
22
+ # do_something
23
+ # when bar
24
+ # nil
25
+ # end
20
26
  #
21
- # case foo
22
- # when bar then 1
23
- # when baz then 2
27
+ # @example AllowComments: true (default)
28
+ #
29
+ # # good
30
+ # case condition
31
+ # when foo
32
+ # do_something
33
+ # when bar
34
+ # # noop
24
35
  # end
36
+ #
37
+ # @example AllowComments: false
38
+ #
39
+ # # bad
40
+ # case condition
41
+ # when foo
42
+ # do_something
43
+ # when bar
44
+ # # do nothing
45
+ # end
46
+ #
25
47
  class EmptyWhen < Cop
26
48
  MSG = 'Avoid `when` branches without a body.'
27
49
 
28
50
  def on_case(node)
29
51
  node.each_when do |when_node|
30
52
  next if when_node.body
53
+ next if cop_config['AllowComments'] && comment_lines?(node)
31
54
 
32
55
  add_offense(when_node, location: when_node.source_range)
33
56
  end
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop checks for *return* from an *ensure* block.
6
+ # This cop checks for `return` from an `ensure` block.
7
7
  # Explicit return from an ensure block alters the control flow
8
8
  # as the return will take precedence over any exception being raised,
9
9
  # and the exception will be silently thrown away as if it were rescued.
@@ -29,6 +29,8 @@ module RuboCop
29
29
  # do_something_else
30
30
  # end
31
31
  class EnsureReturn < Cop
32
+ include RangeHelp
33
+
32
34
  MSG = 'Do not return from an `ensure` block.'
33
35
 
34
36
  def on_ensure(node)
@@ -37,7 +39,22 @@ module RuboCop
37
39
  return unless ensure_body
38
40
 
39
41
  ensure_body.each_node(:return) do |return_node|
40
- add_offense(return_node)
42
+ next if return_node.arguments.size >= 2
43
+
44
+ add_offense(return_node, location: :keyword)
45
+ end
46
+ end
47
+
48
+ def autocorrect(node)
49
+ lambda do |corrector|
50
+ if node.arguments?
51
+ corrector.replace(node, node.source.gsub(/return\s*/, ''))
52
+ else
53
+ range = range_by_whole_lines(
54
+ node.loc.expression, include_final_newline: true
55
+ )
56
+ corrector.remove(range)
57
+ end
41
58
  end
42
59
  end
43
60
  end
@@ -141,9 +141,7 @@ module RuboCop
141
141
  arguments = node.arguments
142
142
  overridden_kwargs = kwargs.dup
143
143
 
144
- if arguments[2]
145
- overridden_kwargs[0] = "trim_mode: #{arguments[2].source}"
146
- end
144
+ overridden_kwargs[0] = "trim_mode: #{arguments[2].source}" if arguments[2]
147
145
 
148
146
  if arguments[3] && !arguments[3].hash_type?
149
147
  overridden_kwargs[1] = "eoutvar: #{arguments[3].source}"
@@ -25,7 +25,7 @@ module RuboCop
25
25
  value, = *node
26
26
 
27
27
  return unless value.infinite? ||
28
- value.zero? && node.source =~ /[1-9]/
28
+ value.zero? && /[1-9]/.match?(node.source)
29
29
 
30
30
  add_offense(node)
31
31
  end
@@ -7,6 +7,10 @@ module RuboCop
7
7
  # expected fields for format/sprintf/#% and what is actually
8
8
  # passed as arguments.
9
9
  #
10
+ # In addition it checks whether different formats are used in the same
11
+ # format string. Do not mix numbered, unnumbered, and named formats in
12
+ # the same format string.
13
+ #
10
14
  # @example
11
15
  #
12
16
  # # bad
@@ -18,16 +22,37 @@ module RuboCop
18
22
  # # good
19
23
  #
20
24
  # format('A value: %s and another: %i', a_value, another)
25
+ #
26
+ # @example
27
+ #
28
+ # # bad
29
+ #
30
+ # format('Unnumbered format: %s and numbered: %2$s', a_value, another)
31
+ #
32
+ # @example
33
+ #
34
+ # # good
35
+ #
36
+ # format('Numbered format: %1$s and numbered %2$s', a_value, another)
21
37
  class FormatParameterMismatch < Cop
22
38
  # http://rubular.com/r/CvpbxkcTzy
23
39
  MSG = "Number of arguments (%<arg_num>i) to `%<method>s` doesn't " \
24
40
  'match the number of fields (%<field_num>i).'
41
+ MSG_INVALID = 'Format string is invalid because formatting sequence types ' \
42
+ '(numbered, named or unnumbered) are mixed.'
25
43
 
26
44
  KERNEL = 'Kernel'
27
45
  SHOVEL = '<<'
28
46
  STRING_TYPES = %i[str dstr].freeze
29
47
 
30
48
  def on_send(node)
49
+ return unless format_string?(node)
50
+
51
+ if invalid_format_string?(node)
52
+ add_offense(node, location: :selector, message: MSG_INVALID)
53
+ return
54
+ end
55
+
31
56
  return unless offending_node?(node)
32
57
 
33
58
  add_offense(node, location: :selector)
@@ -35,9 +60,20 @@ module RuboCop
35
60
 
36
61
  private
37
62
 
63
+ def format_string?(node)
64
+ called_on_string?(node) && method_with_format_args?(node)
65
+ end
66
+
67
+ def invalid_format_string?(node)
68
+ string = if sprintf?(node) || format?(node)
69
+ node.first_argument.source
70
+ else
71
+ node.receiver.source
72
+ end
73
+ !RuboCop::Cop::Utils::FormatString.new(string).valid?
74
+ end
75
+
38
76
  def offending_node?(node)
39
- return false unless called_on_string?(node)
40
- return false unless method_with_format_args?(node)
41
77
  return false if splat_args?(node)
42
78
 
43
79
  num_of_format_args, num_of_expected_fields = count_matches(node)
@@ -10,26 +10,25 @@ module RuboCop
10
10
  # @example
11
11
  #
12
12
  # # bad
13
- #
14
13
  # if 20
15
14
  # do_something
16
15
  # end
17
16
  #
18
- # @example
19
- #
20
17
  # # bad
21
- #
22
18
  # if some_var && true
23
19
  # do_something
24
20
  # end
25
21
  #
26
- # @example
27
- #
28
22
  # # good
29
- #
30
23
  # if some_var && some_condition
31
24
  # do_something
32
25
  # end
26
+ #
27
+ # # good
28
+ # # When using a boolean value for an infinite loop.
29
+ # while true
30
+ # break if condition
31
+ # end
33
32
  class LiteralAsCondition < Cop
34
33
  MSG = 'Literal `%<literal>s` appeared as a condition.'
35
34
 
@@ -38,20 +37,18 @@ module RuboCop
38
37
  end
39
38
 
40
39
  def on_while(node)
41
- check_for_literal(node)
42
- end
40
+ return if condition(node).true_type?
43
41
 
44
- def on_while_post(node)
45
42
  check_for_literal(node)
46
43
  end
44
+ alias on_while_post on_while
47
45
 
48
46
  def on_until(node)
49
- check_for_literal(node)
50
- end
47
+ return if condition(node).false_type?
51
48
 
52
- def on_until_post(node)
53
49
  check_for_literal(node)
54
50
  end
51
+ alias on_until_post on_until
55
52
 
56
53
  def on_case(case_node)
57
54
  if case_node.condition
@@ -3,7 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- # This cop checks for uses of *begin...end while/until something*.
6
+ # This cop checks for uses of `begin...end while/until something`.
7
7
  #
8
8
  # @example
9
9
  #
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Do not mix named captures and numbered captures in a Regexp literal
7
+ # because numbered capture is ignored if they're mixed.
8
+ # Replace numbered captures with non-capturing groupings or
9
+ # named captures.
10
+ #
11
+ # # bad
12
+ # /(?<foo>FOO)(BAR)/
13
+ #
14
+ # # good
15
+ # /(?<foo>FOO)(?<bar>BAR)/
16
+ #
17
+ # # good
18
+ # /(?<foo>FOO)(?:BAR)/
19
+ #
20
+ # # good
21
+ # /(FOO)(BAR)/
22
+ #
23
+ class MixedRegexpCaptureTypes < Cop
24
+ MSG = 'Do not mix named captures and numbered captures ' \
25
+ 'in a Regexp literal.'
26
+
27
+ def on_regexp(node)
28
+ return if contain_non_literal?(node)
29
+
30
+ begin
31
+ tree = Regexp::Parser.parse(node.content)
32
+ # Returns if a regular expression that cannot be processed by regexp_parser gem.
33
+ # https://github.com/rubocop-hq/rubocop/issues/8083
34
+ rescue Regexp::Scanner::ScannerError
35
+ return
36
+ end
37
+
38
+ return unless named_capture?(tree)
39
+ return unless numbered_capture?(tree)
40
+
41
+ add_offense(node)
42
+ end
43
+
44
+ private
45
+
46
+ def contain_non_literal?(node)
47
+ if node.respond_to?(:type) && (node.variable? || node.send_type? || node.const_type?)
48
+ return true
49
+ end
50
+ return false unless node.respond_to?(:children)
51
+
52
+ node.children.any? { |child| contain_non_literal?(child) }
53
+ end
54
+
55
+ def named_capture?(tree)
56
+ tree.each_expression.any? do |e|
57
+ e.instance_of?(Regexp::Expression::Group::Capture)
58
+ end
59
+ end
60
+
61
+ def numbered_capture?(tree)
62
+ tree.each_expression.any? do |e|
63
+ e.instance_of?(Regexp::Expression::Group::Named)
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end