rubocop 0.72.0 → 0.76.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 (249) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -1
  3. data/bin/console +1 -0
  4. data/config/default.yml +93 -56
  5. data/lib/rubocop.rb +21 -10
  6. data/lib/rubocop/ast/builder.rb +1 -0
  7. data/lib/rubocop/ast/node.rb +12 -14
  8. data/lib/rubocop/ast/node/mixin/method_dispatch_node.rb +4 -4
  9. data/lib/rubocop/ast/node/return_node.rb +24 -0
  10. data/lib/rubocop/ast/traversal.rb +3 -3
  11. data/lib/rubocop/cli.rb +7 -4
  12. data/lib/rubocop/comment_config.rb +5 -4
  13. data/lib/rubocop/config.rb +28 -537
  14. data/lib/rubocop/config_loader.rb +21 -3
  15. data/lib/rubocop/config_loader_resolver.rb +4 -3
  16. data/lib/rubocop/config_obsoletion.rb +222 -0
  17. data/lib/rubocop/config_validator.rb +248 -0
  18. data/lib/rubocop/cop/autocorrect_logic.rb +71 -1
  19. data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +1 -1
  20. data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
  21. data/lib/rubocop/cop/commissioner.rb +18 -16
  22. data/lib/rubocop/cop/cop.rb +49 -14
  23. data/lib/rubocop/cop/corrector.rb +10 -10
  24. data/lib/rubocop/cop/correctors/alignment_corrector.rb +43 -17
  25. data/lib/rubocop/cop/correctors/empty_line_corrector.rb +2 -2
  26. data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +2 -2
  27. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  28. data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
  29. data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
  30. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
  31. data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +1 -1
  32. data/lib/rubocop/cop/generator.rb +4 -4
  33. data/lib/rubocop/cop/generator/configuration_injector.rb +9 -4
  34. data/lib/rubocop/cop/generator/require_file_injector.rb +1 -1
  35. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +2 -2
  36. data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +1 -1
  37. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +2 -2
  38. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +1 -1
  39. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +2 -2
  40. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  41. data/lib/rubocop/cop/layout/align_hash.rb +6 -2
  42. data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
  43. data/lib/rubocop/cop/layout/class_structure.rb +1 -1
  44. data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +1 -1
  45. data/lib/rubocop/cop/layout/comment_indentation.rb +10 -13
  46. data/lib/rubocop/cop/layout/empty_comment.rb +7 -16
  47. data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +22 -7
  48. data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +2 -2
  49. data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +2 -2
  50. data/lib/rubocop/cop/layout/end_of_line.rb +8 -3
  51. data/lib/rubocop/cop/layout/extra_spacing.rb +14 -59
  52. data/lib/rubocop/cop/layout/indent_assignment.rb +10 -1
  53. data/lib/rubocop/cop/layout/indent_first_argument.rb +10 -8
  54. data/lib/rubocop/cop/layout/indent_first_hash_element.rb +1 -1
  55. data/lib/rubocop/cop/layout/indent_heredoc.rb +4 -3
  56. data/lib/rubocop/cop/layout/indentation_width.rb +20 -6
  57. data/lib/rubocop/cop/layout/leading_comment_space.rb +28 -0
  58. data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
  59. data/lib/rubocop/cop/layout/multiline_block_layout.rb +24 -2
  60. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +20 -4
  61. data/lib/rubocop/cop/layout/space_around_block_parameters.rb +5 -1
  62. data/lib/rubocop/cop/layout/space_around_operators.rb +42 -23
  63. data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -7
  64. data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +8 -5
  65. data/lib/rubocop/cop/layout/space_inside_block_braces.rb +21 -2
  66. data/lib/rubocop/cop/layout/space_inside_parens.rb +6 -6
  67. data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +24 -40
  68. data/lib/rubocop/cop/layout/tab.rb +10 -22
  69. data/lib/rubocop/cop/layout/trailing_whitespace.rb +18 -2
  70. data/lib/rubocop/cop/lint/assignment_in_condition.rb +17 -4
  71. data/lib/rubocop/cop/lint/big_decimal_new.rb +1 -1
  72. data/lib/rubocop/cop/lint/debugger.rb +4 -6
  73. data/lib/rubocop/cop/lint/duplicate_methods.rb +3 -3
  74. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  75. data/lib/rubocop/cop/lint/empty_interpolation.rb +4 -4
  76. data/lib/rubocop/cop/lint/erb_new_arguments.rb +62 -5
  77. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +11 -37
  78. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +1 -1
  79. data/lib/rubocop/cop/lint/inherit_exception.rb +1 -1
  80. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -8
  81. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +2 -2
  82. data/lib/rubocop/cop/lint/multiple_compare.rb +1 -1
  83. data/lib/rubocop/cop/lint/nested_method_definition.rb +3 -3
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  85. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +1 -1
  86. data/lib/rubocop/cop/lint/number_conversion.rb +3 -3
  87. data/lib/rubocop/cop/lint/rand_one.rb +1 -1
  88. data/lib/rubocop/cop/lint/{unneeded_cop_disable_directive.rb → redundant_cop_disable_directive.rb} +24 -24
  89. data/lib/rubocop/cop/lint/{unneeded_cop_enable_directive.rb → redundant_cop_enable_directive.rb} +6 -8
  90. data/lib/rubocop/cop/lint/{unneeded_require_statement.rb → redundant_require_statement.rb} +2 -2
  91. data/lib/rubocop/cop/lint/{unneeded_splat_expansion.rb → redundant_splat_expansion.rb} +12 -7
  92. data/lib/rubocop/cop/lint/redundant_with_index.rb +1 -1
  93. data/lib/rubocop/cop/lint/redundant_with_object.rb +1 -1
  94. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +10 -11
  95. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +1 -1
  96. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +91 -0
  97. data/lib/rubocop/cop/lint/string_conversion_in_interpolation.rb +6 -6
  98. data/lib/rubocop/cop/lint/unified_integer.rb +1 -1
  99. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  100. data/lib/rubocop/cop/lint/unused_block_argument.rb +22 -6
  101. data/lib/rubocop/cop/lint/unused_method_argument.rb +23 -5
  102. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  103. data/lib/rubocop/cop/lint/uri_regexp.rb +2 -2
  104. data/lib/rubocop/cop/lint/useless_access_modifier.rb +6 -6
  105. data/lib/rubocop/cop/lint/useless_setter_call.rb +1 -1
  106. data/lib/rubocop/cop/lint/void.rb +7 -26
  107. data/lib/rubocop/cop/message_annotator.rb +16 -7
  108. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  109. data/lib/rubocop/cop/metrics/class_length.rb +1 -1
  110. data/lib/rubocop/cop/metrics/line_length.rb +7 -4
  111. data/lib/rubocop/cop/metrics/module_length.rb +1 -1
  112. data/lib/rubocop/cop/metrics/parameter_lists.rb +1 -1
  113. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +23 -6
  114. data/lib/rubocop/cop/migration/department_name.rb +44 -0
  115. data/lib/rubocop/cop/mixin/alignment.rb +1 -1
  116. data/lib/rubocop/cop/mixin/def_node.rb +1 -1
  117. data/lib/rubocop/cop/mixin/documentation_comment.rb +0 -2
  118. data/lib/rubocop/cop/mixin/empty_parameter.rb +1 -1
  119. data/lib/rubocop/cop/mixin/enforce_superclass.rb +4 -4
  120. data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
  121. data/lib/rubocop/cop/mixin/interpolation.rb +27 -0
  122. data/lib/rubocop/cop/mixin/method_complexity.rb +3 -2
  123. data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -3
  124. data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +87 -0
  125. data/lib/rubocop/cop/mixin/safe_mode.rb +2 -0
  126. data/lib/rubocop/cop/mixin/statement_modifier.rb +5 -2
  127. data/lib/rubocop/cop/mixin/surrounding_space.rb +7 -5
  128. data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -6
  129. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  130. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  131. data/lib/rubocop/cop/naming/file_name.rb +12 -5
  132. data/lib/rubocop/cop/naming/method_name.rb +12 -1
  133. data/lib/rubocop/cop/naming/predicate_name.rb +1 -1
  134. data/lib/rubocop/cop/naming/variable_name.rb +1 -0
  135. data/lib/rubocop/cop/offense.rb +18 -7
  136. data/lib/rubocop/cop/registry.rb +22 -1
  137. data/lib/rubocop/cop/security/eval.rb +1 -1
  138. data/lib/rubocop/cop/security/json_load.rb +1 -1
  139. data/lib/rubocop/cop/security/marshal_load.rb +1 -1
  140. data/lib/rubocop/cop/security/open.rb +1 -1
  141. data/lib/rubocop/cop/security/yaml_load.rb +1 -1
  142. data/lib/rubocop/cop/style/access_modifier_declarations.rb +1 -0
  143. data/lib/rubocop/cop/style/alias.rb +1 -1
  144. data/lib/rubocop/cop/style/attr.rb +2 -2
  145. data/lib/rubocop/cop/style/block_delimiters.rb +2 -1
  146. data/lib/rubocop/cop/style/braces_around_hash_parameters.rb +35 -16
  147. data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
  148. data/lib/rubocop/cop/style/colon_method_call.rb +1 -1
  149. data/lib/rubocop/cop/style/comment_annotation.rb +5 -5
  150. data/lib/rubocop/cop/style/commented_keyword.rb +16 -30
  151. data/lib/rubocop/cop/style/conditional_assignment.rb +6 -8
  152. data/lib/rubocop/cop/style/constant_visibility.rb +14 -3
  153. data/lib/rubocop/cop/style/copyright.rb +11 -7
  154. data/lib/rubocop/cop/style/date_time.rb +3 -3
  155. data/lib/rubocop/cop/style/dir.rb +1 -1
  156. data/lib/rubocop/cop/style/documentation_method.rb +45 -1
  157. data/lib/rubocop/cop/style/double_cop_disable_directive.rb +55 -0
  158. data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
  159. data/lib/rubocop/cop/style/each_with_object.rb +1 -1
  160. data/lib/rubocop/cop/style/empty_case_condition.rb +2 -2
  161. data/lib/rubocop/cop/style/empty_literal.rb +2 -2
  162. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  163. data/lib/rubocop/cop/style/eval_with_location.rb +2 -2
  164. data/lib/rubocop/cop/style/even_odd.rb +1 -1
  165. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -4
  166. data/lib/rubocop/cop/style/float_division.rb +4 -4
  167. data/lib/rubocop/cop/style/format_string.rb +17 -14
  168. data/lib/rubocop/cop/style/format_string_token.rb +19 -68
  169. data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +28 -33
  170. data/lib/rubocop/cop/style/guard_clause.rb +39 -10
  171. data/lib/rubocop/cop/style/hash_syntax.rb +4 -4
  172. data/lib/rubocop/cop/style/if_unless_modifier.rb +58 -15
  173. data/lib/rubocop/cop/style/infinite_loop.rb +5 -4
  174. data/lib/rubocop/cop/style/inverse_methods.rb +21 -15
  175. data/lib/rubocop/cop/style/lambda.rb +0 -2
  176. data/lib/rubocop/cop/style/line_end_concatenation.rb +14 -10
  177. data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -25
  178. data/lib/rubocop/cop/style/method_def_parentheses.rb +17 -9
  179. data/lib/rubocop/cop/style/min_max.rb +1 -1
  180. data/lib/rubocop/cop/style/mixin_usage.rb +12 -2
  181. data/lib/rubocop/cop/style/multiline_memoization.rb +1 -1
  182. data/lib/rubocop/cop/style/multiline_when_then.rb +55 -0
  183. data/lib/rubocop/cop/style/multiple_comparison.rb +1 -1
  184. data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
  185. data/lib/rubocop/cop/style/nested_modifier.rb +22 -4
  186. data/lib/rubocop/cop/style/non_nil_check.rb +21 -9
  187. data/lib/rubocop/cop/style/numeric_predicate.rb +3 -3
  188. data/lib/rubocop/cop/style/option_hash.rb +1 -1
  189. data/lib/rubocop/cop/style/or_assignment.rb +8 -3
  190. data/lib/rubocop/cop/style/parentheses_around_condition.rb +15 -1
  191. data/lib/rubocop/cop/style/random_with_offset.rb +6 -6
  192. data/lib/rubocop/cop/style/{unneeded_capital_w.rb → redundant_capital_w.rb} +1 -1
  193. data/lib/rubocop/cop/style/{unneeded_condition.rb → redundant_condition.rb} +3 -3
  194. data/lib/rubocop/cop/style/redundant_conditional.rb +2 -2
  195. data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
  196. data/lib/rubocop/cop/style/redundant_freeze.rb +1 -1
  197. data/lib/rubocop/cop/style/{unneeded_interpolation.rb → redundant_interpolation.rb} +1 -1
  198. data/lib/rubocop/cop/style/redundant_parentheses.rb +15 -6
  199. data/lib/rubocop/cop/style/{unneeded_percent_q.rb → redundant_percent_q.rb} +1 -1
  200. data/lib/rubocop/cop/style/redundant_return.rb +37 -21
  201. data/lib/rubocop/cop/style/redundant_self.rb +18 -1
  202. data/lib/rubocop/cop/style/{unneeded_sort.rb → redundant_sort.rb} +4 -4
  203. data/lib/rubocop/cop/style/redundant_sort_by.rb +1 -1
  204. data/lib/rubocop/cop/style/rescue_modifier.rb +24 -0
  205. data/lib/rubocop/cop/style/rescue_standard_error.rb +2 -2
  206. data/lib/rubocop/cop/style/return_nil.rb +1 -1
  207. data/lib/rubocop/cop/style/safe_navigation.rb +24 -4
  208. data/lib/rubocop/cop/style/sample.rb +1 -1
  209. data/lib/rubocop/cop/style/semicolon.rb +13 -2
  210. data/lib/rubocop/cop/style/single_line_methods.rb +8 -1
  211. data/lib/rubocop/cop/style/special_global_vars.rb +5 -7
  212. data/lib/rubocop/cop/style/stderr_puts.rb +1 -1
  213. data/lib/rubocop/cop/style/string_hash_keys.rb +2 -2
  214. data/lib/rubocop/cop/style/strip.rb +1 -1
  215. data/lib/rubocop/cop/style/struct_inheritance.rb +3 -3
  216. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  217. data/lib/rubocop/cop/style/ternary_parentheses.rb +20 -1
  218. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +4 -6
  219. data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
  220. data/lib/rubocop/cop/style/unpack_first.rb +1 -1
  221. data/lib/rubocop/cop/style/variable_interpolation.rb +6 -16
  222. data/lib/rubocop/cop/style/zero_length_predicate.rb +5 -5
  223. data/lib/rubocop/cop/team.rb +15 -14
  224. data/lib/rubocop/cop/util.rb +1 -1
  225. data/lib/rubocop/cop/utils/format_string.rb +120 -0
  226. data/lib/rubocop/cop/variable_force.rb +7 -5
  227. data/lib/rubocop/cop/variable_force/variable.rb +15 -2
  228. data/lib/rubocop/core_ext/string.rb +0 -24
  229. data/lib/rubocop/error.rb +23 -0
  230. data/lib/rubocop/formatter/clang_style_formatter.rb +8 -3
  231. data/lib/rubocop/formatter/emacs_style_formatter.rb +22 -9
  232. data/lib/rubocop/formatter/file_list_formatter.rb +1 -1
  233. data/lib/rubocop/formatter/formatter_set.rb +16 -15
  234. data/lib/rubocop/formatter/pacman_formatter.rb +80 -0
  235. data/lib/rubocop/formatter/simple_text_formatter.rb +16 -4
  236. data/lib/rubocop/formatter/tap_formatter.rb +17 -4
  237. data/lib/rubocop/magic_comment.rb +4 -0
  238. data/lib/rubocop/node_pattern.rb +5 -3
  239. data/lib/rubocop/options.rb +33 -21
  240. data/lib/rubocop/path_util.rb +1 -1
  241. data/lib/rubocop/processed_source.rb +4 -0
  242. data/lib/rubocop/result_cache.rb +1 -1
  243. data/lib/rubocop/rspec/expect_offense.rb +4 -1
  244. data/lib/rubocop/rspec/shared_contexts.rb +12 -0
  245. data/lib/rubocop/runner.rb +42 -31
  246. data/lib/rubocop/target_finder.rb +12 -4
  247. data/lib/rubocop/version.rb +1 -1
  248. metadata +21 -12
  249. data/lib/rubocop/cop/mixin/ignored_method_patterns.rb +0 -19
@@ -46,7 +46,14 @@ module RuboCop
46
46
  end
47
47
 
48
48
  def class_or_module_scope?(node)
49
- node.parent && %i[class module].include?(node.parent.type)
49
+ return false unless node.parent
50
+
51
+ case node.parent.type
52
+ when :begin
53
+ class_or_module_scope?(node.parent)
54
+ when :class, :module
55
+ true
56
+ end
50
57
  end
51
58
 
52
59
  def visibility_declaration?(node)
@@ -57,9 +64,13 @@ module RuboCop
57
64
  end
58
65
  end
59
66
 
60
- def_node_matcher :visibility_declaration_for?, <<-PATTERN
61
- (send nil? {:public_constant :private_constant} ({sym str} %1))
67
+ def_node_matcher :visibility_declaration_for?, <<~PATTERN
68
+ (send nil? {:public_constant :private_constant} ({sym str} #match_name?(%1)))
62
69
  PATTERN
70
+
71
+ def match_name?(name, constant_name)
72
+ name.to_sym == constant_name.to_sym
73
+ end
63
74
  end
64
75
  end
65
76
  end
@@ -33,13 +33,7 @@ module RuboCop
33
33
  end
34
34
 
35
35
  def autocorrect(token)
36
- raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
37
-
38
- regex = Regexp.new(notice)
39
- unless autocorrect_notice =~ regex
40
- raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
41
- "match Notice /#{notice}/"
42
- end
36
+ verify_autocorrect_notice!
43
37
 
44
38
  lambda do |corrector|
45
39
  range = token.nil? ? range_between(0, 0) : token.pos
@@ -57,6 +51,16 @@ module RuboCop
57
51
  cop_config['AutocorrectNotice']
58
52
  end
59
53
 
54
+ def verify_autocorrect_notice!
55
+ raise Warning, AUTOCORRECT_EMPTY_WARNING if autocorrect_notice.empty?
56
+
57
+ regex = Regexp.new(notice)
58
+ return if autocorrect_notice =~ regex
59
+
60
+ raise Warning, "AutocorrectNotice '#{autocorrect_notice}' must " \
61
+ "match Notice /#{notice}/"
62
+ end
63
+
60
64
  def insert_notice_before(processed_source)
61
65
  token_index = 0
62
66
  token_index += 1 if shebang_token?(processed_source, token_index)
@@ -45,15 +45,15 @@ module RuboCop
45
45
  CLASS_MSG = 'Prefer Time over DateTime.'
46
46
  COERCION_MSG = 'Do not use #to_datetime.'
47
47
 
48
- def_node_matcher :date_time?, <<-PATTERN
48
+ def_node_matcher :date_time?, <<~PATTERN
49
49
  (send (const {nil? (cbase)} :DateTime) ...)
50
50
  PATTERN
51
51
 
52
- def_node_matcher :historic_date?, <<-PATTERN
52
+ def_node_matcher :historic_date?, <<~PATTERN
53
53
  (send _ _ _ (const (const nil? :Date) _))
54
54
  PATTERN
55
55
 
56
- def_node_matcher :to_datetime?, <<-PATTERN
56
+ def_node_matcher :to_datetime?, <<~PATTERN
57
57
  (send _ :to_datetime)
58
58
  PATTERN
59
59
 
@@ -20,7 +20,7 @@ module RuboCop
20
20
  MSG = 'Use `__dir__` to get an absolute path to the current ' \
21
21
  "file's directory."
22
22
 
23
- def_node_matcher :dir_replacement?, <<-PATTERN
23
+ def_node_matcher :dir_replacement?, <<~PATTERN
24
24
  {(send (const nil? :File) :expand_path (send (const nil? :File) :dirname #file_keyword?))
25
25
  (send (const nil? :File) :dirname (send (const nil? :File) :realpath #file_keyword?))}
26
26
  PATTERN
@@ -47,13 +47,57 @@ module RuboCop
47
47
  # def foo.bar
48
48
  # puts baz
49
49
  # end
50
+ #
51
+ # @example RequireForNonPublicMethods: false (default)
52
+ # # good
53
+ # class Foo
54
+ # protected
55
+ # def do_something
56
+ # end
57
+ # end
58
+ #
59
+ # class Foo
60
+ # private
61
+ # def do_something
62
+ # end
63
+ # end
64
+ #
65
+ # @example RequireForNonPublicMethods: true
66
+ # # bad
67
+ # class Foo
68
+ # protected
69
+ # def do_something
70
+ # end
71
+ # end
72
+ #
73
+ # class Foo
74
+ # private
75
+ # def do_something
76
+ # end
77
+ # end
78
+ #
79
+ # # good
80
+ # class Foo
81
+ # protected
82
+ # # Documentation
83
+ # def do_something
84
+ # end
85
+ # end
86
+ #
87
+ # class Foo
88
+ # private
89
+ # # Documentation
90
+ # def do_something
91
+ # end
92
+ # end
93
+ #
50
94
  class DocumentationMethod < Cop
51
95
  include DocumentationComment
52
96
  include DefNode
53
97
 
54
98
  MSG = 'Missing method documentation comment.'
55
99
 
56
- def_node_matcher :module_function_node?, <<-PATTERN
100
+ def_node_matcher :module_function_node?, <<~PATTERN
57
101
  (send nil? :module_function ...)
58
102
  PATTERN
59
103
 
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Lint/RedundantCopDisableDirective
4
+ # rubocop:disable Style/DoubleCopDisableDirective
5
+
6
+ module RuboCop
7
+ module Cop
8
+ module Style
9
+ # Detects double disable comments on one line. This is mostly to catch
10
+ # automatically generated comments that need to be regenerated.
11
+ #
12
+ # @example
13
+ # # bad
14
+ # def f # rubocop:disable Style/For # rubocop:disable Metrics/AbcSize
15
+ # end
16
+ #
17
+ # # good
18
+ # # rubocop:disable Metrics/AbcSize
19
+ # def f # rubocop:disable Style/For
20
+ # end
21
+ # # rubocop:enable Metrics/AbcSize
22
+ #
23
+ # # if both fit on one line
24
+ # def f # rubocop:disable Style/For, Metrics/AbcSize
25
+ # end
26
+ #
27
+ class DoubleCopDisableDirective < Cop
28
+ # rubocop:enable Style/For, Style/DoubleCopDisableDirective
29
+ # rubocop:enable Lint/RedundantCopDisableDirective, Metrics/AbcSize
30
+ MSG = 'More than one disable comment on one line.'
31
+
32
+ def investigate(processed_source)
33
+ processed_source.comments.each do |comment|
34
+ next unless comment.text.scan(/# rubocop:(?:disable|todo)/).size > 1
35
+
36
+ add_offense(comment)
37
+ end
38
+ end
39
+
40
+ def autocorrect(comment)
41
+ prefix = if comment.text.start_with?('# rubocop:disable')
42
+ '# rubocop:disable'
43
+ else
44
+ '# rubocop:todo'
45
+ end
46
+
47
+ lambda do |corrector|
48
+ corrector.replace(comment.loc.expression,
49
+ comment.text[/#{prefix} \S+/])
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -49,7 +49,7 @@ module RuboCop
49
49
 
50
50
  private
51
51
 
52
- def_node_matcher :offending_each_range, <<-PATTERN
52
+ def_node_matcher :offending_each_range, <<~PATTERN
53
53
  (block (send (begin (${irange erange} (int $_) (int $_))) :each) (args) ...)
54
54
  PATTERN
55
55
  end
@@ -22,7 +22,7 @@ module RuboCop
22
22
  MSG = 'Use `each_with_object` instead of `%<method>s`.'
23
23
  METHODS = %i[inject reduce].freeze
24
24
 
25
- def_node_matcher :each_with_object_candidate?, <<-PATTERN
25
+ def_node_matcher :each_with_object_candidate?, <<~PATTERN
26
26
  (block $(send _ {:inject :reduce} _) $_ $_)
27
27
  PATTERN
28
28
 
@@ -84,8 +84,8 @@ module RuboCop
84
84
 
85
85
  next unless conditions.size > 1
86
86
 
87
- range = range_between(conditions.first.loc.expression.begin_pos,
88
- conditions.last.loc.expression.end_pos)
87
+ range = range_between(conditions.first.source_range.begin_pos,
88
+ conditions.last.source_range.end_pos)
89
89
 
90
90
  corrector.replace(range, conditions.map(&:source).join(' || '))
91
91
  end
@@ -84,8 +84,8 @@ module RuboCop
84
84
  # to rewrite the arguments to wrap them in parenthesis.
85
85
  args = node.parent.arguments
86
86
 
87
- range_between(args[0].loc.expression.begin_pos - 1,
88
- args[-1].loc.expression.end_pos)
87
+ range_between(args[0].source_range.begin_pos - 1,
88
+ args[-1].source_range.end_pos)
89
89
  else
90
90
  node.source_range
91
91
  end
@@ -73,11 +73,11 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def corrected(node)
76
- has_parentheses = parentheses?(node.arguments)
77
-
78
- arguments = node.arguments? ? node.arguments.source : ''
79
- extra_space = node.arguments? && !has_parentheses ? ' ' : ''
80
- scope = node.receiver ? "#{node.receiver.source}." : ''
76
+ if node.arguments?
77
+ arguments = node.arguments.source
78
+ extra_space = ' ' unless parentheses?(node.arguments)
79
+ end
80
+ scope = node.receiver ? "#{node.receiver.source}." : ''
81
81
 
82
82
  signature = [scope, node.method_name, extra_space, arguments].join
83
83
 
@@ -37,7 +37,7 @@ module RuboCop
37
37
  MSG_INCORRECT_LINE = 'Use `%<expected>s` instead of `%<actual>s`, ' \
38
38
  'as they are used by backtraces.'
39
39
 
40
- def_node_matcher :eval_without_location?, <<-PATTERN
40
+ def_node_matcher :eval_without_location?, <<~PATTERN
41
41
  {
42
42
  (send nil? :eval ${str dstr})
43
43
  (send nil? :eval ${str dstr} _)
@@ -53,7 +53,7 @@ module RuboCop
53
53
  }
54
54
  PATTERN
55
55
 
56
- def_node_matcher :line_with_offset?, <<-PATTERN
56
+ def_node_matcher :line_with_offset?, <<~PATTERN
57
57
  {
58
58
  (send #special_line_keyword? %1 (int %2))
59
59
  (send (int %2) %1 #special_line_keyword?)
@@ -18,7 +18,7 @@ module RuboCop
18
18
  class EvenOdd < Cop
19
19
  MSG = 'Replace with `Integer#%<method>s?`.'
20
20
 
21
- def_node_matcher :even_odd_candidate?, <<-PATTERN
21
+ def_node_matcher :even_odd_candidate?, <<~PATTERN
22
22
  (send
23
23
  {(send $_ :% (int 2))
24
24
  (begin (send $_ :% (int 2)))}
@@ -51,21 +51,21 @@ module RuboCop
51
51
  'instead of ' \
52
52
  '`Pathname.new(__FILE__).parent.expand_path`.'
53
53
 
54
- def_node_matcher :file_expand_path, <<-PATTERN
54
+ def_node_matcher :file_expand_path, <<~PATTERN
55
55
  (send
56
56
  (const nil? :File) :expand_path
57
57
  $_
58
58
  $_)
59
59
  PATTERN
60
60
 
61
- def_node_matcher :pathname_parent_expand_path, <<-PATTERN
61
+ def_node_matcher :pathname_parent_expand_path, <<~PATTERN
62
62
  (send
63
63
  (send
64
64
  (send nil? :Pathname
65
65
  $_) :parent) :expand_path)
66
66
  PATTERN
67
67
 
68
- def_node_matcher :pathname_new_parent_expand_path, <<-PATTERN
68
+ def_node_matcher :pathname_new_parent_expand_path, <<~PATTERN
69
69
  (send
70
70
  (send
71
71
  (send
@@ -160,7 +160,7 @@ module RuboCop
160
160
  def depth(current_path)
161
161
  paths = current_path.split(File::SEPARATOR)
162
162
 
163
- paths.reject { |path| path == '.' }.count
163
+ paths.count { |path| path != '.' }
164
164
  end
165
165
 
166
166
  def parent_path(current_path)
@@ -42,16 +42,16 @@ module RuboCop
42
42
  class FloatDivision < Cop
43
43
  include ConfigurableEnforcedStyle
44
44
 
45
- def_node_matcher :right_coerce?, <<-PATTERN
45
+ def_node_matcher :right_coerce?, <<~PATTERN
46
46
  (send _ :/ (send _ :to_f))
47
47
  PATTERN
48
- def_node_matcher :left_coerce?, <<-PATTERN
48
+ def_node_matcher :left_coerce?, <<~PATTERN
49
49
  (send (send _ :to_f) :/ _)
50
50
  PATTERN
51
- def_node_matcher :both_coerce?, <<-PATTERN
51
+ def_node_matcher :both_coerce?, <<~PATTERN
52
52
  (send (send _ :to_f) :/ (send _ :to_f))
53
53
  PATTERN
54
- def_node_matcher :any_coerce?, <<-PATTERN
54
+ def_node_matcher :any_coerce?, <<~PATTERN
55
55
  {(send _ :/ (send _ :to_f)) (send (send _ :to_f) :/ _)}
56
56
  PATTERN
57
57
 
@@ -40,15 +40,15 @@ module RuboCop
40
40
 
41
41
  MSG = 'Favor `%<prefer>s` over `%<current>s`.'
42
42
 
43
- def_node_matcher :formatter, <<-PATTERN
44
- {
45
- (send nil? ${:sprintf :format} _ _ ...)
46
- (send {str dstr} $:% ... )
47
- (send !nil? $:% {array hash})
48
- }
43
+ def_node_matcher :formatter, <<~PATTERN
44
+ {
45
+ (send nil? ${:sprintf :format} _ _ ...)
46
+ (send {str dstr} $:% ... )
47
+ (send !nil? $:% {array hash})
48
+ }
49
49
  PATTERN
50
50
 
51
- def_node_matcher :variable_argument?, <<-PATTERN
51
+ def_node_matcher :variable_argument?, <<~PATTERN
52
52
  (send {str dstr} :% {send_type? lvar_type?})
53
53
  PATTERN
54
54
 
@@ -94,10 +94,12 @@ module RuboCop
94
94
  private
95
95
 
96
96
  def autocorrect_from_percent(corrector, node)
97
- args = if %i[array hash].include?(node.first_argument.type)
98
- node.first_argument.children.map(&:source).join(', ')
97
+ percent_rhs = node.first_argument
98
+ args = case percent_rhs.type
99
+ when :array, :hash
100
+ percent_rhs.children.map(&:source).join(', ')
99
101
  else
100
- node.first_argument.source
102
+ percent_rhs.source
101
103
  end
102
104
 
103
105
  corrected = "#{style}(#{node.receiver.source}, #{args})"
@@ -106,14 +108,15 @@ module RuboCop
106
108
  end
107
109
 
108
110
  def autocorrect_to_percent(corrector, node)
109
- format = node.first_argument.source
111
+ format_arg, *param_args = node.arguments
112
+ format = format_arg.source
110
113
 
111
- args = if node.arguments.size == 2
112
- arg = node.arguments.last
114
+ args = if param_args.one?
115
+ arg = param_args.last
113
116
 
114
117
  arg.hash_type? ? "{ #{arg.source} }" : arg.source
115
118
  else
116
- "[#{node.arguments[1..-1].map(&:source).join(', ')}]"
119
+ "[#{param_args.map(&:source).join(', ')}]"
117
120
  end
118
121
 
119
122
  corrector.replace(node.loc.expression, "#{format} % #{args}")
@@ -8,7 +8,7 @@ module RuboCop
8
8
  # **Note:**
9
9
  # `unannotated` style cop only works for strings
10
10
  # which are passed as arguments to those methods:
11
- # `sprintf`, `format`, `%`.
11
+ # `printf`, `sprintf`, `format`, `%`.
12
12
  # The reason is that *unannotated* format is very similar
13
13
  # to encoded URLs or Date/Time formatting strings.
14
14
  #
@@ -41,17 +41,7 @@ module RuboCop
41
41
  class FormatStringToken < Cop
42
42
  include ConfigurableEnforcedStyle
43
43
 
44
- FIELD_CHARACTERS = Regexp.union(%w[A B E G X a b c d e f g i o p s u x])
45
- FORMAT_STRING_METHODS = %i[sprintf format %].freeze
46
-
47
- STYLE_PATTERNS = {
48
- annotated: /(?<token>%<[^>]+>#{FIELD_CHARACTERS})/,
49
- template: /(?<token>%\{[^\}]+\})/,
50
- unannotated: /(?<token>%#{FIELD_CHARACTERS})/
51
- }.freeze
52
-
53
44
  def on_str(node)
54
- return if placeholder_argument?(node)
55
45
  return if node.each_ancestor(:xstr, :regexp).any?
56
46
 
57
47
  tokens(node) do |detected_style, token_range|
@@ -68,14 +58,16 @@ module RuboCop
68
58
 
69
59
  private
70
60
 
71
- def includes_format_methods?(node)
72
- node.each_ancestor(:send).any? do |ancestor|
73
- FORMAT_STRING_METHODS.include?(ancestor.method_name)
74
- end
75
- end
61
+ def_node_matcher :format_string_in_typical_context?, <<~PATTERN
62
+ {
63
+ ^(send _ {:format :sprintf :printf} %0 ...)
64
+ ^(send %0 :% _)
65
+ }
66
+ PATTERN
76
67
 
77
68
  def unannotated_format?(node, detected_style)
78
- detected_style == :unannotated && !includes_format_methods?(node)
69
+ detected_style == :unannotated &&
70
+ !format_string_in_typical_context?(node)
79
71
  end
80
72
 
81
73
  def message(detected_style)
@@ -102,67 +94,26 @@ module RuboCop
102
94
  if source_map.is_a?(Parser::Source::Map::Heredoc)
103
95
  source_map.heredoc_body
104
96
  elsif source_map.begin
105
- slice_source(
106
- source_map.expression,
107
- source_map.expression.begin_pos + 1,
108
- source_map.expression.end_pos - 1
109
- )
97
+ source_map.expression.adjust(begin_pos: +1, end_pos: -1)
110
98
  else
111
99
  source_map.expression
112
100
  end
113
101
  end
114
102
 
115
103
  def token_ranges(contents)
116
- while (offending_match = match_token(contents))
117
- detected_style, *range = *offending_match
118
- token, contents = split_token(contents, *range)
119
- yield(detected_style, token)
120
- end
121
- end
104
+ format_string = RuboCop::Cop::Utils::FormatString.new(contents.source)
122
105
 
123
- def match_token(source_range)
124
- supported_styles.each do |style_name|
125
- pattern = STYLE_PATTERNS.fetch(style_name)
126
- match = source_range.source.match(pattern)
127
- next unless match
106
+ format_string.format_sequences.each do |seq|
107
+ next if seq.percent?
128
108
 
129
- return [style_name, match.begin(:token), match.end(:token)]
130
- end
131
-
132
- nil
133
- end
134
-
135
- def split_token(source_range, match_begin, match_end)
136
- token =
137
- slice_source(
138
- source_range,
139
- source_range.begin_pos + match_begin,
140
- source_range.begin_pos + match_end
141
- )
142
-
143
- remainder =
144
- slice_source(
145
- source_range,
146
- source_range.begin_pos + match_end,
147
- source_range.end_pos
109
+ detected_style = seq.style
110
+ token = contents.begin.adjust(
111
+ begin_pos: seq.begin_pos,
112
+ end_pos: seq.end_pos
148
113
  )
149
114
 
150
- [token, remainder]
151
- end
152
-
153
- def slice_source(source_range, new_begin, new_end)
154
- Parser::Source::Range.new(
155
- source_range.source_buffer,
156
- new_begin,
157
- new_end
158
- )
159
- end
160
-
161
- def placeholder_argument?(node)
162
- return false unless node.parent
163
- return true if node.parent.pair_type?
164
-
165
- placeholder_argument?(node.parent)
115
+ yield(detected_style, token)
116
+ end
166
117
  end
167
118
  end
168
119
  end