rubocop 1.51.0 → 1.52.1
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +20 -2
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_description.rb +32 -8
- data/lib/rubocop/cop/layout/closing_heredoc_indentation.rb +0 -1
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +2 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -2
- data/lib/rubocop/cop/lint/identity_comparison.rb +0 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +1 -2
- data/lib/rubocop/cop/lint/inherit_exception.rb +9 -0
- data/lib/rubocop/cop/lint/missing_super.rb +3 -0
- data/lib/rubocop/cop/lint/ordered_magic_comments.rb +0 -1
- data/lib/rubocop/cop/lint/send_with_mixin_argument.rb +1 -2
- data/lib/rubocop/cop/lint/shadowed_exception.rb +5 -11
- data/lib/rubocop/cop/lint/useless_assignment.rb +4 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -2
- data/lib/rubocop/cop/mixin/allowed_receivers.rb +34 -0
- data/lib/rubocop/cop/naming/variable_name.rb +6 -1
- data/lib/rubocop/cop/style/accessor_grouping.rb +5 -1
- data/lib/rubocop/cop/style/begin_block.rb +1 -2
- data/lib/rubocop/cop/style/class_and_module_children.rb +1 -1
- data/lib/rubocop/cop/style/class_equality_comparison.rb +17 -39
- data/lib/rubocop/cop/style/collection_compact.rb +6 -0
- data/lib/rubocop/cop/style/dir.rb +1 -1
- data/lib/rubocop/cop/style/dir_empty.rb +8 -14
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +8 -2
- data/lib/rubocop/cop/style/file_read.rb +2 -2
- data/lib/rubocop/cop/style/hash_each_methods.rb +1 -22
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +1 -2
- data/lib/rubocop/cop/style/multiple_comparison.rb +14 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +1 -1
- data/lib/rubocop/cop/style/redundant_array_constructor.rb +77 -0
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +101 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +46 -0
- data/lib/rubocop/cop/style/require_order.rb +2 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +1 -3
- data/lib/rubocop/cop/style/select_by_regexp.rb +15 -5
- data/lib/rubocop/cop/style/single_line_methods.rb +1 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/variable_force/assignment.rb +29 -1
- data/lib/rubocop/cop/variable_force.rb +1 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/version.rb +8 -4
- data/lib/rubocop.rb +4 -0
- metadata +13 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84bada99408af7ceb29d5c6bb4e188f61b27a78cb52639bcbbb144a289ebbc92
|
4
|
+
data.tar.gz: 930174d41acdfd3e0f7da8ef80c496ce7e5b68e5b00312d692a2cd93605fa70a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c1f475617dc4826cef3c543ed35e65117bd93ff6f80605adc2096a06ddb38f9171a95800685a92103924600158ac306c27c9168cea787d5f11dc0616bd1a9ba
|
7
|
+
data.tar.gz: 9aaba3f7148469ce255ee22950f7c11542ca1e8480388493ab90c728831e47eef306372c42769a535beaba95d2d715c4b59161852689468cbd3fcd2c2236a535
|
data/README.md
CHANGED
@@ -53,7 +53,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
53
53
|
in your `Gemfile`:
|
54
54
|
|
55
55
|
```rb
|
56
|
-
gem 'rubocop', '~> 1.
|
56
|
+
gem 'rubocop', '~> 1.52', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
data/config/default.yml
CHANGED
@@ -2484,10 +2484,9 @@ Lint/UselessRuby2Keywords:
|
|
2484
2484
|
Lint/UselessSetterCall:
|
2485
2485
|
Description: 'Checks for useless setter call to a local variable.'
|
2486
2486
|
Enabled: true
|
2487
|
-
|
2487
|
+
Safe: false
|
2488
2488
|
VersionAdded: '0.13'
|
2489
2489
|
VersionChanged: '1.2'
|
2490
|
-
Safe: false
|
2491
2490
|
|
2492
2491
|
Lint/UselessTimes:
|
2493
2492
|
Description: 'Checks for useless `Integer#times` calls.'
|
@@ -3363,6 +3362,7 @@ Style/CollectionCompact:
|
|
3363
3362
|
Safe: false
|
3364
3363
|
VersionAdded: '1.2'
|
3365
3364
|
VersionChanged: '1.3'
|
3365
|
+
AllowedReceivers: []
|
3366
3366
|
|
3367
3367
|
# Align with the style guide.
|
3368
3368
|
Style/CollectionMethods:
|
@@ -4383,6 +4383,7 @@ Style/MultipleComparison:
|
|
4383
4383
|
VersionAdded: '0.49'
|
4384
4384
|
VersionChanged: '1.1'
|
4385
4385
|
AllowMethodComparison: true
|
4386
|
+
ComparisonsThreshold: 2
|
4386
4387
|
|
4387
4388
|
Style/MutableConstant:
|
4388
4389
|
Description: 'Do not assign mutable objects to constants.'
|
@@ -4805,6 +4806,11 @@ Style/RedundantArgument:
|
|
4805
4806
|
# String#chomp!
|
4806
4807
|
chomp!: "\n"
|
4807
4808
|
|
4809
|
+
Style/RedundantArrayConstructor:
|
4810
|
+
Description: 'Checks for the instantiation of array using redundant `Array` constructor.'
|
4811
|
+
Enabled: pending
|
4812
|
+
VersionAdded: '1.52'
|
4813
|
+
|
4808
4814
|
Style/RedundantAssignment:
|
4809
4815
|
Description: 'Checks for redundant assignment before returning.'
|
4810
4816
|
Enabled: true
|
@@ -4876,6 +4882,13 @@ Style/RedundantFileExtensionInRequire:
|
|
4876
4882
|
Enabled: true
|
4877
4883
|
VersionAdded: '0.88'
|
4878
4884
|
|
4885
|
+
Style/RedundantFilterChain:
|
4886
|
+
Description: >-
|
4887
|
+
Identifies usages of `any?`, `empty?`, `none?` or `one?` predicate methods chained to
|
4888
|
+
`select`/`filter`/`find_all` and change them to use predicate method instead.
|
4889
|
+
Enabled: pending
|
4890
|
+
VersionAdded: '1.52'
|
4891
|
+
|
4879
4892
|
Style/RedundantFreeze:
|
4880
4893
|
Description: "Checks usages of Object#freeze on immutable objects."
|
4881
4894
|
Enabled: true
|
@@ -4923,6 +4936,11 @@ Style/RedundantRegexpCharacterClass:
|
|
4923
4936
|
Enabled: true
|
4924
4937
|
VersionAdded: '0.85'
|
4925
4938
|
|
4939
|
+
Style/RedundantRegexpConstructor:
|
4940
|
+
Description: 'Checks for the instantiation of regexp using redundant `Regexp.new` or `Regexp.compile`.'
|
4941
|
+
Enabled: pending
|
4942
|
+
VersionAdded: '1.52'
|
4943
|
+
|
4926
4944
|
Style/RedundantRegexpEscape:
|
4927
4945
|
Description: 'Checks for redundant escapes in Regexps.'
|
4928
4946
|
Enabled: true
|
data/lib/rubocop/cop/base.rb
CHANGED
@@ -284,7 +284,7 @@ module RuboCop
|
|
284
284
|
# @api private
|
285
285
|
def self.callbacks_needed
|
286
286
|
@callbacks_needed ||= public_instance_methods.select do |m|
|
287
|
-
m.
|
287
|
+
m.start_with?(/on_|after_/) &&
|
288
288
|
!Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
|
289
289
|
end
|
290
290
|
end
|
@@ -12,6 +12,13 @@ module RuboCop
|
|
12
12
|
# ....
|
13
13
|
# end
|
14
14
|
#
|
15
|
+
# # bad
|
16
|
+
# #
|
17
|
+
# # Checks ...
|
18
|
+
# class SomeCop < Base
|
19
|
+
# ...
|
20
|
+
# end
|
21
|
+
#
|
15
22
|
# # good
|
16
23
|
# # Checks ...
|
17
24
|
# class SomeCop < Base
|
@@ -21,27 +28,47 @@ module RuboCop
|
|
21
28
|
class CopDescription < Base
|
22
29
|
extend AutoCorrector
|
23
30
|
|
24
|
-
|
31
|
+
MSG_STARTS_WITH_WRONG_WORD =
|
32
|
+
'Description should be started with %<suggestion>s instead of `This cop ...`.'
|
33
|
+
MSG_STARTS_WITH_EMPTY_COMMENT_LINE =
|
34
|
+
'Description should not start with an empty comment line.'
|
25
35
|
|
26
36
|
SPECIAL_WORDS = %w[is can could should will would must may].freeze
|
27
37
|
COP_DESC_OFFENSE_REGEX =
|
28
38
|
/^\s+# This cop (?<special>#{SPECIAL_WORDS.join('|')})?\s*(?<word>.+?) .*/.freeze
|
29
39
|
REPLACEMENT_REGEX = /^\s+# This cop (#{SPECIAL_WORDS.join('|')})?\s*(.+?) /.freeze
|
40
|
+
EMPTY_COMMENT_LINE_REGEX = /\A\s*#\s*\n\z/.freeze
|
30
41
|
|
31
|
-
# rubocop:disable Metrics/CyclomaticComplexity
|
32
42
|
def on_class(node)
|
33
43
|
return unless (module_node = node.parent) && node.parent_class
|
34
44
|
|
35
45
|
description_beginning = first_comment_line(module_node)
|
36
46
|
return unless description_beginning
|
37
47
|
|
38
|
-
|
39
|
-
|
48
|
+
if description_beginning.match?(EMPTY_COMMENT_LINE_REGEX)
|
49
|
+
register_offense_for_empty_comment_line(module_node, description_beginning)
|
50
|
+
else
|
51
|
+
start_with_subject = description_beginning.match(COP_DESC_OFFENSE_REGEX)
|
52
|
+
return unless start_with_subject
|
53
|
+
|
54
|
+
register_offense_for_wrong_word(module_node, description_beginning, start_with_subject)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
40
59
|
|
60
|
+
def register_offense_for_empty_comment_line(module_node, description_beginning)
|
61
|
+
range = range(module_node, description_beginning)
|
62
|
+
add_offense(range, message: MSG_STARTS_WITH_EMPTY_COMMENT_LINE) do |corrector|
|
63
|
+
corrector.remove(range)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def register_offense_for_wrong_word(module_node, description_beginning, start_with_subject)
|
41
68
|
suggestion = start_with_subject['word']&.capitalize
|
42
69
|
range = range(module_node, description_beginning)
|
43
70
|
suggestion_for_message = suggestion_for_message(suggestion, start_with_subject)
|
44
|
-
message = format(
|
71
|
+
message = format(MSG_STARTS_WITH_WRONG_WORD, suggestion: suggestion_for_message)
|
45
72
|
|
46
73
|
add_offense(range, message: message) do |corrector|
|
47
74
|
if suggestion && !start_with_subject['special']
|
@@ -49,9 +76,6 @@ module RuboCop
|
|
49
76
|
end
|
50
77
|
end
|
51
78
|
end
|
52
|
-
# rubocop:enable Metrics/CyclomaticComplexity
|
53
|
-
|
54
|
-
private
|
55
79
|
|
56
80
|
def replace_with_suggestion(corrector, range, suggestion, description_beginning)
|
57
81
|
replacement = description_beginning.gsub(REPLACEMENT_REGEX, "#{suggestion} ")
|
@@ -97,7 +97,8 @@ module RuboCop
|
|
97
97
|
def wrap_in_parentheses(corrector, node)
|
98
98
|
range = node.loc.selector.end.join(node.first_argument.source_range.begin)
|
99
99
|
|
100
|
-
corrector.
|
100
|
+
corrector.remove(range)
|
101
|
+
corrector.insert_before(range, '(')
|
101
102
|
corrector.insert_after(node.last_argument, ')')
|
102
103
|
end
|
103
104
|
end
|
@@ -3,8 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
#
|
7
|
-
# This cop checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
|
6
|
+
# Checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
|
8
7
|
#
|
9
8
|
# When an array of IO objects waiting for an exception (the third argument of `IO.select`)
|
10
9
|
# is used as an argument, there is no alternative API, so offenses are not registered.
|
@@ -58,6 +58,7 @@ module RuboCop
|
|
58
58
|
|
59
59
|
def on_class(node)
|
60
60
|
return unless node.parent_class && exception_class?(node.parent_class)
|
61
|
+
return if inherit_exception_class_with_omitted_namespace?(node)
|
61
62
|
|
62
63
|
message = message(node.parent_class)
|
63
64
|
|
@@ -87,6 +88,14 @@ module RuboCop
|
|
87
88
|
class_node.const_name == 'Exception'
|
88
89
|
end
|
89
90
|
|
91
|
+
def inherit_exception_class_with_omitted_namespace?(class_node)
|
92
|
+
return false if class_node.parent_class.namespace&.cbase_type?
|
93
|
+
|
94
|
+
class_node.left_siblings.any? do |sibling|
|
95
|
+
sibling.respond_to?(:identifier) && exception_class?(sibling.identifier)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
90
99
|
def preferred_base_class
|
91
100
|
PREFERRED_BASE_CLASS[style]
|
92
101
|
end
|
@@ -11,6 +11,9 @@ module RuboCop
|
|
11
11
|
# missing method. In other cases, the theoretical ideal handling could be
|
12
12
|
# challenging or verbose for no actual gain.
|
13
13
|
#
|
14
|
+
# Autocorrection is not supported because the position of `super` cannot be
|
15
|
+
# determined automatically.
|
16
|
+
#
|
14
17
|
# @example
|
15
18
|
# # bad
|
16
19
|
# class Employee < Person
|
@@ -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
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
128
|
+
rescue NameError
|
129
|
+
converted << nil
|
136
130
|
end
|
137
131
|
else
|
138
132
|
# treat an empty `rescue` as `rescue StandardError`
|
@@ -132,10 +132,12 @@ module RuboCop
|
|
132
132
|
node.receiver.nil? && !node.arguments?
|
133
133
|
end
|
134
134
|
|
135
|
+
# rubocop:disable Metrics/AbcSize
|
135
136
|
def autocorrect(corrector, assignment)
|
136
137
|
if assignment.exception_assignment?
|
137
138
|
remove_exception_assignment_part(corrector, assignment.node)
|
138
|
-
elsif assignment.multiple_assignment?
|
139
|
+
elsif assignment.multiple_assignment? || assignment.rest_assignment? ||
|
140
|
+
assignment.for_assignment?
|
139
141
|
rename_variable_with_underscore(corrector, assignment.node)
|
140
142
|
elsif assignment.operator_assignment?
|
141
143
|
remove_trailing_character_from_operator(corrector, assignment.node)
|
@@ -146,6 +148,7 @@ module RuboCop
|
|
146
148
|
remove_local_variable_assignment_part(corrector, assignment.node)
|
147
149
|
end
|
148
150
|
end
|
151
|
+
# rubocop:enable Metrics/AbcSize
|
149
152
|
|
150
153
|
def remove_exception_assignment_part(corrector, node)
|
151
154
|
corrector.remove(
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
# This module encapsulates the ability to allow certain receivers in a cop.
|
6
|
+
module AllowedReceivers
|
7
|
+
def allowed_receiver?(receiver)
|
8
|
+
receiver_name = receiver_name(receiver)
|
9
|
+
|
10
|
+
allowed_receivers.include?(receiver_name)
|
11
|
+
end
|
12
|
+
|
13
|
+
def receiver_name(receiver)
|
14
|
+
if receiver.receiver && !receiver.receiver.const_type?
|
15
|
+
return receiver_name(receiver.receiver)
|
16
|
+
end
|
17
|
+
|
18
|
+
if receiver.send_type?
|
19
|
+
if receiver.receiver
|
20
|
+
"#{receiver_name(receiver.receiver)}.#{receiver.method_name}"
|
21
|
+
else
|
22
|
+
receiver.method_name.to_s
|
23
|
+
end
|
24
|
+
else
|
25
|
+
receiver.source
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def allowed_receivers
|
30
|
+
cop_config.fetch('AllowedReceivers', [])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -20,9 +20,14 @@ module RuboCop
|
|
20
20
|
# # good
|
21
21
|
# fooBar = 1
|
22
22
|
#
|
23
|
+
# @example AllowedIdentifiers: ['fooBar']
|
24
|
+
# # good (with EnforcedStyle: snake_case)
|
25
|
+
# fooBar = 1
|
26
|
+
#
|
23
27
|
# @example AllowedPatterns: ['_v\d+\z']
|
24
|
-
# # good
|
28
|
+
# # good (with EnforcedStyle: camelCase)
|
25
29
|
# :release_v1
|
30
|
+
#
|
26
31
|
class VariableName < Base
|
27
32
|
include AllowedIdentifiers
|
28
33
|
include ConfigurableNaming
|
@@ -92,6 +92,7 @@ module RuboCop
|
|
92
92
|
comment_line?(processed_source[node.first_line - 2])
|
93
93
|
end
|
94
94
|
|
95
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
95
96
|
def groupable_accessor?(node)
|
96
97
|
return true unless (previous_expression = node.left_siblings.last)
|
97
98
|
|
@@ -104,8 +105,11 @@ module RuboCop
|
|
104
105
|
|
105
106
|
return true unless previous_expression.send_type?
|
106
107
|
|
107
|
-
previous_expression.attribute_accessor? ||
|
108
|
+
previous_expression.attribute_accessor? ||
|
109
|
+
previous_expression.access_modifier? ||
|
110
|
+
node.first_line - previous_expression.last_line > 1 # there is a space between nodes
|
108
111
|
end
|
112
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
109
113
|
|
110
114
|
def class_send_elements(class_node)
|
111
115
|
class_def = class_node.body
|
@@ -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?`
|
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
|
-
#
|
24
|
-
#
|
25
|
-
#
|
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
|
-
#
|
34
|
-
#
|
35
|
-
#
|
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
|
-
#
|
42
|
-
#
|
43
|
-
#
|
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
|
-
#
|
51
|
-
#
|
52
|
-
#
|
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
|
-
#
|
60
|
-
#
|
61
|
-
#
|
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
|
@@ -35,7 +35,12 @@ module RuboCop
|
|
35
35
|
# # good
|
36
36
|
# hash.compact!
|
37
37
|
#
|
38
|
+
# @example AllowedReceivers: ['params']
|
39
|
+
# # good
|
40
|
+
# params.reject(&:nil?)
|
41
|
+
#
|
38
42
|
class CollectionCompact < Base
|
43
|
+
include AllowedReceivers
|
39
44
|
include RangeHelp
|
40
45
|
extend AutoCorrector
|
41
46
|
extend TargetRubyVersion
|
@@ -76,6 +81,7 @@ module RuboCop
|
|
76
81
|
|
77
82
|
def on_send(node)
|
78
83
|
return unless (range = offense_range(node))
|
84
|
+
return if allowed_receiver?(node.receiver)
|
79
85
|
if (target_ruby_version <= 3.0 || node.method?(:delete_if)) && to_enum_method?(node)
|
80
86
|
return
|
81
87
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Checks for places where the
|
6
|
+
# Checks for places where the `#\_\_dir\_\_` method can replace more
|
7
7
|
# complex constructs to retrieve a canonicalized absolute path to the
|
8
8
|
# current file.
|
9
9
|
#
|
@@ -19,18 +19,16 @@ module RuboCop
|
|
19
19
|
extend AutoCorrector
|
20
20
|
extend TargetRubyVersion
|
21
21
|
|
22
|
-
MSG = 'Use
|
23
|
-
RESTRICT_ON_SEND = %i[== > empty? none?].freeze
|
22
|
+
MSG = 'Use `%<replacement>s` instead.'
|
23
|
+
RESTRICT_ON_SEND = %i[== != > empty? none?].freeze
|
24
24
|
|
25
25
|
minimum_target_ruby_version 2.4
|
26
26
|
|
27
27
|
# @!method offensive?(node)
|
28
28
|
def_node_matcher :offensive?, <<~PATTERN
|
29
29
|
{
|
30
|
-
(send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) {:== :>} (int 2))
|
31
|
-
(send (send (send $(const {nil? cbase} :Dir) :children $_) :size) {:== :>} (int 0))
|
32
|
-
(send (send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) :!) {:== :>} (int 2))
|
33
|
-
(send (send (send (send $(const {nil? cbase} :Dir) :children $_) :size) :!) {:== :>} (int 0))
|
30
|
+
(send (send (send $(const {nil? cbase} :Dir) :entries $_) :size) {:== :!= :>} (int 2))
|
31
|
+
(send (send (send $(const {nil? cbase} :Dir) :children $_) :size) {:== :!= :>} (int 0))
|
34
32
|
(send (send $(const {nil? cbase} :Dir) :children $_) :empty?)
|
35
33
|
(send (send $(const {nil? cbase} :Dir) :each_child $_) :none?)
|
36
34
|
}
|
@@ -38,10 +36,9 @@ module RuboCop
|
|
38
36
|
|
39
37
|
def on_send(node)
|
40
38
|
offensive?(node) do |const_node, arg_node|
|
41
|
-
|
42
|
-
|
43
|
-
corrector.replace(node,
|
44
|
-
"#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})")
|
39
|
+
replacement = "#{bang(node)}#{const_node.source}.empty?(#{arg_node.source})"
|
40
|
+
add_offense(node, message: format(MSG, replacement: replacement)) do |corrector|
|
41
|
+
corrector.replace(node, replacement)
|
45
42
|
end
|
46
43
|
end
|
47
44
|
end
|
@@ -49,10 +46,7 @@ module RuboCop
|
|
49
46
|
private
|
50
47
|
|
51
48
|
def bang(node)
|
52
|
-
if
|
53
|
-
(node.method?(:>) && !node.child_nodes.first.method?(:!))
|
54
|
-
'!'
|
55
|
-
end
|
49
|
+
'!' if %i[!= >].include? node.method_name
|
56
50
|
end
|
57
51
|
end
|
58
52
|
end
|
@@ -4,12 +4,12 @@ module RuboCop
|
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
6
|
# Ensures that eval methods (`eval`, `instance_eval`, `class_eval`
|
7
|
-
# and `module_eval`) are given filename and line number values (`
|
8
|
-
# and `
|
7
|
+
# and `module_eval`) are given filename and line number values (`\_\_FILE\_\_`
|
8
|
+
# and `\_\_LINE\_\_`). This data is used to ensure that any errors raised
|
9
9
|
# within the evaluated code will be given the correct identification
|
10
10
|
# in a backtrace.
|
11
11
|
#
|
12
|
-
# The cop also checks that the line number given relative to `
|
12
|
+
# The cop also checks that the line number given relative to `\_\_LINE\_\_` is
|
13
13
|
# correct.
|
14
14
|
#
|
15
15
|
# This cop will autocorrect incorrect or missing filename and line number
|
@@ -57,7 +57,7 @@ module RuboCop
|
|
57
57
|
extend AutoCorrector
|
58
58
|
|
59
59
|
MSG = 'Pass `__FILE__` and `__LINE__` to `%<method_name>s`.'
|
60
|
-
MSG_EVAL = 'Pass a binding, `__FILE__
|
60
|
+
MSG_EVAL = 'Pass a binding, `__FILE__`, and `__LINE__` to `eval`.'
|
61
61
|
MSG_INCORRECT_FILE = 'Incorrect file for `%<method_name>s`; ' \
|
62
62
|
'use `%<expected>s` instead of `%<actual>s`.'
|
63
63
|
MSG_INCORRECT_LINE = 'Incorrect line number for `%<method_name>s`; ' \
|
@@ -41,8 +41,7 @@ module RuboCop
|
|
41
41
|
return unless (regexp = exact_regexp_match(node))
|
42
42
|
|
43
43
|
parsed_regexp = Regexp::Parser.parse(regexp)
|
44
|
-
|
45
|
-
return unless tokens[0] == :bos && tokens[1] == :literal && tokens[2] == :eos
|
44
|
+
return unless exact_match_pattern?(parsed_regexp)
|
46
45
|
|
47
46
|
prefer = "#{node.receiver.source} #{new_method(node)} '#{parsed_regexp[1].text}'"
|
48
47
|
|
@@ -53,6 +52,13 @@ module RuboCop
|
|
53
52
|
|
54
53
|
private
|
55
54
|
|
55
|
+
def exact_match_pattern?(parsed_regexp)
|
56
|
+
tokens = parsed_regexp.map(&:token)
|
57
|
+
return false unless tokens[0] == :bos && tokens[1] == :literal && tokens[2] == :eos
|
58
|
+
|
59
|
+
!parsed_regexp[1].quantifier
|
60
|
+
end
|
61
|
+
|
56
62
|
def new_method(node)
|
57
63
|
node.method?(:!~) ? '!=' : '=='
|
58
64
|
end
|