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
@@ -93,12 +93,8 @@ module RuboCop
93
93
 
94
94
  def check(begin_node)
95
95
  node = begin_node.children.first
96
- if keyword_with_redundant_parentheses?(node)
97
- return offense(begin_node, 'a keyword')
98
- end
99
- if disallowed_literal?(begin_node, node)
100
- return offense(begin_node, 'a literal')
101
- end
96
+ return offense(begin_node, 'a keyword') if keyword_with_redundant_parentheses?(node)
97
+ return offense(begin_node, 'a literal') if disallowed_literal?(begin_node, node)
102
98
  return offense(begin_node, 'a variable') if node.variable?
103
99
  return offense(begin_node, 'a constant') if node.const_type?
104
100
 
@@ -160,7 +156,7 @@ module RuboCop
160
156
  source_buffer = node.source_range.source_buffer
161
157
  line_range = source_buffer.line_range(node.loc.end.line)
162
158
 
163
- line_range.source =~ /^\s*\)\s*,/
159
+ /^\s*\)\s*,/.match?(line_range.source)
164
160
  end
165
161
 
166
162
  def disallowed_literal?(begin_node, node)
@@ -27,7 +27,7 @@ module RuboCop
27
27
  EMPTY = ''
28
28
  PERCENT_Q = '%q'
29
29
  PERCENT_CAPITAL_Q = '%Q'
30
- STRING_INTERPOLATION_REGEXP = /#\{.+}/.freeze
30
+ STRING_INTERPOLATION_REGEXP = /#\{.+\}/.freeze
31
31
  ESCAPED_NON_BACKSLASH = /\\[^\\]/.freeze
32
32
 
33
33
  def on_dstr(node)
@@ -97,13 +97,13 @@ module RuboCop
97
97
 
98
98
  return true if STRING_INTERPOLATION_REGEXP.match?(src)
99
99
 
100
- src.scan(/\\./).any? { |s| s =~ ESCAPED_NON_BACKSLASH }
100
+ src.scan(/\\./).any? { |s| ESCAPED_NON_BACKSLASH.match?(s) }
101
101
  end
102
102
 
103
103
  def acceptable_capital_q?(node)
104
104
  src = node.source
105
105
  src.include?(QUOTE) &&
106
- (src =~ STRING_INTERPOLATION_REGEXP ||
106
+ (STRING_INTERPOLATION_REGEXP.match?(src) ||
107
107
  (node.str_type? && double_quotes_required?(src)))
108
108
  end
109
109
  end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for unnecessary single-element Regexp character classes.
7
+ #
8
+ # @example
9
+ #
10
+ # # bad
11
+ # r = /[x]/
12
+ #
13
+ # # good
14
+ # r = /x/
15
+ #
16
+ # # bad
17
+ # r = /[\s]/
18
+ #
19
+ # # good
20
+ # r = /\s/
21
+ #
22
+ # # good
23
+ # r = /[ab]/
24
+ class RedundantRegexpCharacterClass < Cop
25
+ include MatchRange
26
+ include RegexpLiteralHelp
27
+
28
+ MSG_REDUNDANT_CHARACTER_CLASS = 'Redundant single-element character class, ' \
29
+ '`%<char_class>s` can be replaced with `%<element>s`.'
30
+
31
+ PATTERN = /
32
+ (
33
+ (?<!\\) # No \-prefix (i.e. not escaped)
34
+ \[ # Literal [
35
+ (?!\#\{) # Not (the start of) an interpolation
36
+ (?: # Either...
37
+ \\. | # Any escaped character
38
+ [^.*+?{}()|$] | # or one that doesn't require escaping outside the character class
39
+ \\[upP]\{[^}]+\} # or a unicode code-point or property
40
+ )
41
+ \] # Literal ]
42
+ )
43
+ /x.freeze
44
+
45
+ def on_regexp(node)
46
+ each_redundant_character_class(node) do |loc|
47
+ next if whitespace_in_free_space_mode?(node, loc)
48
+
49
+ add_offense(
50
+ node,
51
+ location: loc,
52
+ message: format(
53
+ MSG_REDUNDANT_CHARACTER_CLASS,
54
+ char_class: loc.source,
55
+ element: without_character_class(loc)
56
+ )
57
+ )
58
+ end
59
+ end
60
+
61
+ def autocorrect(node)
62
+ lambda do |corrector|
63
+ each_redundant_character_class(node) do |loc|
64
+ corrector.replace(loc, without_character_class(loc))
65
+ end
66
+ end
67
+ end
68
+
69
+ def each_redundant_character_class(node)
70
+ pattern_source(node).scan(PATTERN) do
71
+ yield match_range(node.loc.begin.end, Regexp.last_match)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def without_character_class(loc)
78
+ loc.source[1..-2]
79
+ end
80
+
81
+ def whitespace_in_free_space_mode?(node, loc)
82
+ return false unless freespace_mode_regexp?(node)
83
+
84
+ /\[\s\]/.match?(loc.source)
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks for redundant escapes inside Regexp literals.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # %r{foo\/bar}
11
+ #
12
+ # # good
13
+ # %r{foo/bar}
14
+ #
15
+ # # good
16
+ # /foo\/bar/
17
+ #
18
+ # # good
19
+ # %r/foo\/bar/
20
+ #
21
+ # # good
22
+ # %r!foo\!bar!
23
+ #
24
+ # # bad
25
+ # /a\-b/
26
+ #
27
+ # # good
28
+ # /a-b/
29
+ #
30
+ # # bad
31
+ # /[\+\-]\d/
32
+ #
33
+ # # good
34
+ # /[+\-]\d/
35
+ class RedundantRegexpEscape < Cop
36
+ include RangeHelp
37
+ include RegexpLiteralHelp
38
+
39
+ MSG_REDUNDANT_ESCAPE = 'Redundant escape inside regexp literal'
40
+
41
+ ALLOWED_ALWAYS_ESCAPES = ' []^\\#'.chars.freeze
42
+ ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES = '-'.chars.freeze
43
+ ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES = '.*+?{}()|$'.chars.freeze
44
+
45
+ def on_regexp(node)
46
+ each_escape(node) do |char, index, within_character_class|
47
+ next if allowed_escape?(node, char, within_character_class)
48
+
49
+ add_offense(
50
+ node,
51
+ location: escape_range_at_index(node, index),
52
+ message: MSG_REDUNDANT_ESCAPE
53
+ )
54
+ end
55
+ end
56
+
57
+ def autocorrect(node)
58
+ lambda do |corrector|
59
+ each_escape(node) do |char, index, within_character_class|
60
+ next if allowed_escape?(node, char, within_character_class)
61
+
62
+ corrector.remove_leading(escape_range_at_index(node, index), 1)
63
+ end
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def allowed_escape?(node, char, within_character_class)
70
+ # Strictly speaking a few single-letter metachars are currently
71
+ # unnecessary to "escape", e.g. g, i, E, F, but enumerating them is
72
+ # rather difficult, and their behaviour could change over time with
73
+ # different versions of Ruby so that e.g. /\g/ != /g/
74
+ return true if /[[:alnum:]]/.match?(char)
75
+ return true if ALLOWED_ALWAYS_ESCAPES.include?(char) || delimiter?(node, char)
76
+
77
+ if within_character_class
78
+ ALLOWED_WITHIN_CHAR_CLASS_METACHAR_ESCAPES.include?(char)
79
+ else
80
+ ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES.include?(char)
81
+ end
82
+ end
83
+
84
+ def delimiter?(node, char)
85
+ delimiters = [
86
+ node.loc.begin.source.chars.last,
87
+ node.loc.end.source.chars.first
88
+ ]
89
+
90
+ delimiters.include?(char)
91
+ end
92
+
93
+ def each_escape(node)
94
+ pattern_source(node).each_char.with_index.reduce(
95
+ [nil, false]
96
+ ) do |(previous, within_character_class), (current, index)|
97
+ if previous == '\\'
98
+ yield [current, index - 1, within_character_class]
99
+
100
+ [nil, within_character_class]
101
+ elsif previous == '[' && current != ':'
102
+ [current, true]
103
+ elsif previous != ':' && current == ']'
104
+ [current, false]
105
+ else
106
+ [current, within_character_class]
107
+ end
108
+ end
109
+ end
110
+
111
+ def escape_range_at_index(node, index)
112
+ regexp_begin = node.loc.begin.end_pos
113
+
114
+ start = regexp_begin + index
115
+
116
+ range_between(start, start + 2)
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -44,6 +44,11 @@ module RuboCop
44
44
  class RedundantSelf < Cop
45
45
  MSG = 'Redundant `self` detected.'
46
46
  KERNEL_METHODS = Kernel.methods(false)
47
+ KEYWORDS = %i[alias and begin break case class def defined? do
48
+ else elsif end ensure false for if in module
49
+ next nil not or redo rescue retry return self
50
+ super then true undef unless until when while
51
+ yield __FILE__ __LINE__ __ENCODING__].freeze
47
52
 
48
53
  def self.autocorrect_incompatible_with
49
54
  [ColonMethodCall]
@@ -131,7 +136,7 @@ module RuboCop
131
136
 
132
137
  def regular_method_call?(node)
133
138
  !(node.operator_method? ||
134
- keyword?(node.method_name) ||
139
+ KEYWORDS.include?(node.method_name) ||
135
140
  node.camel_case_method? ||
136
141
  node.setter_method? ||
137
142
  node.implicit_call?)
@@ -142,14 +147,6 @@ module RuboCop
142
147
  @local_variables_scopes[node] << name
143
148
  end
144
149
 
145
- def keyword?(method_name)
146
- %i[alias and begin break case class def defined? do
147
- else elsif end ensure false for if in module
148
- next nil not or redo rescue retry return self
149
- super then true undef unless until when while
150
- yield __FILE__ __LINE__ __ENCODING__].include?(method_name)
151
- end
152
-
153
150
  def allow_self(node)
154
151
  return unless node.send_type? && node.self_receiver?
155
152
 
@@ -167,9 +167,7 @@ module RuboCop
167
167
  checked_variable, matching_receiver, method =
168
168
  extract_common_parts(receiver, variable)
169
169
 
170
- if receiver && LOGIC_JUMP_KEYWORDS.include?(receiver.type)
171
- matching_receiver = nil
172
- end
170
+ matching_receiver = nil if receiver && LOGIC_JUMP_KEYWORDS.include?(receiver.type)
173
171
 
174
172
  [checked_variable, matching_receiver, receiver, method]
175
173
  end
@@ -221,9 +219,7 @@ module RuboCop
221
219
  return true if unsafe_method?(method)
222
220
 
223
221
  method.each_ancestor(:send).any? do |ancestor|
224
- unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
225
- break true
226
- end
222
+ break true unless config.for_cop('Lint/SafeNavigationChain')['Enabled']
227
223
 
228
224
  break true if unsafe_method?(ancestor)
229
225
  break true if nil_methods.include?(ancestor.method_name)
@@ -92,7 +92,7 @@ module RuboCop
92
92
  second.int_type? ? second.to_a.first : :unknown
93
93
  end
94
94
 
95
- def range_size(range_node)
95
+ def range_size(range_node) # rubocop:todo Metrics/CyclomaticComplexity
96
96
  vals = range_node.to_a
97
97
  return :unknown unless vals.all?(&:int_type?)
98
98
 
@@ -39,7 +39,7 @@ module RuboCop
39
39
  check_for_line_terminator_or_opener
40
40
  end
41
41
 
42
- def on_begin(node)
42
+ def on_begin(node) # rubocop:todo Metrics/CyclomaticComplexity
43
43
  return if cop_config['AllowAsExpressionSeparator']
44
44
 
45
45
  exprs = node.children
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop checks that arrays are sliced with endless ranges instead of
7
+ # `ary[start..-1]` on Ruby 2.6+.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # items[1..-1]
12
+ #
13
+ # # good
14
+ # items[1..]
15
+ class SlicingWithRange < Cop
16
+ extend TargetRubyVersion
17
+
18
+ minimum_target_ruby_version 2.6
19
+
20
+ MSG = 'Prefer ary[n..] over ary[n..-1].'
21
+
22
+ def_node_matcher :range_till_minus_one?, '(irange !nil? (int -1))'
23
+
24
+ def on_send(node)
25
+ return unless node.method?(:[]) && node.arguments.count == 1
26
+ return unless range_till_minus_one?(node.arguments.first)
27
+
28
+ add_offense(node.arguments.first)
29
+ end
30
+
31
+ def autocorrect(node)
32
+ lambda do |corrector|
33
+ corrector.remove(node.end)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -181,13 +181,9 @@ module RuboCop
181
181
  parent_type = node.parent&.type
182
182
  preferred_name = preferred_names(global_var).first
183
183
 
184
- unless %i[dstr xstr regexp].include?(parent_type)
185
- return preferred_name.to_s
186
- end
184
+ return preferred_name.to_s unless %i[dstr xstr regexp].include?(parent_type)
187
185
 
188
- if style == :use_english_names
189
- return english_name_replacement(preferred_name, node)
190
- end
186
+ return english_name_replacement(preferred_name, node) if style == :use_english_names
191
187
 
192
188
  "##{preferred_name}"
193
189
  end
@@ -20,6 +20,8 @@ module RuboCop
20
20
  # end
21
21
  # end
22
22
  class StructInheritance < Cop
23
+ include RangeHelp
24
+
23
25
  MSG = "Don't extend an instance initialized by `Struct.new`. " \
24
26
  'Use a block to customize the struct.'
25
27
 
@@ -29,10 +31,29 @@ module RuboCop
29
31
  add_offense(node, location: node.parent_class.source_range)
30
32
  end
31
33
 
34
+ def autocorrect(node)
35
+ lambda do |corrector|
36
+ corrector.remove(range_with_surrounding_space(range: node.loc.keyword))
37
+ corrector.replace(node.loc.operator, '=')
38
+
39
+ correct_parent(node.parent_class, corrector)
40
+ end
41
+ end
42
+
32
43
  def_node_matcher :struct_constructor?, <<~PATTERN
33
44
  {(send (const nil? :Struct) :new ...)
34
45
  (block (send (const nil? :Struct) :new ...) ...)}
35
46
  PATTERN
47
+
48
+ private
49
+
50
+ def correct_parent(parent, corrector)
51
+ if parent.block_type?
52
+ corrector.remove(range_with_surrounding_space(range: parent.loc.end, newlines: false))
53
+ else
54
+ corrector.insert_after(parent.loc.expression, ' do')
55
+ end
56
+ end
36
57
  end
37
58
  end
38
59
  end
@@ -65,7 +65,7 @@ module RuboCop
65
65
  def symbols_contain_spaces?(node)
66
66
  node.children.any? do |sym|
67
67
  content, = *sym
68
- content =~ / /
68
+ / /.match?(content)
69
69
  end
70
70
  end
71
71
 
@@ -104,12 +104,12 @@ module RuboCop
104
104
  )
105
105
 
106
106
  # method name
107
- string =~ /\A[a-zA-Z_]\w*[!?]?\z/ ||
107
+ /\A[a-zA-Z_]\w*[!?]?\z/.match?(string) ||
108
108
  # instance / class variable
109
- string =~ /\A\@\@?[a-zA-Z_]\w*\z/ ||
109
+ /\A@@?[a-zA-Z_]\w*\z/.match?(string) ||
110
110
  # global variable
111
- string =~ /\A\$[1-9]\d*\z/ ||
112
- string =~ /\A\$[a-zA-Z_]\w*\z/ ||
111
+ /\A\$[1-9]\d*\z/.match?(string) ||
112
+ /\A\$[a-zA-Z_]\w*\z/.match?(string) ||
113
113
  special_gvars.include?(string) ||
114
114
  redefinable_operators.include?(string)
115
115
  end