rubocop 1.41.0 → 1.42.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.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +26 -1
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/config.rb +7 -7
- data/lib/rubocop/config_loader_resolver.rb +5 -1
- data/lib/rubocop/cop/base.rb +62 -61
- data/lib/rubocop/cop/cop.rb +28 -28
- data/lib/rubocop/cop/corrector.rb +23 -11
- data/lib/rubocop/cop/gemspec/dependency_version.rb +16 -18
- data/lib/rubocop/cop/layout/class_structure.rb +32 -11
- data/lib/rubocop/cop/layout/comment_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +6 -6
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -1
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +19 -0
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +3 -1
- data/lib/rubocop/cop/lint/regexp_as_condition.rb +6 -0
- data/lib/rubocop/cop/lint/require_parentheses.rb +3 -1
- data/lib/rubocop/cop/lint/unused_method_argument.rb +2 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -3
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -4
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/registry.rb +22 -22
- data/lib/rubocop/cop/security/compound_hash.rb +2 -1
- data/lib/rubocop/cop/style/alias.rb +9 -1
- data/lib/rubocop/cop/style/block_comments.rb +1 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +22 -2
- data/lib/rubocop/cop/style/documentation.rb +10 -4
- data/lib/rubocop/cop/style/guard_clause.rb +12 -8
- data/lib/rubocop/cop/style/hash_syntax.rb +10 -7
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +15 -0
- data/lib/rubocop/cop/style/map_to_set.rb +61 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +11 -4
- data/lib/rubocop/cop/style/min_max_comparison.rb +73 -0
- data/lib/rubocop/cop/style/redundant_string_escape.rb +6 -3
- data/lib/rubocop/cop/style/require_order.rb +4 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +6 -2
- data/lib/rubocop/cop/style/signal_exception.rb +8 -6
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -4
- data/lib/rubocop/cop/style/word_array.rb +41 -0
- data/lib/rubocop/cop/style/yoda_expression.rb +74 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +31 -14
- data/lib/rubocop/cop/team.rb +29 -29
- data/lib/rubocop/cop/variable_force.rb +0 -3
- data/lib/rubocop/cops_documentation_generator.rb +11 -8
- data/lib/rubocop/formatter.rb +2 -0
- data/lib/rubocop/path_util.rb +6 -1
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/runner.rb +10 -3
- data/lib/rubocop/target_ruby.rb +0 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -0
- metadata +12 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e37ffc01dbd2782dd811d4c35129f893502179457e76d8e3501d7c3683563cc2
|
4
|
+
data.tar.gz: 9dba5be8e2168e986170e8366a62c73940262bfffec0a374c3a01b3f207ca291
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23769dc5239a734dc07a859a594e1cc0b732d05d24c61c1887525f9f69f748e0c23cbb84404e865e00a04bfb5c91e73d1e0bdb7908a72340ede4245fc38508c6
|
7
|
+
data.tar.gz: f016891fb54e93a8f6c418d4aa97f7400a74c187c8cf5dbbe274020ea5bda900721f2a7fefbbb368472664cf21a4b586db4fb9373510c27da6428aa490d504e6
|
data/LICENSE.txt
CHANGED
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.42', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -246,5 +246,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
246
246
|
|
247
247
|
## Copyright
|
248
248
|
|
249
|
-
Copyright (c) 2012-
|
249
|
+
Copyright (c) 2012-2023 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
250
250
|
further details.
|
data/config/default.yml
CHANGED
@@ -3429,6 +3429,7 @@ Style/CommentedKeyword:
|
|
3429
3429
|
Style/ConcatArrayLiterals:
|
3430
3430
|
Description: 'Enforces the use of `Array#push(item)` instead of `Array#concat([item])` to avoid redundant array literals.'
|
3431
3431
|
Enabled: pending
|
3432
|
+
Safe: false
|
3432
3433
|
VersionAdded: '1.41'
|
3433
3434
|
|
3434
3435
|
Style/ConditionalAssignment:
|
@@ -3900,7 +3901,7 @@ Style/HashSyntax:
|
|
3900
3901
|
- never
|
3901
3902
|
# accepts both shorthand and explicit use of hash literal value.
|
3902
3903
|
- either
|
3903
|
-
#
|
3904
|
+
# forces use of the 3.1 syntax only if all values can be omitted in the hash.
|
3904
3905
|
- consistent
|
3905
3906
|
# Force hashes that have a symbol value to use hash rockets
|
3906
3907
|
UseHashRocketsWithSymbolValues: false
|
@@ -4109,6 +4110,12 @@ Style/MapToHash:
|
|
4109
4110
|
VersionAdded: '1.24'
|
4110
4111
|
Safe: false
|
4111
4112
|
|
4113
|
+
Style/MapToSet:
|
4114
|
+
Description: 'Prefer `to_set` with a block over `map.to_set`.'
|
4115
|
+
Enabled: pending
|
4116
|
+
Safe: false
|
4117
|
+
VersionAdded: '1.42'
|
4118
|
+
|
4112
4119
|
Style/MethodCallWithArgsParentheses:
|
4113
4120
|
Description: 'Use parentheses for method calls with arguments.'
|
4114
4121
|
StyleGuide: '#method-invocation-parens'
|
@@ -4167,6 +4174,12 @@ Style/MinMax:
|
|
4167
4174
|
Enabled: true
|
4168
4175
|
VersionAdded: '0.50'
|
4169
4176
|
|
4177
|
+
Style/MinMaxComparison:
|
4178
|
+
Description: 'Enforces the use of `max` or `min` instead of comparison for greater or less.'
|
4179
|
+
Enabled: pending
|
4180
|
+
Safe: false
|
4181
|
+
VersionAdded: '1.42'
|
4182
|
+
|
4170
4183
|
Style/MissingElse:
|
4171
4184
|
Description: >-
|
4172
4185
|
Require if/case expressions to have an else branches.
|
@@ -5425,6 +5438,18 @@ Style/YodaCondition:
|
|
5425
5438
|
VersionAdded: '0.49'
|
5426
5439
|
VersionChanged: '0.75'
|
5427
5440
|
|
5441
|
+
Style/YodaExpression:
|
5442
|
+
Description: 'Forbid the use of yoda expressions.'
|
5443
|
+
Enabled: pending
|
5444
|
+
Safe: false
|
5445
|
+
VersionAdded: '1.42'
|
5446
|
+
SupportedOperators:
|
5447
|
+
- '*'
|
5448
|
+
- '+'
|
5449
|
+
- '&'
|
5450
|
+
- '|'
|
5451
|
+
- '^'
|
5452
|
+
|
5428
5453
|
Style/ZeroLengthPredicate:
|
5429
5454
|
Description: 'Use #empty? when testing for objects of length 0.'
|
5430
5455
|
Enabled: true
|
data/lib/rubocop/cli.rb
CHANGED
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
STATUS_SUCCESS = 0
|
8
8
|
STATUS_OFFENSES = 1
|
9
9
|
STATUS_ERROR = 2
|
10
|
-
STATUS_INTERRUPTED =
|
10
|
+
STATUS_INTERRUPTED = Signal.list['INT'] + 128
|
11
11
|
DEFAULT_PARALLEL_OPTIONS = %i[
|
12
12
|
color debug display_style_guide display_time display_only_fail_level_offenses
|
13
13
|
display_only_failed except extra_details fail_level fix_layout format
|
data/lib/rubocop/config.rb
CHANGED
@@ -21,6 +21,13 @@ module RuboCop
|
|
21
21
|
DEFAULT_RAILS_VERSION = 5.0
|
22
22
|
attr_reader :loaded_path
|
23
23
|
|
24
|
+
def self.create(hash, path, check: true)
|
25
|
+
config = new(hash, path)
|
26
|
+
config.check if check
|
27
|
+
|
28
|
+
config
|
29
|
+
end
|
30
|
+
|
24
31
|
# rubocop:disable Metrics/AbcSize
|
25
32
|
def initialize(hash = {}, loaded_path = nil)
|
26
33
|
@loaded_path = loaded_path
|
@@ -39,13 +46,6 @@ module RuboCop
|
|
39
46
|
end
|
40
47
|
# rubocop:enable Metrics/AbcSize
|
41
48
|
|
42
|
-
def self.create(hash, path, check: true)
|
43
|
-
config = new(hash, path)
|
44
|
-
config.check if check
|
45
|
-
|
46
|
-
config
|
47
|
-
end
|
48
|
-
|
49
49
|
def loaded_features
|
50
50
|
@loaded_features ||= ConfigLoader.loaded_features
|
51
51
|
end
|
@@ -206,7 +206,11 @@ module RuboCop
|
|
206
206
|
end
|
207
207
|
|
208
208
|
def base_configs(path, inherit_from, file)
|
209
|
-
|
209
|
+
inherit_froms = Array(inherit_from).compact.flat_map do |f|
|
210
|
+
PathUtil.glob?(f) ? Dir.glob(f) : f
|
211
|
+
end
|
212
|
+
|
213
|
+
configs = inherit_froms.map do |f|
|
210
214
|
ConfigLoader.load_file(inherited_file(path, f, file))
|
211
215
|
end
|
212
216
|
|
data/lib/rubocop/cop/base.rb
CHANGED
@@ -68,6 +68,64 @@ module RuboCop
|
|
68
68
|
Documentation.url_for(self) if builtin?
|
69
69
|
end
|
70
70
|
|
71
|
+
def self.inherited(subclass)
|
72
|
+
super
|
73
|
+
Registry.global.enlist(subclass)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Call for abstract Cop classes
|
77
|
+
def self.exclude_from_registry
|
78
|
+
Registry.global.dismiss(self)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Returns if class supports autocorrect.
|
82
|
+
# It is recommended to extend AutoCorrector instead of overriding
|
83
|
+
def self.support_autocorrect?
|
84
|
+
false
|
85
|
+
end
|
86
|
+
|
87
|
+
### Naming
|
88
|
+
|
89
|
+
def self.badge
|
90
|
+
@badge ||= Badge.for(name)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.cop_name
|
94
|
+
badge.to_s
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.department
|
98
|
+
badge.department
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.lint?
|
102
|
+
department == :Lint
|
103
|
+
end
|
104
|
+
|
105
|
+
# Returns true if the cop name or the cop namespace matches any of the
|
106
|
+
# given names.
|
107
|
+
def self.match?(given_names)
|
108
|
+
return false unless given_names
|
109
|
+
|
110
|
+
given_names.include?(cop_name) || given_names.include?(badge.department_name)
|
111
|
+
end
|
112
|
+
|
113
|
+
# Override and return the Force class(es) you need to join
|
114
|
+
def self.joining_forces; end
|
115
|
+
|
116
|
+
### Persistence
|
117
|
+
|
118
|
+
# Override if your cop should be called repeatedly for multiple investigations
|
119
|
+
# Between calls to `on_new_investigation` and `on_investigation_end`,
|
120
|
+
# the result of `processed_source` will remain constant.
|
121
|
+
# You should invalidate any caches that depend on the current `processed_source`
|
122
|
+
# in the `on_new_investigation` callback.
|
123
|
+
# If your cop does autocorrections, be aware that your instance may be called
|
124
|
+
# multiple times with the same `processed_source.path` but different content.
|
125
|
+
def self.support_multiple_source?
|
126
|
+
false
|
127
|
+
end
|
128
|
+
|
71
129
|
def initialize(config = nil, options = nil)
|
72
130
|
@config = config || Config.new
|
73
131
|
@options = options || { debug: false }
|
@@ -92,9 +150,6 @@ module RuboCop
|
|
92
150
|
# Typically do nothing here
|
93
151
|
end
|
94
152
|
|
95
|
-
# Override and return the Force class(es) you need to join
|
96
|
-
def self.joining_forces; end
|
97
|
-
|
98
153
|
# Gets called if no message is specified when calling `add_offense` or
|
99
154
|
# `add_global_offense`
|
100
155
|
# Cops are discouraged to override this; instead pass your message directly
|
@@ -147,48 +202,6 @@ module RuboCop
|
|
147
202
|
nil
|
148
203
|
end
|
149
204
|
|
150
|
-
def self.inherited(subclass)
|
151
|
-
super
|
152
|
-
Registry.global.enlist(subclass)
|
153
|
-
end
|
154
|
-
|
155
|
-
# Call for abstract Cop classes
|
156
|
-
def self.exclude_from_registry
|
157
|
-
Registry.global.dismiss(self)
|
158
|
-
end
|
159
|
-
|
160
|
-
# Returns if class supports autocorrect.
|
161
|
-
# It is recommended to extend AutoCorrector instead of overriding
|
162
|
-
def self.support_autocorrect?
|
163
|
-
false
|
164
|
-
end
|
165
|
-
|
166
|
-
### Naming
|
167
|
-
|
168
|
-
def self.badge
|
169
|
-
@badge ||= Badge.for(name)
|
170
|
-
end
|
171
|
-
|
172
|
-
def self.cop_name
|
173
|
-
badge.to_s
|
174
|
-
end
|
175
|
-
|
176
|
-
def self.department
|
177
|
-
badge.department
|
178
|
-
end
|
179
|
-
|
180
|
-
def self.lint?
|
181
|
-
department == :Lint
|
182
|
-
end
|
183
|
-
|
184
|
-
# Returns true if the cop name or the cop namespace matches any of the
|
185
|
-
# given names.
|
186
|
-
def self.match?(given_names)
|
187
|
-
return false unless given_names
|
188
|
-
|
189
|
-
given_names.include?(cop_name) || given_names.include?(badge.department_name)
|
190
|
-
end
|
191
|
-
|
192
205
|
def cop_name
|
193
206
|
@cop_name ||= self.class.cop_name
|
194
207
|
end
|
@@ -240,19 +253,6 @@ module RuboCop
|
|
240
253
|
ProcessedSource.new(source, target_ruby_version, path)
|
241
254
|
end
|
242
255
|
|
243
|
-
### Persistence
|
244
|
-
|
245
|
-
# Override if your cop should be called repeatedly for multiple investigations
|
246
|
-
# Between calls to `on_new_investigation` and `on_investigation_end`,
|
247
|
-
# the result of `processed_source` will remain constant.
|
248
|
-
# You should invalidate any caches that depend on the current `processed_source`
|
249
|
-
# in the `on_new_investigation` callback.
|
250
|
-
# If your cop does autocorrections, be aware that your instance may be called
|
251
|
-
# multiple times with the same `processed_source.path` but different content.
|
252
|
-
def self.support_multiple_source?
|
253
|
-
false
|
254
|
-
end
|
255
|
-
|
256
256
|
# @api private
|
257
257
|
# Called between investigations
|
258
258
|
def ready
|
@@ -271,6 +271,7 @@ module RuboCop
|
|
271
271
|
|
272
272
|
### Reserved for Commissioner
|
273
273
|
|
274
|
+
# rubocop:disable Layout/ClassStructure
|
274
275
|
# @api private
|
275
276
|
def callbacks_needed
|
276
277
|
self.class.callbacks_needed
|
@@ -283,6 +284,7 @@ module RuboCop
|
|
283
284
|
!Base.method_defined?(m) # exclude standard "callbacks" like 'on_begin_investigation'
|
284
285
|
end
|
285
286
|
end
|
287
|
+
# rubocop:enable Layout/ClassStructure
|
286
288
|
|
287
289
|
private
|
288
290
|
|
@@ -327,11 +329,8 @@ module RuboCop
|
|
327
329
|
@current_corrector = nil
|
328
330
|
end
|
329
331
|
|
330
|
-
# rubocop:disable Layout/ClassStructure
|
331
332
|
EMPTY_OFFENSES = [].freeze
|
332
333
|
private_constant :EMPTY_OFFENSES
|
333
|
-
# rubocop:enable Layout/ClassStructure
|
334
|
-
|
335
334
|
# Called to complete an investigation
|
336
335
|
def complete_investigation
|
337
336
|
InvestigationReport.new(
|
@@ -343,6 +342,7 @@ module RuboCop
|
|
343
342
|
|
344
343
|
### Actually private methods
|
345
344
|
|
345
|
+
# rubocop:disable Layout/ClassStructure
|
346
346
|
def self.builtin?
|
347
347
|
return false unless (m = instance_methods(false).first) # any custom method will do
|
348
348
|
|
@@ -350,6 +350,7 @@ module RuboCop
|
|
350
350
|
path.start_with?(__dir__)
|
351
351
|
end
|
352
352
|
private_class_method :builtin?
|
353
|
+
# rubocop:enable Layout/ClassStructure
|
353
354
|
|
354
355
|
def reset_investigation
|
355
356
|
@currently_disabled_lines = @current_offenses = @processed_source = @current_corrector = nil
|
data/lib/rubocop/cop/cop.rb
CHANGED
@@ -22,6 +22,34 @@ module RuboCop
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.support_autocorrect?
|
26
|
+
method_defined?(:autocorrect)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.joining_forces
|
30
|
+
return unless method_defined?(:join_force?)
|
31
|
+
|
32
|
+
cop = new
|
33
|
+
Force.all.select { |force_class| cop.join_force?(force_class) }
|
34
|
+
end
|
35
|
+
|
36
|
+
### Deprecated registry access
|
37
|
+
|
38
|
+
# @deprecated Use Registry.global
|
39
|
+
def self.registry
|
40
|
+
Registry.global
|
41
|
+
end
|
42
|
+
|
43
|
+
# @deprecated Use Registry.all
|
44
|
+
def self.all
|
45
|
+
Registry.all
|
46
|
+
end
|
47
|
+
|
48
|
+
# @deprecated Use Registry.qualified_cop_name
|
49
|
+
def self.qualified_cop_name(name, origin)
|
50
|
+
Registry.qualified_cop_name(name, origin)
|
51
|
+
end
|
52
|
+
|
25
53
|
def add_offense(node_or_range, location: :expression, message: nil, severity: nil, &block)
|
26
54
|
@v0_argument = node_or_range
|
27
55
|
range = find_location(node_or_range, location)
|
@@ -45,17 +73,6 @@ module RuboCop
|
|
45
73
|
self.class.support_autocorrect?
|
46
74
|
end
|
47
75
|
|
48
|
-
def self.support_autocorrect?
|
49
|
-
method_defined?(:autocorrect)
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.joining_forces
|
53
|
-
return unless method_defined?(:join_force?)
|
54
|
-
|
55
|
-
cop = new
|
56
|
-
Force.all.select { |force_class| cop.join_force?(force_class) }
|
57
|
-
end
|
58
|
-
|
59
76
|
# @deprecated
|
60
77
|
def corrections
|
61
78
|
# warn 'Cop#corrections is deprecated' TODO
|
@@ -76,23 +93,6 @@ module RuboCop
|
|
76
93
|
super
|
77
94
|
end
|
78
95
|
|
79
|
-
### Deprecated registry access
|
80
|
-
|
81
|
-
# @deprecated Use Registry.global
|
82
|
-
def self.registry
|
83
|
-
Registry.global
|
84
|
-
end
|
85
|
-
|
86
|
-
# @deprecated Use Registry.all
|
87
|
-
def self.all
|
88
|
-
Registry.all
|
89
|
-
end
|
90
|
-
|
91
|
-
# @deprecated Use Registry.qualified_cop_name
|
92
|
-
def self.qualified_cop_name(name, origin)
|
93
|
-
Registry.qualified_cop_name(name, origin)
|
94
|
-
end
|
95
|
-
|
96
96
|
private
|
97
97
|
|
98
98
|
def begin_investigation(processed_source)
|
@@ -11,6 +11,20 @@ module RuboCop
|
|
11
11
|
class Corrector < ::Parser::Source::TreeRewriter
|
12
12
|
NOOP_CONSUMER = ->(diagnostic) {} # noop
|
13
13
|
|
14
|
+
# Duck typing for get to a ::Parser::Source::Buffer
|
15
|
+
def self.source_buffer(source)
|
16
|
+
source = source.processed_source if source.respond_to?(:processed_source)
|
17
|
+
source = source.buffer if source.respond_to?(:buffer)
|
18
|
+
source = source.source_buffer if source.respond_to?(:source_buffer)
|
19
|
+
|
20
|
+
unless source.is_a? ::Parser::Source::Buffer
|
21
|
+
raise TypeError, 'Expected argument to lead to a Parser::Source::Buffer ' \
|
22
|
+
"but got #{source.inspect}"
|
23
|
+
end
|
24
|
+
|
25
|
+
source
|
26
|
+
end
|
27
|
+
|
14
28
|
# @param source [Parser::Source::Buffer, or anything
|
15
29
|
# leading to one via `(processed_source.)buffer`]
|
16
30
|
#
|
@@ -64,18 +78,16 @@ module RuboCop
|
|
64
78
|
remove(to_remove)
|
65
79
|
end
|
66
80
|
|
67
|
-
#
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
raise TypeError, 'Expected argument to lead to a Parser::Source::Buffer ' \
|
75
|
-
"but got #{source.inspect}"
|
76
|
-
end
|
81
|
+
# Swaps sources at the given ranges.
|
82
|
+
#
|
83
|
+
# @param [Parser::Source::Range, RuboCop::AST::Node] node_or_range1
|
84
|
+
# @param [Parser::Source::Range, RuboCop::AST::Node] node_or_range2
|
85
|
+
def swap(node_or_range1, node_or_range2)
|
86
|
+
range1 = to_range(node_or_range1)
|
87
|
+
range2 = to_range(node_or_range2)
|
77
88
|
|
78
|
-
source
|
89
|
+
replace(range1, range2.source)
|
90
|
+
replace(range2, range1.source)
|
79
91
|
end
|
80
92
|
|
81
93
|
private
|
@@ -58,8 +58,13 @@ module RuboCop
|
|
58
58
|
FORBIDDEN_MSG = 'Dependency version specification is forbidden.'
|
59
59
|
VERSION_SPECIFICATION_REGEX = /^\s*[~<>=]*\s*[0-9.]+/.freeze
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
ADD_DEPENDENCY_METHODS = %i[
|
62
|
+
add_dependency add_runtime_dependency add_development_dependency
|
63
|
+
].freeze
|
64
|
+
RESTRICT_ON_SEND = ADD_DEPENDENCY_METHODS
|
65
|
+
|
66
|
+
# @!method add_dependency_method_declaration?(node)
|
67
|
+
def_node_matcher :add_dependency_method_declaration?, <<~PATTERN
|
63
68
|
(send
|
64
69
|
(lvar #match_block_variable_name?) #add_dependency_method? ...)
|
65
70
|
PATTERN
|
@@ -74,18 +79,15 @@ module RuboCop
|
|
74
79
|
(send _ #add_dependency_method? <(hash <(pair (sym {:branch :ref :tag}) (str _)) ...>) ...>)
|
75
80
|
PATTERN
|
76
81
|
|
77
|
-
def
|
78
|
-
return
|
79
|
-
|
80
|
-
add_dependency_method_nodes.each do |node|
|
81
|
-
next if allowed_gem?(node)
|
82
|
+
def on_send(node)
|
83
|
+
return unless add_dependency_method_declaration?(node)
|
84
|
+
return if allowed_gem?(node)
|
82
85
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
86
|
+
if offense?(node)
|
87
|
+
add_offense(node)
|
88
|
+
opposite_style_detected
|
89
|
+
else
|
90
|
+
correct_style_detected
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
@@ -116,11 +118,7 @@ module RuboCop
|
|
116
118
|
end
|
117
119
|
|
118
120
|
def add_dependency_method?(method_name)
|
119
|
-
|
120
|
-
end
|
121
|
-
|
122
|
-
def add_dependency_method_nodes
|
123
|
-
add_dependency_method_declarations(processed_source.ast)
|
121
|
+
ADD_DEPENDENCY_METHODS.include?(method_name)
|
124
122
|
end
|
125
123
|
|
126
124
|
def offense?(node)
|
@@ -132,25 +132,19 @@ module RuboCop
|
|
132
132
|
# end
|
133
133
|
# end
|
134
134
|
#
|
135
|
-
# @see https://rubystyle.guide#consistent-classes
|
136
135
|
class ClassStructure < Base
|
137
136
|
include VisibilityHelp
|
138
137
|
extend AutoCorrector
|
139
138
|
|
140
139
|
HUMANIZED_NODE_TYPE = {
|
141
140
|
casgn: :constants,
|
142
|
-
defs: :
|
141
|
+
defs: :public_class_methods,
|
143
142
|
def: :public_methods,
|
144
143
|
sclass: :class_singleton
|
145
144
|
}.freeze
|
146
145
|
|
147
146
|
MSG = '`%<category>s` is supposed to appear before `%<previous>s`.'
|
148
147
|
|
149
|
-
# @!method dynamic_constant?(node)
|
150
|
-
def_node_matcher :dynamic_constant?, <<~PATTERN
|
151
|
-
(casgn nil? _ (send ...))
|
152
|
-
PATTERN
|
153
|
-
|
154
148
|
# Validates code style on class declaration.
|
155
149
|
# Add offense when find a node out of expected order.
|
156
150
|
def on_class(class_node)
|
@@ -222,7 +216,7 @@ module RuboCop
|
|
222
216
|
def walk_over_nested_class_definition(class_node)
|
223
217
|
class_elements(class_node).each do |node|
|
224
218
|
classification = classify(node)
|
225
|
-
next if ignore?(classification)
|
219
|
+
next if ignore?(node, classification)
|
226
220
|
|
227
221
|
yield node, classification
|
228
222
|
end
|
@@ -240,17 +234,20 @@ module RuboCop
|
|
240
234
|
end
|
241
235
|
end
|
242
236
|
|
243
|
-
def ignore?(classification)
|
237
|
+
def ignore?(node, classification)
|
244
238
|
classification.nil? ||
|
245
239
|
classification.to_s.end_with?('=') ||
|
246
|
-
expected_order.index(classification).nil?
|
240
|
+
expected_order.index(classification).nil? ||
|
241
|
+
private_constant?(node)
|
247
242
|
end
|
248
243
|
|
249
244
|
def ignore_for_autocorrect?(node, sibling)
|
250
245
|
classification = classify(node)
|
251
246
|
sibling_class = classify(sibling)
|
252
247
|
|
253
|
-
ignore?(sibling_class) ||
|
248
|
+
ignore?(sibling, sibling_class) ||
|
249
|
+
classification == sibling_class ||
|
250
|
+
dynamic_constant?(node)
|
254
251
|
end
|
255
252
|
|
256
253
|
def humanize_node(node)
|
@@ -262,6 +259,30 @@ module RuboCop
|
|
262
259
|
HUMANIZED_NODE_TYPE[node.type] || node.type
|
263
260
|
end
|
264
261
|
|
262
|
+
def dynamic_constant?(node)
|
263
|
+
return false unless node.casgn_type? && node.namespace.nil?
|
264
|
+
|
265
|
+
expression = node.expression
|
266
|
+
expression.send_type? &&
|
267
|
+
!(expression.method?(:freeze) && expression.receiver&.recursive_basic_literal?)
|
268
|
+
end
|
269
|
+
|
270
|
+
def private_constant?(node)
|
271
|
+
return false unless node.casgn_type? && node.namespace.nil?
|
272
|
+
return false unless (parent = node.parent)
|
273
|
+
|
274
|
+
parent.each_child_node(:send) do |child_node|
|
275
|
+
return true if marked_as_private_constant?(child_node, node.name)
|
276
|
+
end
|
277
|
+
false
|
278
|
+
end
|
279
|
+
|
280
|
+
def marked_as_private_constant?(node, name)
|
281
|
+
return false unless node.method?(:private_constant)
|
282
|
+
|
283
|
+
node.arguments.any? { |arg| (arg.sym_type? || arg.str_type?) && arg.value == name }
|
284
|
+
end
|
285
|
+
|
265
286
|
def source_range_with_comment(node)
|
266
287
|
begin_pos, end_pos =
|
267
288
|
if (node.def_type? && !node.method?(:initialize)) ||
|
@@ -154,7 +154,9 @@ module RuboCop
|
|
154
154
|
end
|
155
155
|
|
156
156
|
def less_indented?(line)
|
157
|
-
|
157
|
+
rule = config.for_cop('Layout/AccessModifierIndentation')['EnforcedStyle'] == 'outdent'
|
158
|
+
access_modifier = 'private|protected|public'
|
159
|
+
/\A\s*(end\b|[)}\]])/.match?(line) || (rule && /\A\s*(#{access_modifier})\b/.match?(line))
|
158
160
|
end
|
159
161
|
|
160
162
|
def two_alternatives?(line)
|
@@ -40,10 +40,13 @@ module RuboCop
|
|
40
40
|
MSG = '%<type>s detected in indentation.'
|
41
41
|
|
42
42
|
def on_new_investigation
|
43
|
-
str_ranges =
|
43
|
+
str_ranges = nil
|
44
44
|
|
45
45
|
processed_source.lines.each.with_index(1) do |line, lineno|
|
46
46
|
next unless (range = find_offense(line, lineno))
|
47
|
+
|
48
|
+
# Perform costly calculation only when needed.
|
49
|
+
str_ranges ||= string_literal_ranges(processed_source.ast)
|
47
50
|
next if in_string_literal?(str_ranges, range)
|
48
51
|
|
49
52
|
add_offense(range) { |corrector| autocorrect(corrector, range) }
|
@@ -31,15 +31,11 @@ module RuboCop
|
|
31
31
|
include RangeHelp
|
32
32
|
extend AutoCorrector
|
33
33
|
|
34
|
-
# rubocop:disable Metrics/AbcSize
|
35
34
|
def on_new_investigation
|
36
35
|
return unless processed_source.raw_source.include?('\\')
|
37
36
|
|
38
37
|
last_line = last_line(processed_source)
|
39
38
|
|
40
|
-
@ignored_ranges = string_literal_ranges(processed_source.ast) +
|
41
|
-
comment_ranges(processed_source.comments)
|
42
|
-
|
43
39
|
processed_source.raw_source.lines.each_with_index do |line, index|
|
44
40
|
break if index >= last_line
|
45
41
|
|
@@ -47,7 +43,6 @@ module RuboCop
|
|
47
43
|
investigate(line, line_number)
|
48
44
|
end
|
49
45
|
end
|
50
|
-
# rubocop:enable Metrics/AbcSize
|
51
46
|
|
52
47
|
private
|
53
48
|
|
@@ -120,7 +115,12 @@ module RuboCop
|
|
120
115
|
end
|
121
116
|
|
122
117
|
def ignore_range?(backtick_range)
|
123
|
-
|
118
|
+
ignored_ranges.any? { |range| range.contains?(backtick_range) }
|
119
|
+
end
|
120
|
+
|
121
|
+
def ignored_ranges
|
122
|
+
@ignored_ranges ||= string_literal_ranges(processed_source.ast) +
|
123
|
+
comment_ranges(processed_source.comments)
|
124
124
|
end
|
125
125
|
|
126
126
|
def no_space_style?
|