rubocop 0.88.0 → 0.89.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 (239) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/bin/rubocop-profile +1 -0
  4. data/config/default.yml +96 -16
  5. data/lib/rubocop.rb +16 -4
  6. data/lib/rubocop/cli/command/auto_genenerate_config.rb +1 -1
  7. data/lib/rubocop/cli/command/base.rb +1 -0
  8. data/lib/rubocop/cli/command/execute_runner.rb +1 -1
  9. data/lib/rubocop/cli/command/show_cops.rb +1 -1
  10. data/lib/rubocop/cli/command/version.rb +2 -2
  11. data/lib/rubocop/comment_config.rb +2 -2
  12. data/lib/rubocop/config.rb +19 -2
  13. data/lib/rubocop/config_loader.rb +1 -1
  14. data/lib/rubocop/config_loader_resolver.rb +3 -3
  15. data/lib/rubocop/config_obsoletion.rb +6 -1
  16. data/lib/rubocop/config_validator.rb +1 -3
  17. data/lib/rubocop/cop/base.rb +2 -2
  18. data/lib/rubocop/cop/commissioner.rb +0 -1
  19. data/lib/rubocop/cop/correctors/line_break_corrector.rb +3 -3
  20. data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +1 -1
  21. data/lib/rubocop/cop/correctors/punctuation_corrector.rb +1 -1
  22. data/lib/rubocop/cop/correctors/unused_arg_corrector.rb +15 -18
  23. data/lib/rubocop/cop/force.rb +1 -0
  24. data/lib/rubocop/cop/gemspec/required_ruby_version.rb +32 -11
  25. data/lib/rubocop/cop/generator/configuration_injector.rb +2 -2
  26. data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +4 -12
  27. data/lib/rubocop/cop/internal_affairs/node_destructuring.rb +1 -1
  28. data/lib/rubocop/cop/internal_affairs/offense_location_keyword.rb +8 -8
  29. data/lib/rubocop/cop/internal_affairs/redundant_location_argument.rb +10 -7
  30. data/lib/rubocop/cop/internal_affairs/redundant_message_argument.rb +7 -8
  31. data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -2
  32. data/lib/rubocop/cop/layout/block_alignment.rb +1 -1
  33. data/lib/rubocop/cop/layout/empty_lines.rb +0 -2
  34. data/lib/rubocop/cop/layout/extra_spacing.rb +9 -16
  35. data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +1 -1
  36. data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
  37. data/lib/rubocop/cop/layout/indentation_style.rb +0 -2
  38. data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +1 -1
  39. data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +0 -2
  40. data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +9 -1
  41. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +7 -4
  42. data/lib/rubocop/cop/lint/ambiguous_operator.rb +15 -10
  43. data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +11 -13
  44. data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -2
  45. data/lib/rubocop/cop/lint/big_decimal_new.rb +10 -10
  46. data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +49 -0
  47. data/lib/rubocop/cop/lint/boolean_symbol.rb +16 -11
  48. data/lib/rubocop/cop/lint/circular_argument_reference.rb +1 -1
  49. data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
  50. data/lib/rubocop/cop/lint/debugger.rb +7 -1
  51. data/lib/rubocop/cop/lint/deprecated_class_methods.rb +9 -10
  52. data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +17 -13
  53. data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
  54. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +1 -1
  55. data/lib/rubocop/cop/lint/duplicate_methods.rb +7 -4
  56. data/lib/rubocop/cop/lint/duplicate_rescue_exception.rb +60 -0
  57. data/lib/rubocop/cop/lint/each_with_object_argument.rb +1 -1
  58. data/lib/rubocop/cop/lint/else_layout.rb +1 -1
  59. data/lib/rubocop/cop/lint/empty_conditional_body.rb +67 -0
  60. data/lib/rubocop/cop/lint/empty_ensure.rb +5 -5
  61. data/lib/rubocop/cop/lint/empty_expression.rb +2 -2
  62. data/lib/rubocop/cop/lint/empty_interpolation.rb +5 -6
  63. data/lib/rubocop/cop/lint/empty_when.rb +2 -2
  64. data/lib/rubocop/cop/lint/ensure_return.rb +27 -29
  65. data/lib/rubocop/cop/lint/erb_new_arguments.rb +11 -10
  66. data/lib/rubocop/cop/lint/flip_flop.rb +1 -1
  67. data/lib/rubocop/cop/lint/float_comparison.rb +93 -0
  68. data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
  69. data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +5 -4
  70. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +13 -14
  71. data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +2 -2
  72. data/lib/rubocop/cop/lint/ineffective_access_modifier.rb +8 -8
  73. data/lib/rubocop/cop/lint/inherit_exception.rb +12 -7
  74. data/lib/rubocop/cop/lint/interpolation_check.rb +18 -15
  75. data/lib/rubocop/cop/lint/literal_as_condition.rb +4 -2
  76. data/lib/rubocop/cop/lint/literal_in_interpolation.rb +7 -7
  77. data/lib/rubocop/cop/lint/loop.rb +23 -2
  78. data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +6 -5
  79. data/lib/rubocop/cop/lint/missing_super.rb +99 -0
  80. data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
  81. data/lib/rubocop/cop/lint/multiple_comparison.rb +6 -9
  82. data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
  83. data/lib/rubocop/cop/lint/nested_percent_literal.rb +1 -1
  84. data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
  85. data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +27 -23
  86. data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +2 -2
  87. data/lib/rubocop/cop/lint/number_conversion.rb +6 -9
  88. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +11 -13
  89. data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +61 -0
  90. data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +4 -10
  91. data/lib/rubocop/cop/lint/percent_string_array.rb +13 -12
  92. data/lib/rubocop/cop/lint/percent_symbol_array.rb +13 -12
  93. data/lib/rubocop/cop/lint/raise_exception.rb +12 -10
  94. data/lib/rubocop/cop/lint/rand_one.rb +2 -2
  95. data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -2
  96. data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +7 -11
  97. data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -7
  98. data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +13 -9
  99. data/lib/rubocop/cop/lint/redundant_string_coercion.rb +6 -13
  100. data/lib/rubocop/cop/lint/redundant_with_index.rb +11 -14
  101. data/lib/rubocop/cop/lint/redundant_with_object.rb +11 -14
  102. data/lib/rubocop/cop/lint/regexp_as_condition.rb +4 -6
  103. data/lib/rubocop/cop/lint/require_parentheses.rb +2 -2
  104. data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
  105. data/lib/rubocop/cop/lint/rescue_type.rb +8 -8
  106. data/lib/rubocop/cop/lint/return_in_void_context.rb +2 -4
  107. data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -6
  108. data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +14 -10
  109. data/lib/rubocop/cop/lint/safe_navigation_with_empty.rb +7 -7
  110. data/lib/rubocop/cop/lint/script_permission.rb +10 -7
  111. data/lib/rubocop/cop/lint/self_assignment.rb +78 -0
  112. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +5 -11
  113. data/lib/rubocop/cop/lint/shadowed_argument.rb +3 -3
  114. data/lib/rubocop/cop/lint/shadowed_exception.rb +2 -2
  115. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +3 -3
  116. data/lib/rubocop/cop/lint/struct_new_override.rb +1 -1
  117. data/lib/rubocop/cop/lint/suppressed_exception.rb +4 -7
  118. data/lib/rubocop/cop/lint/to_json.rb +4 -6
  119. data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +34 -0
  120. data/lib/rubocop/cop/lint/underscore_prefixed_variable_name.rb +4 -4
  121. data/lib/rubocop/cop/lint/unified_integer.rb +4 -6
  122. data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
  123. data/lib/rubocop/cop/lint/unreachable_loop.rb +174 -0
  124. data/lib/rubocop/cop/lint/unused_block_argument.rb +8 -3
  125. data/lib/rubocop/cop/lint/unused_method_argument.rb +8 -3
  126. data/lib/rubocop/cop/lint/uri_escape_unescape.rb +1 -1
  127. data/lib/rubocop/cop/lint/uri_regexp.rb +11 -31
  128. data/lib/rubocop/cop/lint/useless_access_modifier.rb +25 -15
  129. data/lib/rubocop/cop/lint/useless_assignment.rb +4 -4
  130. data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +6 -15
  131. data/lib/rubocop/cop/lint/useless_setter_call.rb +4 -6
  132. data/lib/rubocop/cop/lint/void.rb +3 -7
  133. data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
  134. data/lib/rubocop/cop/metrics/block_length.rb +2 -2
  135. data/lib/rubocop/cop/metrics/block_nesting.rb +2 -2
  136. data/lib/rubocop/cop/metrics/class_length.rb +2 -2
  137. data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +2 -1
  138. data/lib/rubocop/cop/metrics/method_length.rb +2 -2
  139. data/lib/rubocop/cop/metrics/module_length.rb +2 -2
  140. data/lib/rubocop/cop/metrics/parameter_lists.rb +2 -6
  141. data/lib/rubocop/cop/metrics/perceived_complexity.rb +7 -8
  142. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +48 -5
  143. data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +52 -24
  144. data/lib/rubocop/cop/metrics/utils/repeated_csend_discount.rb +37 -0
  145. data/lib/rubocop/cop/migration/department_name.rb +13 -15
  146. data/lib/rubocop/cop/mixin/array_min_size.rb +1 -1
  147. data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
  148. data/lib/rubocop/cop/mixin/code_length.rb +22 -5
  149. data/lib/rubocop/cop/mixin/enforce_superclass.rb +2 -0
  150. data/lib/rubocop/cop/mixin/method_complexity.rb +10 -2
  151. data/lib/rubocop/cop/mixin/statement_modifier.rb +35 -6
  152. data/lib/rubocop/cop/mixin/surrounding_space.rb +0 -25
  153. data/lib/rubocop/cop/mixin/uncommunicative_name.rb +6 -13
  154. data/lib/rubocop/cop/mixin/unused_argument.rb +4 -6
  155. data/lib/rubocop/cop/naming/accessor_method_name.rb +4 -2
  156. data/lib/rubocop/cop/naming/ascii_identifiers.rb +3 -3
  157. data/lib/rubocop/cop/naming/binary_operator_parameter_name.rb +1 -1
  158. data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
  159. data/lib/rubocop/cop/naming/class_and_module_camel_case.rb +2 -2
  160. data/lib/rubocop/cop/naming/constant_name.rb +2 -2
  161. data/lib/rubocop/cop/naming/file_name.rb +3 -3
  162. data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +2 -2
  163. data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +2 -2
  164. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +2 -2
  165. data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
  166. data/lib/rubocop/cop/naming/predicate_name.rb +3 -5
  167. data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +12 -11
  168. data/lib/rubocop/cop/registry.rb +3 -3
  169. data/lib/rubocop/cop/security/eval.rb +2 -2
  170. data/lib/rubocop/cop/security/json_load.rb +6 -8
  171. data/lib/rubocop/cop/security/marshal_load.rb +2 -4
  172. data/lib/rubocop/cop/security/open.rb +2 -2
  173. data/lib/rubocop/cop/security/yaml_load.rb +6 -6
  174. data/lib/rubocop/cop/style/access_modifier_declarations.rb +11 -1
  175. data/lib/rubocop/cop/style/accessor_grouping.rb +9 -7
  176. data/lib/rubocop/cop/style/alias.rb +7 -3
  177. data/lib/rubocop/cop/style/bisected_attr_accessor.rb +0 -2
  178. data/lib/rubocop/cop/style/case_equality.rb +22 -3
  179. data/lib/rubocop/cop/style/case_like_if.rb +2 -2
  180. data/lib/rubocop/cop/style/colon_method_call.rb +3 -3
  181. data/lib/rubocop/cop/style/conditional_assignment.rb +11 -2
  182. data/lib/rubocop/cop/style/documentation.rb +4 -4
  183. data/lib/rubocop/cop/style/each_with_object.rb +0 -2
  184. data/lib/rubocop/cop/style/empty_method.rb +5 -5
  185. data/lib/rubocop/cop/style/eval_with_location.rb +4 -0
  186. data/lib/rubocop/cop/style/expand_path_arguments.rb +4 -0
  187. data/lib/rubocop/cop/style/explicit_block_argument.rb +102 -0
  188. data/lib/rubocop/cop/style/format_string.rb +4 -0
  189. data/lib/rubocop/cop/style/format_string_token.rb +1 -0
  190. data/lib/rubocop/cop/style/global_std_stream.rb +65 -0
  191. data/lib/rubocop/cop/style/guard_clause.rb +2 -2
  192. data/lib/rubocop/cop/style/hash_as_last_array_item.rb +8 -1
  193. data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
  194. data/lib/rubocop/cop/style/identical_conditional_branches.rb +1 -1
  195. data/lib/rubocop/cop/style/if_inside_else.rb +1 -1
  196. data/lib/rubocop/cop/style/if_unless_modifier.rb +0 -20
  197. data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
  198. data/lib/rubocop/cop/style/inverse_methods.rb +2 -3
  199. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +5 -0
  200. data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -1
  201. data/lib/rubocop/cop/style/missing_respond_to_missing.rb +9 -2
  202. data/lib/rubocop/cop/style/multiline_memoization.rb +2 -2
  203. data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -1
  204. data/lib/rubocop/cop/style/numeric_predicate.rb +4 -0
  205. data/lib/rubocop/cop/style/optional_boolean_parameter.rb +42 -0
  206. data/lib/rubocop/cop/style/parallel_assignment.rb +2 -2
  207. data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -2
  208. data/lib/rubocop/cop/style/random_with_offset.rb +1 -0
  209. data/lib/rubocop/cop/style/redundant_condition.rb +15 -3
  210. data/lib/rubocop/cop/style/redundant_exception.rb +4 -0
  211. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +9 -9
  212. data/lib/rubocop/cop/style/redundant_sort.rb +25 -10
  213. data/lib/rubocop/cop/style/signal_exception.rb +2 -0
  214. data/lib/rubocop/cop/style/single_argument_dig.rb +54 -0
  215. data/lib/rubocop/cop/style/string_concatenation.rb +92 -0
  216. data/lib/rubocop/cop/style/struct_inheritance.rb +1 -1
  217. data/lib/rubocop/cop/style/symbol_array.rb +1 -1
  218. data/lib/rubocop/cop/style/symbol_proc.rb +1 -1
  219. data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -1
  220. data/lib/rubocop/cop/style/zero_length_predicate.rb +10 -6
  221. data/lib/rubocop/cop/team.rb +1 -1
  222. data/lib/rubocop/cop/tokens_util.rb +84 -0
  223. data/lib/rubocop/cop/util.rb +1 -13
  224. data/lib/rubocop/cop/variable_force.rb +0 -2
  225. data/lib/rubocop/cop/variable_force/branch.rb +1 -0
  226. data/lib/rubocop/cop/variable_force/variable.rb +2 -2
  227. data/lib/rubocop/cops_documentation_generator.rb +282 -0
  228. data/lib/rubocop/error.rb +1 -0
  229. data/lib/rubocop/formatter/formatter_set.rb +1 -0
  230. data/lib/rubocop/path_util.rb +19 -4
  231. data/lib/rubocop/rake_task.rb +1 -0
  232. data/lib/rubocop/rspec/expect_offense.rb +1 -1
  233. data/lib/rubocop/target_finder.rb +12 -9
  234. data/lib/rubocop/version.rb +2 -2
  235. metadata +19 -6
  236. data/lib/rubocop/cop/lint/useless_comparison.rb +0 -28
  237. data/lib/rubocop/cop/mixin/parser_diagnostic.rb +0 -37
  238. data/lib/rubocop/cop/mixin/too_many_lines.rb +0 -25
  239. data/lib/rubocop/cop/style/method_missing_super.rb +0 -34
@@ -101,10 +101,14 @@ module RuboCop
101
101
  end
102
102
 
103
103
  def lexical_scope_type(node)
104
- node.each_ancestor(:class, :module) do |ancestor|
105
- return ancestor.class_type? ? 'in a class body' : 'in a module body'
104
+ ancestor = node.each_ancestor(:class, :module).first
105
+ if ancestor.nil?
106
+ 'at the top level'
107
+ elsif ancestor.class_type?
108
+ 'in a class body'
109
+ else
110
+ 'in a module body'
106
111
  end
107
- 'at the top level'
108
112
  end
109
113
 
110
114
  def bareword?(sym_node)
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  module RuboCop
6
4
  module Cop
7
5
  module Style
@@ -29,13 +29,20 @@ module RuboCop
29
29
  # (1..100).include?(7)
30
30
  # some_string =~ /something/
31
31
  #
32
- class CaseEquality < Cop
32
+ class CaseEquality < Base
33
+ extend AutoCorrector
34
+
33
35
  MSG = 'Avoid the use of the case equality operator `===`.'
34
36
 
35
- def_node_matcher :case_equality?, '(send #const? :=== _)'
37
+ def_node_matcher :case_equality?, '(send $#const? :=== $_)'
36
38
 
37
39
  def on_send(node)
38
- case_equality?(node) { add_offense(node, location: :selector) }
40
+ case_equality?(node) do |lhs, rhs|
41
+ add_offense(node.loc.selector) do |corrector|
42
+ replacement = replacement(lhs, rhs)
43
+ corrector.replace(node, replacement) if replacement
44
+ end
45
+ end
39
46
  end
40
47
 
41
48
  private
@@ -47,6 +54,18 @@ module RuboCop
47
54
  true
48
55
  end
49
56
  end
57
+
58
+ def replacement(lhs, rhs)
59
+ case lhs.type
60
+ when :regexp
61
+ "#{rhs.source} =~ #{lhs.source}"
62
+ when :begin
63
+ child = lhs.children.first
64
+ "#{lhs.source}.include?(#{rhs.source})" if child&.range_type?
65
+ when :const
66
+ "#{rhs.source}.is_a?(#{lhs.source})"
67
+ end
68
+ end
50
69
  end
51
70
  end
52
71
  end
@@ -112,6 +112,7 @@ module RuboCop
112
112
  def find_target_in_equality_node(node)
113
113
  argument = node.arguments.first
114
114
  receiver = node.receiver
115
+ return unless receiver
115
116
 
116
117
  if argument.literal? || const_reference?(argument)
117
118
  receiver
@@ -123,6 +124,7 @@ module RuboCop
123
124
  def find_target_in_match_node(node)
124
125
  argument = node.arguments.first
125
126
  receiver = node.receiver
127
+ return unless receiver
126
128
 
127
129
  if receiver.regexp_type?
128
130
  argument
@@ -149,7 +151,6 @@ module RuboCop
149
151
  conditions << condition if condition
150
152
  end
151
153
 
152
- # rubocop:disable Metrics/AbcSize
153
154
  # rubocop:disable Metrics/CyclomaticComplexity
154
155
  def condition_from_send_node(node, target)
155
156
  case node.method_name
@@ -167,7 +168,6 @@ module RuboCop
167
168
  end
168
169
  end
169
170
  # rubocop:enable Metrics/CyclomaticComplexity
170
- # rubocop:enable Metrics/AbcSize
171
171
 
172
172
  def condition_from_binary_op(lhs, rhs, target)
173
173
  lhs = deparenthesize(lhs)
@@ -30,12 +30,12 @@ module RuboCop
30
30
  end
31
31
 
32
32
  def on_send(node)
33
- # ignore Java interop code like Java::int
34
- return if java_type_node?(node)
35
-
36
33
  return unless node.receiver && node.double_colon?
37
34
  return if node.camel_case_method?
38
35
 
36
+ # ignore Java interop code like Java::int
37
+ return if java_type_node?(node)
38
+
39
39
  add_offense(node, location: :dot)
40
40
  end
41
41
 
@@ -43,7 +43,7 @@ module RuboCop
43
43
  when :and_asgn, :or_asgn
44
44
  "#{node.children[0].source} #{node.loc.operator.source} "
45
45
  when :casgn
46
- "#{node.children[1]} = "
46
+ lhs_for_casgn(node)
47
47
  when *ConditionalAssignment::VARIABLE_ASSIGNMENT_TYPES
48
48
  "#{node.children[0]} = "
49
49
  else
@@ -67,7 +67,7 @@ module RuboCop
67
67
 
68
68
  private
69
69
 
70
- def expand_elsif(node, elsif_branches = []) # rubocop:todo Metrics/CyclomaticComplexity
70
+ def expand_elsif(node, elsif_branches = [])
71
71
  return [] if node.nil? || !node.if_type? || !node.elsif?
72
72
 
73
73
  elsif_branches << node.if_branch
@@ -93,6 +93,15 @@ module RuboCop
93
93
  end
94
94
  end
95
95
 
96
+ def lhs_for_casgn(node)
97
+ namespace = node.children[0]
98
+ if namespace.nil? || namespace.cbase_type?
99
+ "#{namespace&.source}#{node.children[1]} = "
100
+ else
101
+ "#{namespace.source}::#{node.children[1]} = "
102
+ end
103
+ end
104
+
96
105
  def setter_method?(method_name)
97
106
  method_name.to_s.end_with?(EQUAL) &&
98
107
  !%i[!= == === >= <=].include?(method_name)
@@ -112,17 +112,17 @@ module RuboCop
112
112
  # proceeds to check its ancestors for :nodoc: all.
113
113
  # Note: How end-of-line comments are associated with code changed in
114
114
  # parser-2.2.0.4.
115
- def nodoc_comment?(node, require_all = false)
115
+ def nodoc_comment?(node, require_all: false)
116
116
  return false unless node&.children&.first
117
117
 
118
118
  nodoc = nodoc(node)
119
119
 
120
- return true if same_line?(nodoc, node) && nodoc?(nodoc, require_all)
120
+ return true if same_line?(nodoc, node) && nodoc?(nodoc, require_all: require_all)
121
121
 
122
- nodoc_comment?(node.parent, true)
122
+ nodoc_comment?(node.parent, require_all: true)
123
123
  end
124
124
 
125
- def nodoc?(comment, require_all = false)
125
+ def nodoc?(comment, require_all: false)
126
126
  /^#\s*:nodoc:#{"\s+all\s*$" if require_all}/.match?(comment.text)
127
127
  end
128
128
 
@@ -41,7 +41,6 @@ module RuboCop
41
41
  end
42
42
  end
43
43
 
44
- # rubocop:disable Metrics/AbcSize
45
44
  def autocorrect(node)
46
45
  lambda do |corrector|
47
46
  corrector.replace(node.send_node.loc.selector, 'each_with_object')
@@ -60,7 +59,6 @@ module RuboCop
60
59
  end
61
60
  end
62
61
  end
63
- # rubocop:enable Metrics/AbcSize
64
62
 
65
63
  private
66
64
 
@@ -73,13 +73,13 @@ module RuboCop
73
73
  end
74
74
 
75
75
  def corrected(node)
76
- if node.arguments?
77
- arguments = node.arguments.source
78
- extra_space = ' ' unless parentheses?(node.arguments)
79
- end
80
76
  scope = node.receiver ? "#{node.receiver.source}." : ''
77
+ arguments = if node.arguments?
78
+ args = node.arguments.map(&:source).join(', ')
81
79
 
82
- signature = [scope, node.method_name, extra_space, arguments].join
80
+ parentheses?(node.arguments) ? "(#{args})" : " #{args}"
81
+ end
82
+ signature = [scope, node.method_name, arguments].join
83
83
 
84
84
  ["def #{signature}", 'end'].join(joint(node))
85
85
  end
@@ -37,6 +37,8 @@ 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
+ EVAL_METHODS = %i[eval class_eval module_eval instance_eval].to_set.freeze
41
+
40
42
  def_node_matcher :eval_without_location?, <<~PATTERN
41
43
  {
42
44
  (send nil? :eval ${str dstr})
@@ -61,6 +63,8 @@ module RuboCop
61
63
  PATTERN
62
64
 
63
65
  def on_send(node)
66
+ return unless EVAL_METHODS.include?(node.method_name)
67
+
64
68
  eval_without_location?(node) do |code|
65
69
  if with_lineno?(node)
66
70
  on_with_lineno(node, code)
@@ -73,7 +73,10 @@ module RuboCop
73
73
  $_) :parent) :expand_path)
74
74
  PATTERN
75
75
 
76
+ # rubocop:disable Metrics/PerceivedComplexity
76
77
  def on_send(node)
78
+ return unless node.method?(:expand_path)
79
+
77
80
  if (captured_values = file_expand_path(node))
78
81
  current_path, default_dir = captured_values
79
82
 
@@ -88,6 +91,7 @@ module RuboCop
88
91
  add_offense(node, message: PATHNAME_NEW_MSG)
89
92
  end
90
93
  end
94
+ # rubocop:enable Metrics/PerceivedComplexity
91
95
 
92
96
  def autocorrect(node)
93
97
  lambda do |corrector|
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces the use of explicit block argument to avoid writing
7
+ # block literal that just passes its arguments to another block.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # def with_tmp_dir
12
+ # Dir.mktmpdir do |tmp_dir|
13
+ # Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
14
+ # end
15
+ # end
16
+ #
17
+ # # bad
18
+ # def nine_times
19
+ # 9.times { yield }
20
+ # end
21
+ #
22
+ # # good
23
+ # def with_tmp_dir(&block)
24
+ # Dir.mktmpdir do |tmp_dir|
25
+ # Dir.chdir(tmp_dir, &block)
26
+ # end
27
+ # end
28
+ #
29
+ # with_tmp_dir do |dir|
30
+ # puts "dir is accessible as a parameter and pwd is set: #{dir}"
31
+ # end
32
+ #
33
+ # # good
34
+ # def nine_times(&block)
35
+ # 9.times(&block)
36
+ # end
37
+ #
38
+ class ExplicitBlockArgument < Base
39
+ include RangeHelp
40
+ extend AutoCorrector
41
+
42
+ MSG = 'Consider using explicit block argument in the '\
43
+ "surrounding method's signature over `yield`."
44
+
45
+ def_node_matcher :yielding_block?, <<~PATTERN
46
+ (block $_ (args $...) (yield $...))
47
+ PATTERN
48
+
49
+ def initialize(config = nil, options = nil)
50
+ super
51
+ @def_nodes = Set.new
52
+ end
53
+
54
+ def on_yield(node)
55
+ block_node = node.parent
56
+
57
+ yielding_block?(block_node) do |send_node, block_args, yield_args|
58
+ return unless yielding_arguments?(block_args, yield_args)
59
+
60
+ add_offense(block_node) do |corrector|
61
+ corrector.remove(block_body_range(block_node, send_node))
62
+
63
+ add_block_argument(send_node, corrector)
64
+
65
+ def_node = block_node.each_ancestor(:def, :defs).first
66
+ add_block_argument(def_node, corrector) if @def_nodes.add?(def_node)
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def yielding_arguments?(block_args, yield_args)
74
+ yield_args.zip(block_args).all? do |yield_arg, block_arg|
75
+ block_arg && yield_arg.children.first == block_arg.children.first
76
+ end
77
+ end
78
+
79
+ def add_block_argument(node, corrector)
80
+ if node.arguments?
81
+ last_arg = node.arguments.last
82
+ arg_range = range_with_surrounding_comma(last_arg.source_range, :right)
83
+ replacement = ' &block'
84
+ replacement = ",#{replacement}" unless arg_range.source.end_with?(',')
85
+ corrector.insert_after(arg_range, replacement) unless last_arg.blockarg_type?
86
+ elsif node.send_type?
87
+ corrector.insert_after(node, '(&block)')
88
+ else
89
+ corrector.insert_after(node.loc.name, '(&block)')
90
+ end
91
+ end
92
+
93
+ def block_body_range(block_node, send_node)
94
+ range_between(
95
+ send_node.loc.expression.end_pos,
96
+ block_node.loc.end.end_pos
97
+ )
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
@@ -40,6 +40,8 @@ module RuboCop
40
40
 
41
41
  MSG = 'Favor `%<prefer>s` over `%<current>s`.'
42
42
 
43
+ FORMAT_METHODS = %i[format sprintf %].freeze
44
+
43
45
  def_node_matcher :formatter, <<~PATTERN
44
46
  {
45
47
  (send nil? ${:sprintf :format} _ _ ...)
@@ -53,6 +55,8 @@ module RuboCop
53
55
  PATTERN
54
56
 
55
57
  def on_send(node)
58
+ return unless FORMAT_METHODS.include?(node.method_name)
59
+
56
60
  formatter(node) do |selector|
57
61
  detected_style = selector == :% ? :percent : selector
58
62
 
@@ -41,6 +41,7 @@ module RuboCop
41
41
  include ConfigurableEnforcedStyle
42
42
 
43
43
  def on_str(node)
44
+ return unless node.value.include?('%')
44
45
  return if node.each_ancestor(:xstr, :regexp).any?
45
46
 
46
47
  tokens(node) do |detected_style, token_range|
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Style
6
+ # This cop enforces the use of `$stdout/$stderr/$stdin` instead of `STDOUT/STDERR/STDIN`.
7
+ # `STDOUT/STDERR/STDIN` are constants, and while you can actually
8
+ # reassign (possibly to redirect some stream) constants in Ruby, you'll get
9
+ # an interpreter warning if you do so.
10
+ #
11
+ # @example
12
+ # # bad
13
+ # STDOUT.puts('hello')
14
+ #
15
+ # hash = { out: STDOUT, key: value }
16
+ #
17
+ # def m(out = STDOUT)
18
+ # out.puts('hello')
19
+ # end
20
+ #
21
+ # # good
22
+ # $stdout.puts('hello')
23
+ #
24
+ # hash = { out: $stdout, key: value }
25
+ #
26
+ # def m(out = $stdout)
27
+ # out.puts('hello')
28
+ # end
29
+ #
30
+ class GlobalStdStream < Base
31
+ extend AutoCorrector
32
+
33
+ MSG = 'Use `%<gvar_name>s` instead of `%<const_name>s`.'
34
+
35
+ STD_STREAMS = %i[STDIN STDOUT STDERR].to_set.freeze
36
+
37
+ def_node_matcher :const_to_gvar_assignment?, <<~PATTERN
38
+ (gvasgn %1 (const nil? _))
39
+ PATTERN
40
+
41
+ def on_const(node)
42
+ const_name = node.children[1]
43
+ return unless STD_STREAMS.include?(const_name)
44
+
45
+ gvar_name = gvar_name(const_name).to_sym
46
+ return if const_to_gvar_assignment?(node.parent, gvar_name)
47
+
48
+ add_offense(node, message: message(const_name)) do |corrector|
49
+ corrector.replace(node, gvar_name)
50
+ end
51
+ end
52
+
53
+ private
54
+
55
+ def message(const_name)
56
+ format(MSG, gvar_name: gvar_name(const_name), const_name: const_name)
57
+ end
58
+
59
+ def gvar_name(const_name)
60
+ "$#{const_name.to_s.downcase}"
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -87,7 +87,7 @@ module RuboCop
87
87
  private
88
88
 
89
89
  def check_ending_if(node)
90
- return if accepted_form?(node, true) || !min_body_length?(node)
90
+ return if accepted_form?(node, ending: true) || !min_body_length?(node)
91
91
 
92
92
  register_offense(node, 'return', opposite_keyword(node))
93
93
  end
@@ -125,7 +125,7 @@ module RuboCop
125
125
  max && node.source_range.column + example.length > max
126
126
  end
127
127
 
128
- def accepted_form?(node, ending = false)
128
+ def accepted_form?(node, ending: false)
129
129
  accepted_if?(node, ending) || node.condition.multiline? ||
130
130
  node.parent&.assignment?
131
131
  end