rubocop 1.52.0 → 1.53.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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/config/default.yml +38 -1
  4. data/lib/rubocop/cli/command/lsp.rb +19 -0
  5. data/lib/rubocop/cli.rb +3 -0
  6. data/lib/rubocop/config_loader_resolver.rb +4 -3
  7. data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
  8. data/lib/rubocop/cop/bundler/gem_version.rb +2 -2
  9. data/lib/rubocop/cop/gemspec/dependency_version.rb +2 -2
  10. data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
  11. data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +3 -3
  12. data/lib/rubocop/cop/layout/class_structure.rb +7 -0
  13. data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +1 -2
  14. data/lib/rubocop/cop/layout/empty_line_between_defs.rb +1 -1
  15. data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +2 -0
  16. data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
  17. data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
  18. data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
  19. data/lib/rubocop/cop/layout/space_inside_range_literal.rb +1 -1
  20. data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
  21. data/lib/rubocop/cop/lint/debugger.rb +1 -1
  22. data/lib/rubocop/cop/lint/duplicate_hash_key.rb +2 -1
  23. data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +46 -19
  24. data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
  25. data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +1 -1
  26. data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
  27. data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
  28. data/lib/rubocop/cop/lint/inherit_exception.rb +3 -1
  29. data/lib/rubocop/cop/lint/missing_super.rb +31 -5
  30. data/lib/rubocop/cop/lint/mixed_case_range.rb +109 -0
  31. data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
  32. data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
  33. data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +120 -0
  34. data/lib/rubocop/cop/lint/redundant_require_statement.rb +8 -3
  35. data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +2 -2
  36. data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
  37. data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
  38. data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
  39. data/lib/rubocop/cop/lint/useless_assignment.rb +2 -1
  40. data/lib/rubocop/cop/lint/void.rb +1 -1
  41. data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
  42. data/lib/rubocop/cop/migration/department_name.rb +2 -2
  43. data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
  44. data/lib/rubocop/cop/mixin/end_keyword_alignment.rb +1 -1
  45. data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
  46. data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
  47. data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +3 -3
  48. data/lib/rubocop/cop/style/begin_block.rb +1 -2
  49. data/lib/rubocop/cop/style/block_comments.rb +1 -1
  50. data/lib/rubocop/cop/style/block_delimiters.rb +3 -3
  51. data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
  52. data/lib/rubocop/cop/style/conditional_assignment.rb +3 -1
  53. data/lib/rubocop/cop/style/dir.rb +1 -1
  54. data/lib/rubocop/cop/style/dir_empty.rb +8 -14
  55. data/lib/rubocop/cop/style/document_dynamic_eval_definition.rb +1 -1
  56. data/lib/rubocop/cop/style/eval_with_location.rb +3 -3
  57. data/lib/rubocop/cop/style/file_read.rb +2 -2
  58. data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
  59. data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
  60. data/lib/rubocop/cop/style/identical_conditional_branches.rb +6 -2
  61. data/lib/rubocop/cop/style/invertible_unless_condition.rb +1 -1
  62. data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +2 -2
  63. data/lib/rubocop/cop/style/preferred_hash_methods.rb +1 -1
  64. data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
  65. data/lib/rubocop/cop/style/redundant_conditional.rb +1 -1
  66. data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +38 -0
  67. data/lib/rubocop/cop/style/redundant_line_continuation.rb +2 -2
  68. data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -1
  69. data/lib/rubocop/cop/style/redundant_regexp_argument.rb +86 -0
  70. data/lib/rubocop/cop/style/redundant_regexp_escape.rb +2 -1
  71. data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +3 -1
  72. data/lib/rubocop/cop/style/redundant_sort.rb +1 -1
  73. data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -0
  74. data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +81 -0
  75. data/lib/rubocop/cop/style/signal_exception.rb +1 -1
  76. data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
  77. data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
  78. data/lib/rubocop/cop/style/yaml_file_read.rb +66 -0
  79. data/lib/rubocop/cop/util.rb +1 -1
  80. data/lib/rubocop/cop/utils/regexp_ranges.rb +100 -0
  81. data/lib/rubocop/cop/variable_force/assignment.rb +14 -1
  82. data/lib/rubocop/cops_documentation_generator.rb +1 -1
  83. data/lib/rubocop/ext/regexp_parser.rb +4 -1
  84. data/lib/rubocop/lsp/logger.rb +22 -0
  85. data/lib/rubocop/lsp/routes.rb +223 -0
  86. data/lib/rubocop/lsp/runtime.rb +79 -0
  87. data/lib/rubocop/lsp/server.rb +62 -0
  88. data/lib/rubocop/lsp/severity.rb +27 -0
  89. data/lib/rubocop/options.rb +11 -1
  90. data/lib/rubocop/version.rb +1 -1
  91. data/lib/rubocop.rb +8 -0
  92. metadata +36 -9
@@ -14,6 +14,13 @@ module RuboCop
14
14
  # Autocorrection is not supported because the position of `super` cannot be
15
15
  # determined automatically.
16
16
  #
17
+ # `Object` and `BasicObject` are allowed by this cop because of their
18
+ # stateless nature. However, sometimes you might want to allow other parent
19
+ # classes from this cop, for example in the case of an abstract class that is
20
+ # not meant to be called with `super`. In those cases, you can use the
21
+ # `AllowedParentClasses` option to specify which classes should be allowed
22
+ # *in addition to* `Object` and `BasicObject`.
23
+ #
17
24
  # @example
18
25
  # # bad
19
26
  # class Employee < Person
@@ -60,6 +67,21 @@ module RuboCop
60
67
  # end
61
68
  # end
62
69
  #
70
+ # # good
71
+ # class ClassWithNoParent
72
+ # def initialize
73
+ # do_something
74
+ # end
75
+ # end
76
+ #
77
+ # @example AllowedParentClasses: [MyAbstractClass]
78
+ # # good
79
+ # class MyConcreteClass < MyAbstractClass
80
+ # def initialize
81
+ # do_something
82
+ # end
83
+ # end
84
+ #
63
85
  class MissingSuper < Base
64
86
  CONSTRUCTOR_MSG = 'Call `super` to initialize state of the parent class.'
65
87
  CALLBACK_MSG = 'Call `super` to invoke callback defined in the parent class.'
@@ -103,7 +125,7 @@ module RuboCop
103
125
  end
104
126
 
105
127
  def callback_method_def?(node)
106
- return unless CALLBACKS.include?(node.method_name)
128
+ return false unless CALLBACKS.include?(node.method_name)
107
129
 
108
130
  node.each_ancestor(:class, :sclass, :module).first
109
131
  end
@@ -116,16 +138,20 @@ module RuboCop
116
138
  if (block_node = node.each_ancestor(:block, :numblock).first)
117
139
  return false unless (super_class = class_new_block(block_node))
118
140
 
119
- !stateless_class?(super_class)
141
+ !allowed_class?(super_class)
120
142
  elsif (class_node = node.each_ancestor(:class).first)
121
- class_node.parent_class && !stateless_class?(class_node.parent_class)
143
+ class_node.parent_class && !allowed_class?(class_node.parent_class)
122
144
  else
123
145
  false
124
146
  end
125
147
  end
126
148
 
127
- def stateless_class?(node)
128
- STATELESS_CLASSES.include?(node.const_name)
149
+ def allowed_class?(node)
150
+ allowed_classes.include?(node.const_name)
151
+ end
152
+
153
+ def allowed_classes
154
+ @allowed_classes ||= STATELESS_CLASSES + cop_config.fetch('AllowedParentClasses', [])
129
155
  end
130
156
  end
131
157
  end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for mixed-case character ranges since they include likely unintended characters.
7
+ #
8
+ # Offenses are registered for regexp character classes like `/[A-z]/`
9
+ # as well as range objects like `('A'..'z')`.
10
+ #
11
+ # NOTE: Range objects cannot be autocorrected.
12
+ #
13
+ # @safety
14
+ # The cop autocorrects regexp character classes
15
+ # by replacing one character range with two: `A-z` becomes `A-Za-z`.
16
+ # In most cases this is probably what was originally intended
17
+ # but it changes the regexp to no longer match symbols it used to include.
18
+ # For this reason, this cop's autocorrect is unsafe (it will
19
+ # change the behavior of the code).
20
+ #
21
+ # @example
22
+ #
23
+ # # bad
24
+ # r = /[A-z]/
25
+ #
26
+ # # good
27
+ # r = /[A-Za-z]/
28
+ class MixedCaseRange < Base
29
+ extend AutoCorrector
30
+ include RangeHelp
31
+
32
+ MSG = 'Ranges from upper to lower case ASCII letters may include unintended ' \
33
+ 'characters. Instead of `A-z` (which also includes several symbols) ' \
34
+ 'specify each range individually: `A-Za-z` and individually specify any symbols.'
35
+ RANGES = [('a'..'z').freeze, ('A'..'Z').freeze].freeze
36
+
37
+ def on_irange(node)
38
+ return unless node.children.compact.all?(&:str_type?)
39
+
40
+ range_start, range_end = node.children
41
+
42
+ return if range_start.nil? || range_end.nil?
43
+
44
+ add_offense(node) if unsafe_range?(range_start.value, range_end.value)
45
+ end
46
+ alias on_erange on_irange
47
+
48
+ def on_regexp(node)
49
+ each_unsafe_regexp_range(node) do |loc|
50
+ add_offense(loc) do |corrector|
51
+ corrector.replace(loc, rewrite_regexp_range(loc.source))
52
+ end
53
+ end
54
+ end
55
+
56
+ def each_unsafe_regexp_range(node)
57
+ node.parsed_tree&.each_expression do |expr|
58
+ next if skip_expression?(expr)
59
+
60
+ range_pairs(expr).reject do |range_start, range_end|
61
+ next if skip_range?(range_start, range_end)
62
+
63
+ next unless unsafe_range?(range_start.text, range_end.text)
64
+
65
+ yield(build_source_range(range_start, range_end))
66
+ end
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def build_source_range(range_start, range_end)
73
+ range_between(range_start.expression.begin_pos, range_end.expression.end_pos)
74
+ end
75
+
76
+ def range_for(char)
77
+ RANGES.detect do |range|
78
+ range.include?(char)
79
+ end
80
+ end
81
+
82
+ def range_pairs(expr)
83
+ RuboCop::Cop::Utils::RegexpRanges.new(expr).pairs
84
+ end
85
+
86
+ def unsafe_range?(range_start, range_end)
87
+ range_for(range_start) != range_for(range_end)
88
+ end
89
+
90
+ def skip_expression?(expr)
91
+ !(expr.type == :set && expr.token == :character)
92
+ end
93
+
94
+ def skip_range?(range_start, range_end)
95
+ [range_start, range_end].any? do |bound|
96
+ bound.type == :escape
97
+ end
98
+ end
99
+
100
+ def rewrite_regexp_range(source)
101
+ open, close = source.split('-')
102
+ first = [open, range_for(open).end]
103
+ second = [range_for(close).begin, close]
104
+ "#{first.uniq.join('-')}#{second.uniq.join('-')}"
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -74,6 +74,7 @@ module RuboCop
74
74
  extend AutoCorrector
75
75
  include AllowedMethods
76
76
  include AllowedPattern
77
+ include IgnoredNode
77
78
 
78
79
  CONVERSION_METHOD_CLASS_MAPPING = {
79
80
  to_i: "#{Integer.name}(%<number_object>s, 10)",
@@ -116,7 +117,11 @@ module RuboCop
116
117
  corrected_method: correct_method(node, receiver)
117
118
  )
118
119
  add_offense(node, message: message) do |corrector|
120
+ next if part_of_ignored_node?(node)
121
+
119
122
  corrector.replace(node, correct_method(node, node.receiver))
123
+
124
+ ignore_node(node)
120
125
  end
121
126
  end
122
127
  end
@@ -3,7 +3,6 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- #
7
6
  # Checks the proper ordering of magic comments and whether
8
7
  # a magic comment is not placed before a shebang.
9
8
  #
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Lint
6
+ # Checks for redundant quantifiers inside Regexp literals.
7
+ #
8
+ # @example
9
+ # # bad
10
+ # /(?:x+)+/
11
+ #
12
+ # # good
13
+ # /(?:x)+/
14
+ #
15
+ # # good
16
+ # /(?:x+)/
17
+ #
18
+ # # bad
19
+ # /(?:x+)?/
20
+ #
21
+ # # good
22
+ # /(?:x)*/
23
+ #
24
+ # # good
25
+ # /(?:x*)/
26
+ class RedundantRegexpQuantifiers < Base
27
+ include RangeHelp
28
+ extend AutoCorrector
29
+
30
+ MSG_REDUNDANT_QUANTIFIER = 'Replace redundant quantifiers ' \
31
+ '`%<inner_quantifier>s` and `%<outer_quantifier>s` ' \
32
+ 'with a single `%<replacement>s`.'
33
+
34
+ def on_regexp(node)
35
+ each_redundantly_quantified_pair(node) do |group, child|
36
+ replacement = merged_quantifier(group, child)
37
+ add_offense(
38
+ quantifier_range(group, child),
39
+ message: message(group, child, replacement)
40
+ ) do |corrector|
41
+ # drop outer quantifier
42
+ corrector.replace(group.loc.quantifier, '')
43
+ # replace inner quantifier
44
+ corrector.replace(child.loc.quantifier, replacement)
45
+ end
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def each_redundantly_quantified_pair(node)
52
+ seen = Set.new
53
+ node.parsed_tree&.each_expression do |(expr)|
54
+ next if seen.include?(expr) || !redundant_group?(expr) || !mergeable_quantifier(expr)
55
+
56
+ expr.each_expression do |(subexp)|
57
+ seen << subexp
58
+ break unless redundantly_quantifiable?(subexp)
59
+
60
+ yield(expr, subexp) if mergeable_quantifier(subexp)
61
+ end
62
+ end
63
+ end
64
+
65
+ def redundant_group?(expr)
66
+ expr.is?(:passive, :group) && expr.count { |child| child.type != :free_space } == 1
67
+ end
68
+
69
+ def redundantly_quantifiable?(node)
70
+ redundant_group?(node) || character_set?(node) || node.terminal?
71
+ end
72
+
73
+ def character_set?(expr)
74
+ expr.is?(:character, :set)
75
+ end
76
+
77
+ def mergeable_quantifier(expr)
78
+ # Merging reluctant or possessive quantifiers would be more complex,
79
+ # and Ruby does not emit warnings for these cases.
80
+ return unless expr.quantifier&.greedy?
81
+
82
+ # normalize quantifiers, e.g. "{1,}" => "+"
83
+ case expr.quantity
84
+ when [0, -1]
85
+ '*'
86
+ when [0, 1]
87
+ '?'
88
+ when [1, -1]
89
+ '+'
90
+ end
91
+ end
92
+
93
+ def merged_quantifier(exp1, exp2)
94
+ quantifier1 = mergeable_quantifier(exp1)
95
+ quantifier2 = mergeable_quantifier(exp2)
96
+ if quantifier1 == quantifier2
97
+ # (?:a+)+ equals (?:a+) ; (?:a*)* equals (?:a*) ; # (?:a?)? equals (?:a?)
98
+ quantifier1
99
+ else
100
+ # (?:a+)*, (?:a+)?, (?:a*)+, (?:a*)?, (?:a?)+, (?:a?)* - all equal (?:a*)
101
+ '*'
102
+ end
103
+ end
104
+
105
+ def quantifier_range(group, child)
106
+ range_between(child.loc.quantifier.begin_pos, group.loc.quantifier.end_pos)
107
+ end
108
+
109
+ def message(group, child, replacement)
110
+ format(
111
+ MSG_REDUNDANT_QUANTIFIER,
112
+ inner_quantifier: child.quantifier.to_s,
113
+ outer_quantifier: group.quantifier.to_s,
114
+ replacement: replacement
115
+ )
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -49,6 +49,11 @@ module RuboCop
49
49
  (str #redundant_feature?))
50
50
  PATTERN
51
51
 
52
+ # @!method pp_const?(node)
53
+ def_node_matcher :pp_const?, <<~PATTERN
54
+ (const {nil? cbase} :PP)
55
+ PATTERN
56
+
52
57
  def on_send(node)
53
58
  return unless redundant_require_statement?(node)
54
59
 
@@ -72,16 +77,16 @@ module RuboCop
72
77
  feature_name == 'enumerator' ||
73
78
  (target_ruby_version >= 2.1 && feature_name == 'thread') ||
74
79
  (target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
75
- (target_ruby_version >= 2.5 && feature_name == 'pp' && !use_pretty_print_method?) ||
80
+ (target_ruby_version >= 2.5 && feature_name == 'pp' && !need_to_require_pp?) ||
76
81
  (target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
77
82
  (target_ruby_version >= 3.1 && feature_name == 'fiber') ||
78
83
  (target_ruby_version >= 3.2 && feature_name == 'set')
79
84
  end
80
85
  # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
81
86
 
82
- def use_pretty_print_method?
87
+ def need_to_require_pp?
83
88
  processed_source.ast.each_descendant(:send).any? do |node|
84
- PRETTY_PRINT_METHODS.include?(node.method_name)
89
+ pp_const?(node.receiver) || PRETTY_PRINT_METHODS.include?(node.method_name)
85
90
  end
86
91
  end
87
92
  end
@@ -49,7 +49,7 @@ module RuboCop
49
49
  # do_something if attrs&.not_nil_safe_method(:[])
50
50
  #
51
51
  class RedundantSafeNavigation < Base
52
- include NilMethods
52
+ include AllowedMethods
53
53
  include RangeHelp
54
54
  extend AutoCorrector
55
55
 
@@ -63,7 +63,7 @@ module RuboCop
63
63
  PATTERN
64
64
 
65
65
  def on_csend(node)
66
- return unless check?(node) && nil_methods.include?(node.method_name)
66
+ return unless check?(node) && allowed_method?(node.method_name)
67
67
  return if respond_to_nil_specific_method?(node)
68
68
 
69
69
  range = range_between(node.loc.dot.begin_pos, node.source_range.end_pos)
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Lint
6
- #
7
- # This cop checks for `send`, `public_send`, and `__send__` methods
6
+ # Checks for `send`, `public_send`, and `__send__` methods
8
7
  # when using mix-in.
9
8
  #
10
9
  # `include` and `prepend` methods were private methods until Ruby 2.0,
@@ -121,18 +121,12 @@ module RuboCop
121
121
 
122
122
  if rescued_exceptions.any?
123
123
  rescued_exceptions.each_with_object([]) do |exception, converted|
124
- # FIXME: Workaround `rubocop:disable` comment for JRuby.
125
- # https://github.com/jruby/jruby/issues/6642
126
- # rubocop:disable Style/RedundantBegin
127
- begin
128
- RuboCop::Util.silence_warnings do
129
- # Avoid printing deprecation warnings about constants
130
- converted << Kernel.const_get(exception.source)
131
- end
132
- rescue NameError
133
- converted << nil
124
+ RuboCop::Util.silence_warnings do
125
+ # Avoid printing deprecation warnings about constants
126
+ converted << Kernel.const_get(exception.source)
134
127
  end
135
- # rubocop:enable Style/RedundantBegin
128
+ rescue NameError
129
+ converted << nil
136
130
  end
137
131
  else
138
132
  # treat an empty `rescue` as `rescue StandardError`
@@ -117,7 +117,7 @@ module RuboCop
117
117
 
118
118
  def comment_between_rescue_and_end?(node)
119
119
  ancestor = node.each_ancestor(:kwbegin, :def, :defs, :block, :numblock).first
120
- return unless ancestor
120
+ return false unless ancestor
121
121
 
122
122
  end_line = ancestor.loc.end.line
123
123
  processed_source[node.first_line...end_line].any? { |line| comment_line?(line) }
@@ -136,7 +136,8 @@ module RuboCop
136
136
  def autocorrect(corrector, assignment)
137
137
  if assignment.exception_assignment?
138
138
  remove_exception_assignment_part(corrector, assignment.node)
139
- elsif assignment.multiple_assignment? || assignment.rest_assignment?
139
+ elsif assignment.multiple_assignment? || assignment.rest_assignment? ||
140
+ assignment.for_assignment?
140
141
  rename_variable_with_underscore(corrector, assignment.node)
141
142
  elsif assignment.operator_assignment?
142
143
  remove_trailing_character_from_operator(corrector, assignment.node)
@@ -144,7 +144,7 @@ module RuboCop
144
144
  end
145
145
 
146
146
  def check_nonmutating(node)
147
- return unless node.respond_to?(:method_name)
147
+ return if !node.send_type? && !node.block_type? && !node.numblock_type?
148
148
 
149
149
  method_name = node.method_name
150
150
  return unless NONMUTATING_METHODS.include?(method_name)
@@ -117,8 +117,7 @@ module RuboCop
117
117
  end
118
118
 
119
119
  def capturing_variable?(name)
120
- # TODO: Remove `Symbol#to_s` after supporting only Ruby >= 2.7.
121
- name && !name.to_s.start_with?('_')
120
+ name && !name.start_with?('_')
122
121
  end
123
122
 
124
123
  def branch?(node)
@@ -16,7 +16,7 @@ module RuboCop
16
16
  # The token that makes up a disable comment.
17
17
  # The allowed specification for comments after `# rubocop: disable` is
18
18
  # `DepartmentName/CopName` or` all`.
19
- DISABLING_COPS_CONTENT_TOKEN = %r{[A-z]+/[A-z]+|all}.freeze
19
+ DISABLING_COPS_CONTENT_TOKEN = %r{[A-Za-z]+/[A-Za-z]+|all}.freeze
20
20
 
21
21
  def on_new_investigation
22
22
  processed_source.comments.each do |comment|
@@ -67,7 +67,7 @@ module RuboCop
67
67
  end
68
68
 
69
69
  def contain_unexpected_character_for_department_name?(name)
70
- name.match?(%r{[^A-z/, ]})
70
+ name.match?(%r{[^A-Za-z/, ]})
71
71
  end
72
72
 
73
73
  def qualified_legacy_cop_name(cop_name)
@@ -25,7 +25,7 @@ module RuboCop
25
25
  def comments_contain_disables?(node, cop_name)
26
26
  disabled_ranges = processed_source.disabled_line_ranges[cop_name]
27
27
 
28
- return unless disabled_ranges
28
+ return false unless disabled_ranges
29
29
 
30
30
  node_range = node.source_range.line...find_end_line(node)
31
31
 
@@ -67,7 +67,7 @@ module RuboCop
67
67
  end
68
68
 
69
69
  def variable_alignment?(whole_expression, rhs, end_alignment_style)
70
- return if end_alignment_style == :keyword
70
+ return false if end_alignment_style == :keyword
71
71
 
72
72
  !line_break_before_keyword?(whole_expression, rhs)
73
73
  end
@@ -9,7 +9,7 @@ module RuboCop
9
9
  private
10
10
 
11
11
  def percent_literal?(node)
12
- return unless (begin_source = begin_source(node))
12
+ return false unless (begin_source = begin_source(node))
13
13
 
14
14
  begin_source.start_with?('%')
15
15
  end
@@ -109,7 +109,7 @@ module RuboCop
109
109
  end
110
110
 
111
111
  def use_block_argument_as_local_variable?(node, last_argument)
112
- return if node.body.nil?
112
+ return false if node.body.nil?
113
113
 
114
114
  node.body.each_descendant(:lvar, :lvasgn).any? do |lvar|
115
115
  !lvar.parent.block_pass_type? && lvar.node_parts[0].to_s == last_argument
@@ -204,14 +204,14 @@ module RuboCop
204
204
  # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
205
205
  def on_defined?(node)
206
206
  arg = node.arguments.first
207
- return unless arg.ivar_type?
207
+ return false unless arg.ivar_type?
208
208
 
209
209
  method_node, method_name = find_definition(node)
210
- return unless method_node
210
+ return false unless method_node
211
211
 
212
212
  var_name = arg.children.first
213
213
  defined_memoized?(method_node.body, var_name) do |defined_ivar, return_ivar, ivar_assign|
214
- return if matches?(method_name, ivar_assign)
214
+ return false if matches?(method_name, ivar_assign)
215
215
 
216
216
  suggested_var = suggested_var(method_name)
217
217
  msg = format(
@@ -3,8 +3,7 @@
3
3
  module RuboCop
4
4
  module Cop
5
5
  module Style
6
- #
7
- # This cop checks for BEGIN blocks.
6
+ # Checks for BEGIN blocks.
8
7
  #
9
8
  # @example
10
9
  # # bad
@@ -35,7 +35,7 @@ module RuboCop
35
35
  unless contents.empty?
36
36
  corrector.replace(
37
37
  contents,
38
- contents.source.gsub(/\A/, '# ').gsub(/\n\n/, "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
38
+ contents.source.gsub(/\A/, '# ').gsub("\n\n", "\n#\n").gsub(/\n(?=[^#])/, "\n# ")
39
39
  )
40
40
  end
41
41
  corrector.remove(eq_end)
@@ -411,7 +411,7 @@ module RuboCop
411
411
  end
412
412
 
413
413
  def correction_would_break_code?(node)
414
- return unless node.keywords?
414
+ return false unless node.keywords?
415
415
 
416
416
  node.send_node.arguments? && !node.send_node.parenthesized?
417
417
  end
@@ -433,7 +433,7 @@ module RuboCop
433
433
  end
434
434
 
435
435
  def return_value_used?(node)
436
- return unless node.parent
436
+ return false unless node.parent
437
437
 
438
438
  # If there are parentheses around the block, check if that
439
439
  # is being used.
@@ -445,7 +445,7 @@ module RuboCop
445
445
  end
446
446
 
447
447
  def return_value_of_scope?(node)
448
- return unless node.parent
448
+ return false unless node.parent
449
449
 
450
450
  conditional?(node.parent) || array_or_range?(node.parent) ||
451
451
  node.parent.children.last == node
@@ -5,7 +5,7 @@ module RuboCop
5
5
  module Style
6
6
  # Enforces the use of `Object#instance_of?` instead of class comparison
7
7
  # for equality.
8
- # `==`, `equal?`, and `eql?` methods are allowed by default.
8
+ # `==`, `equal?`, and `eql?` custom method definitions are allowed by default.
9
9
  # These are customizable with `AllowedMethods` option.
10
10
  #
11
11
  # @example
@@ -18,53 +18,31 @@ module RuboCop
18
18
  # # good
19
19
  # var.instance_of?(Date)
20
20
  #
21
- # @example AllowedMethods: [] (default)
21
+ # @example AllowedMethods: ['==', 'equal?', 'eql?'] (default)
22
22
  # # good
23
- # var.instance_of?(Date)
24
- #
25
- # # bad
26
- # var.class == Date
27
- # var.class.equal?(Date)
28
- # var.class.eql?(Date)
29
- # var.class.name == 'Date'
30
- # var.class.to_s == 'Date'
31
- # var.class.inspect == 'Date'
23
+ # def ==(other)
24
+ # self.class == other.class && name == other.name
25
+ # end
32
26
  #
33
- # @example AllowedMethods: [`==`]
34
- # # good
35
- # var.instance_of?(Date)
36
- # var.class == Date
37
- # var.class.name == 'Date'
38
- # var.class.to_s == 'Date'
39
- # var.class.inspect == 'Date'
27
+ # def equal?(other)
28
+ # self.class.equal?(other.class) && name.equal?(other.name)
29
+ # end
40
30
  #
41
- # # bad
42
- # var.class.equal?(Date)
43
- # var.class.eql?(Date)
31
+ # def eql?(other)
32
+ # self.class.eql?(other.class) && name.eql?(other.name)
33
+ # end
44
34
  #
45
35
  # @example AllowedPatterns: [] (default)
46
- # # good
47
- # var.instance_of?(Date)
48
- #
49
36
  # # bad
50
- # var.class == Date
51
- # var.class.equal?(Date)
52
- # var.class.eql?(Date)
53
- # var.class.name == 'Date'
54
- # var.class.to_s == 'Date'
55
- # var.class.inspect == 'Date'
37
+ # def eq(other)
38
+ # self.class.eq(other.class) && name.eq(other.name)
39
+ # end
56
40
  #
57
41
  # @example AllowedPatterns: ['eq']
58
42
  # # good
59
- # var.instance_of?(Date)
60
- # var.class.equal?(Date)
61
- # var.class.eql?(Date)
62
- #
63
- # # bad
64
- # var.class == Date
65
- # var.class.name == 'Date'
66
- # var.class.to_s == 'Date'
67
- # var.class.inspect == 'Date'
43
+ # def eq(other)
44
+ # self.class.eq(other.class) && name.eq(other.name)
45
+ # end
68
46
  #
69
47
  class ClassEqualityComparison < Base
70
48
  include RangeHelp