rubocop 1.41.1 → 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 +25 -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 -10
- 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/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/registry.rb +22 -22
- data/lib/rubocop/cop/security/compound_hash.rb +2 -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/guard_clause.rb +11 -7
- 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 +4 -2
- 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/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
@@ -3901,7 +3901,7 @@ Style/HashSyntax:
|
|
3901
3901
|
- never
|
3902
3902
|
# accepts both shorthand and explicit use of hash literal value.
|
3903
3903
|
- either
|
3904
|
-
#
|
3904
|
+
# forces use of the 3.1 syntax only if all values can be omitted in the hash.
|
3905
3905
|
- consistent
|
3906
3906
|
# Force hashes that have a symbol value to use hash rockets
|
3907
3907
|
UseHashRocketsWithSymbolValues: false
|
@@ -4110,6 +4110,12 @@ Style/MapToHash:
|
|
4110
4110
|
VersionAdded: '1.24'
|
4111
4111
|
Safe: false
|
4112
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
|
+
|
4113
4119
|
Style/MethodCallWithArgsParentheses:
|
4114
4120
|
Description: 'Use parentheses for method calls with arguments.'
|
4115
4121
|
StyleGuide: '#method-invocation-parens'
|
@@ -4168,6 +4174,12 @@ Style/MinMax:
|
|
4168
4174
|
Enabled: true
|
4169
4175
|
VersionAdded: '0.50'
|
4170
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
|
+
|
4171
4183
|
Style/MissingElse:
|
4172
4184
|
Description: >-
|
4173
4185
|
Require if/case expressions to have an else branches.
|
@@ -5426,6 +5438,18 @@ Style/YodaCondition:
|
|
5426
5438
|
VersionAdded: '0.49'
|
5427
5439
|
VersionChanged: '0.75'
|
5428
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
|
+
|
5429
5453
|
Style/ZeroLengthPredicate:
|
5430
5454
|
Description: 'Use #empty? when testing for objects of length 0.'
|
5431
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)
|
@@ -138,18 +138,13 @@ module RuboCop
|
|
138
138
|
|
139
139
|
HUMANIZED_NODE_TYPE = {
|
140
140
|
casgn: :constants,
|
141
|
-
defs: :
|
141
|
+
defs: :public_class_methods,
|
142
142
|
def: :public_methods,
|
143
143
|
sclass: :class_singleton
|
144
144
|
}.freeze
|
145
145
|
|
146
146
|
MSG = '`%<category>s` is supposed to appear before `%<previous>s`.'
|
147
147
|
|
148
|
-
# @!method dynamic_constant?(node)
|
149
|
-
def_node_matcher :dynamic_constant?, <<~PATTERN
|
150
|
-
(casgn nil? _ (send ...))
|
151
|
-
PATTERN
|
152
|
-
|
153
148
|
# Validates code style on class declaration.
|
154
149
|
# Add offense when find a node out of expected order.
|
155
150
|
def on_class(class_node)
|
@@ -221,7 +216,7 @@ module RuboCop
|
|
221
216
|
def walk_over_nested_class_definition(class_node)
|
222
217
|
class_elements(class_node).each do |node|
|
223
218
|
classification = classify(node)
|
224
|
-
next if ignore?(classification)
|
219
|
+
next if ignore?(node, classification)
|
225
220
|
|
226
221
|
yield node, classification
|
227
222
|
end
|
@@ -239,17 +234,20 @@ module RuboCop
|
|
239
234
|
end
|
240
235
|
end
|
241
236
|
|
242
|
-
def ignore?(classification)
|
237
|
+
def ignore?(node, classification)
|
243
238
|
classification.nil? ||
|
244
239
|
classification.to_s.end_with?('=') ||
|
245
|
-
expected_order.index(classification).nil?
|
240
|
+
expected_order.index(classification).nil? ||
|
241
|
+
private_constant?(node)
|
246
242
|
end
|
247
243
|
|
248
244
|
def ignore_for_autocorrect?(node, sibling)
|
249
245
|
classification = classify(node)
|
250
246
|
sibling_class = classify(sibling)
|
251
247
|
|
252
|
-
ignore?(sibling_class) ||
|
248
|
+
ignore?(sibling, sibling_class) ||
|
249
|
+
classification == sibling_class ||
|
250
|
+
dynamic_constant?(node)
|
253
251
|
end
|
254
252
|
|
255
253
|
def humanize_node(node)
|
@@ -261,6 +259,30 @@ module RuboCop
|
|
261
259
|
HUMANIZED_NODE_TYPE[node.type] || node.type
|
262
260
|
end
|
263
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
|
+
|
264
286
|
def source_range_with_comment(node)
|
265
287
|
begin_pos, end_pos =
|
266
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?
|
@@ -256,7 +256,7 @@ module RuboCop
|
|
256
256
|
# regular dotted method calls bind more tightly than operators
|
257
257
|
# so we need to climb up the AST past them
|
258
258
|
node.each_ancestor do |ancestor|
|
259
|
-
return true if ancestor.and_type? || ancestor.or_type?
|
259
|
+
return true if ancestor.and_type? || ancestor.or_type? || ancestor.range_type?
|
260
260
|
return false unless ancestor.send_type?
|
261
261
|
return true if ancestor.operator_method?
|
262
262
|
end
|