rubocop 1.69.1 → 1.70.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 +19 -2
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/config.rb +13 -4
- data/lib/rubocop/config_loader.rb +4 -0
- data/lib/rubocop/config_loader_resolver.rb +14 -3
- data/lib/rubocop/config_validator.rb +18 -8
- data/lib/rubocop/cop/autocorrect_logic.rb +31 -34
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -7
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -6
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -0
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +24 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +152 -0
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +11 -3
- data/lib/rubocop/cop/lint/nested_method_definition.rb +5 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +6 -14
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +65 -0
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -4
- data/lib/rubocop/cop/lint/void.rb +3 -2
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/method_length.rb +8 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +7 -7
- data/lib/rubocop/cop/mixin/comments_help.rb +6 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/line_length_help.rb +5 -4
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +46 -22
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +1 -1
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +32 -1
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +1 -4
- data/lib/rubocop/cop/style/block_delimiters.rb +8 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +5 -2
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +3 -6
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +1 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +1 -1
- data/lib/rubocop/cop/style/file_null.rb +20 -4
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/hash_except.rb +54 -67
- data/lib/rubocop/cop/style/hash_syntax.rb +5 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +6 -4
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +11 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
- data/lib/rubocop/cop/style/object_then.rb +13 -15
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +5 -3
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +2 -1
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +12 -9
- data/lib/rubocop/cop/style/redundant_parentheses.rb +1 -4
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +6 -5
- data/lib/rubocop/cop/style/safe_navigation.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +2 -3
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/super_arguments.rb +63 -15
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -0
- data/lib/rubocop/cop/util.rb +9 -2
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +15 -49
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/magic_comment.rb +3 -3
- data/lib/rubocop/path_util.rb +11 -8
- data/lib/rubocop/rspec/shared_contexts.rb +4 -1
- data/lib/rubocop/runner.rb +5 -6
- data/lib/rubocop/target_ruby.rb +15 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +3 -0
- data/lib/ruby_lsp/rubocop/addon.rb +78 -0
- data/lib/ruby_lsp/rubocop/wraps_built_in_lsp_runtime.rb +50 -0
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55382302106a1f2c44166213aaa0c23bfccc3c0ebac5b1af95fa9073ddf59aa0
|
4
|
+
data.tar.gz: bb1a6e491c7750b3f4aff90fbe2590f289d5f85ca9bbc2d71e01bd35d420b38c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6cff98184e513e6a57e5a82234f57a8130ef2e242eb3df675b677cfe5be8920d3cb732ce1f615385641731c328253fb65829922d371621d5e5148601f309ee51
|
7
|
+
data.tar.gz: 3c3d8e5fc22db6f9b1a1ca6f9e31a8a29467c4df358e12da099fcc528884832d00bc18842d846ee76300791c1cb76122a22b6eb079b5a713c6f7b827fbea71dc
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -52,7 +52,7 @@ To prevent an unwanted RuboCop update you might want to use a conservative versi
|
|
52
52
|
in your `Gemfile`:
|
53
53
|
|
54
54
|
```rb
|
55
|
-
gem 'rubocop', '~> 1.
|
55
|
+
gem 'rubocop', '~> 1.70', require: false
|
56
56
|
```
|
57
57
|
|
58
58
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -247,5 +247,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
247
247
|
|
248
248
|
## Copyright
|
249
249
|
|
250
|
-
Copyright (c) 2012-
|
250
|
+
Copyright (c) 2012-2025 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
251
251
|
further details.
|
data/config/default.yml
CHANGED
@@ -1665,6 +1665,11 @@ Lint/ConstantOverwrittenInRescue:
|
|
1665
1665
|
Enabled: pending
|
1666
1666
|
VersionAdded: '1.31'
|
1667
1667
|
|
1668
|
+
Lint/ConstantReassignment:
|
1669
|
+
Description: 'Checks for constant reassignments.'
|
1670
|
+
Enabled: pending
|
1671
|
+
VersionAdded: '1.70'
|
1672
|
+
|
1668
1673
|
Lint/ConstantResolution:
|
1669
1674
|
Description: 'Check that constants are fully qualified with `::`.'
|
1670
1675
|
Enabled: false
|
@@ -2402,6 +2407,12 @@ Lint/ShadowingOuterLocalVariable:
|
|
2402
2407
|
Enabled: true
|
2403
2408
|
VersionAdded: '0.9'
|
2404
2409
|
|
2410
|
+
Lint/SharedMutableDefault:
|
2411
|
+
Description: 'Checks for mutable literals used as default arguments during Hash initialization.'
|
2412
|
+
StyleGuide: '#no-mutable-defaults'
|
2413
|
+
Enabled: pending
|
2414
|
+
VersionAdded: '1.70'
|
2415
|
+
|
2405
2416
|
Lint/StructNewOverride:
|
2406
2417
|
Description: 'Disallow overriding the `Struct` built-in methods via `Struct.new`.'
|
2407
2418
|
Enabled: true
|
@@ -3136,13 +3147,14 @@ Style/AccessModifierDeclarations:
|
|
3136
3147
|
Description: 'Checks style of how access modifiers are used.'
|
3137
3148
|
Enabled: true
|
3138
3149
|
VersionAdded: '0.57'
|
3139
|
-
VersionChanged: '
|
3150
|
+
VersionChanged: '1.70'
|
3140
3151
|
EnforcedStyle: group
|
3141
3152
|
SupportedStyles:
|
3142
3153
|
- inline
|
3143
3154
|
- group
|
3144
3155
|
AllowModifiersOnSymbols: true
|
3145
3156
|
AllowModifiersOnAttrs: true
|
3157
|
+
AllowModifiersOnAliasMethod: true
|
3146
3158
|
SafeAutoCorrect: false
|
3147
3159
|
|
3148
3160
|
Style/AccessorGrouping:
|
@@ -4316,6 +4328,11 @@ Style/IpAddresses:
|
|
4316
4328
|
- '**/gems.rb'
|
4317
4329
|
- '**/*.gemspec'
|
4318
4330
|
|
4331
|
+
Style/ItAssignment:
|
4332
|
+
Description: 'Checks for assignment to `it` inside a block.'
|
4333
|
+
Enabled: pending
|
4334
|
+
VersionAdded: '1.70'
|
4335
|
+
|
4319
4336
|
Style/KeywordArgumentsMerging:
|
4320
4337
|
Description: >-
|
4321
4338
|
When passing an existing hash as keyword arguments, provide additional arguments
|
@@ -5059,7 +5076,7 @@ Style/RedundantConstantBase:
|
|
5059
5076
|
VersionAdded: '1.40'
|
5060
5077
|
|
5061
5078
|
Style/RedundantCurrentDirectoryInPath:
|
5062
|
-
Description: 'Checks for
|
5079
|
+
Description: 'Checks for a redundant current directory in a path given to `require_relative`.'
|
5063
5080
|
Enabled: pending
|
5064
5081
|
VersionAdded: '1.53'
|
5065
5082
|
|
@@ -71,11 +71,11 @@ module RuboCop
|
|
71
71
|
|
72
72
|
warn Rainbow("\n#{pluralize(errors.size, 'error')} occurred:").red
|
73
73
|
|
74
|
-
errors.each { |error| warn error }
|
74
|
+
errors.each { |error| warn Rainbow(error).red }
|
75
75
|
|
76
|
-
warn <<~WARNING
|
76
|
+
warn Rainbow(<<~WARNING.strip).yellow
|
77
77
|
Errors are usually caused by RuboCop bugs.
|
78
|
-
Please,
|
78
|
+
Please, update to the latest RuboCop version if not already in use, and report a bug if the issue still occurs on this version.
|
79
79
|
#{bug_tracker_uri}
|
80
80
|
Mention the following information in the issue report:
|
81
81
|
#{RuboCop::Version.verbose}
|
data/lib/rubocop/config.rb
CHANGED
@@ -16,6 +16,7 @@ module RuboCop
|
|
16
16
|
|
17
17
|
CopConfig = Struct.new(:name, :metadata)
|
18
18
|
|
19
|
+
EMPTY_CONFIG = {}.freeze
|
19
20
|
DEFAULT_RAILS_VERSION = 5.0
|
20
21
|
attr_reader :loaded_path
|
21
22
|
|
@@ -80,10 +81,7 @@ module RuboCop
|
|
80
81
|
|
81
82
|
def make_excludes_absolute
|
82
83
|
each_key do |key|
|
83
|
-
|
84
|
-
next unless self[key]['Exclude']
|
85
|
-
|
86
|
-
self[key]['Exclude'].map! do |exclude_elem|
|
84
|
+
dig(key, 'Exclude')&.map! do |exclude_elem|
|
87
85
|
if exclude_elem.is_a?(String) && !absolute?(exclude_elem)
|
88
86
|
File.expand_path(File.join(base_dir_for_path_parameters, exclude_elem))
|
89
87
|
else
|
@@ -123,6 +121,13 @@ module RuboCop
|
|
123
121
|
@for_cop[cop]
|
124
122
|
end
|
125
123
|
|
124
|
+
# @return [Config, Hash] for the given cop / cop name.
|
125
|
+
# If the given cop is enabled, returns its configuration hash.
|
126
|
+
# Otherwise, returns an empty hash.
|
127
|
+
def for_enabled_cop(cop)
|
128
|
+
cop_enabled?(cop) ? for_cop(cop) : EMPTY_CONFIG
|
129
|
+
end
|
130
|
+
|
126
131
|
# @return [Config] for the given cop merged with that of its department (if any)
|
127
132
|
# Note: the 'Enabled' attribute is same as that returned by `for_cop`
|
128
133
|
def for_badge(badge)
|
@@ -159,6 +164,10 @@ module RuboCop
|
|
159
164
|
@for_all_cops ||= self['AllCops'] || {}
|
160
165
|
end
|
161
166
|
|
167
|
+
def cop_enabled?(name)
|
168
|
+
!!for_cop(name)['Enabled']
|
169
|
+
end
|
170
|
+
|
162
171
|
def disabled_new_cops?
|
163
172
|
for_all_cops['NewCops'] == 'disable'
|
164
173
|
end
|
@@ -163,14 +163,21 @@ module RuboCop
|
|
163
163
|
end
|
164
164
|
|
165
165
|
def warn_on_duplicate_setting(base_hash, derived_hash, key, **opts)
|
166
|
+
# If the file being considered is remote, don't bother checking for duplicates
|
167
|
+
return if remote_config?(opts[:file])
|
168
|
+
|
166
169
|
return unless duplicate_setting?(base_hash, derived_hash, key, opts[:inherited_file])
|
167
170
|
|
168
171
|
inherit_mode = opts[:inherit_mode]['merge'] || opts[:inherit_mode]['override']
|
169
172
|
return if base_hash[key].is_a?(Array) && inherit_mode&.include?(key)
|
170
173
|
|
171
|
-
puts
|
172
|
-
|
173
|
-
|
174
|
+
puts duplicate_setting_warning(opts, key)
|
175
|
+
end
|
176
|
+
|
177
|
+
def duplicate_setting_warning(opts, key)
|
178
|
+
"#{PathUtil.smart_path(opts[:file])}: " \
|
179
|
+
"#{opts[:cop_name]}:#{key} overrides " \
|
180
|
+
"the same parameter in #{opts[:inherited_file]}"
|
174
181
|
end
|
175
182
|
|
176
183
|
def determine_inherit_mode(hash, key)
|
@@ -242,6 +249,10 @@ module RuboCop
|
|
242
249
|
uri.start_with?('http://', 'https://')
|
243
250
|
end
|
244
251
|
|
252
|
+
def remote_config?(file)
|
253
|
+
file.is_a?(RemoteConfig)
|
254
|
+
end
|
255
|
+
|
245
256
|
def handle_disabled_by_default(config, new_default_configuration)
|
246
257
|
department_config = config.to_hash.reject { |cop| cop.include?('/') }
|
247
258
|
department_config.each do |dept, dept_params|
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
# Handles validation of configuration, for example cop names, parameter
|
5
5
|
# names, and Ruby versions.
|
6
|
+
# rubocop:disable Metrics/ClassLength
|
6
7
|
class ConfigValidator
|
7
8
|
extend SimpleForwardable
|
8
9
|
|
@@ -41,8 +42,9 @@ module RuboCop
|
|
41
42
|
ConfigLoader.default_configuration.key?(key)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
+
validate_parameter_shape(valid_cop_names)
|
45
46
|
|
47
|
+
check_obsoletions
|
46
48
|
alert_about_unrecognized_cops(invalid_cop_names)
|
47
49
|
validate_new_cops_parameter
|
48
50
|
validate_parameter_names(valid_cop_names)
|
@@ -64,12 +66,6 @@ module RuboCop
|
|
64
66
|
target_ruby.version
|
65
67
|
end
|
66
68
|
|
67
|
-
def validate_section_presence(name)
|
68
|
-
return unless @config.key?(name) && @config[name].nil?
|
69
|
-
|
70
|
-
raise ValidationError, "empty section #{name} found in #{smart_loaded_path}"
|
71
|
-
end
|
72
|
-
|
73
69
|
private
|
74
70
|
|
75
71
|
attr_reader :target_ruby
|
@@ -177,9 +173,22 @@ module RuboCop
|
|
177
173
|
raise ValidationError, message
|
178
174
|
end
|
179
175
|
|
176
|
+
def validate_parameter_shape(valid_cop_names)
|
177
|
+
valid_cop_names.each do |name|
|
178
|
+
if @config[name].nil?
|
179
|
+
raise ValidationError, "empty section #{name.inspect} found in #{smart_loaded_path}"
|
180
|
+
elsif !@config[name].is_a?(Hash)
|
181
|
+
raise ValidationError, <<~MESSAGE
|
182
|
+
The configuration for #{name.inspect} in #{smart_loaded_path} is not a Hash.
|
183
|
+
|
184
|
+
Found: #{@config[name].inspect}
|
185
|
+
MESSAGE
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
180
190
|
def validate_parameter_names(valid_cop_names)
|
181
191
|
valid_cop_names.each do |name|
|
182
|
-
validate_section_presence(name)
|
183
192
|
each_invalid_parameter(name) do |param, supported_params|
|
184
193
|
warn Rainbow(<<~MESSAGE).yellow
|
185
194
|
Warning: #{name} does not support #{param} parameter.
|
@@ -277,4 +286,5 @@ module RuboCop
|
|
277
286
|
"is supposed to be #{supposed_values} and #{Rainbow(value).yellow} is not."
|
278
287
|
end
|
279
288
|
end
|
289
|
+
# rubocop:enable Metrics/ClassLength
|
280
290
|
end
|
@@ -49,17 +49,31 @@ module RuboCop
|
|
49
49
|
private
|
50
50
|
|
51
51
|
def disable_offense(offense_range)
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
unbreakable_range = multiline_ranges(offense_range)&.find do |range|
|
53
|
+
range_overlaps_offense?(offense_range, range)
|
54
|
+
end
|
55
55
|
|
56
|
-
if
|
57
|
-
disable_offense_before_and_after(range_by_lines(
|
56
|
+
if unbreakable_range
|
57
|
+
disable_offense_before_and_after(range_by_lines(unbreakable_range))
|
58
58
|
else
|
59
59
|
disable_offense_with_eol_or_surround_comment(offense_range)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def multiline_ranges(offense_range)
|
64
|
+
return if offense_range.empty?
|
65
|
+
|
66
|
+
processed_source.ast.each_node.filter_map do |node|
|
67
|
+
if surrounding_heredoc?(node)
|
68
|
+
heredoc_range(node)
|
69
|
+
elsif string_continuation?(node)
|
70
|
+
range_by_lines(node.source_range)
|
71
|
+
elsif surrounding_percent_array?(node) || multiline_string?(node)
|
72
|
+
node.source_range
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
63
77
|
def disable_offense_with_eol_or_surround_comment(range)
|
64
78
|
eol_comment = " # rubocop:todo #{cop_name}"
|
65
79
|
needed_line_length = (range.source_line + eol_comment).length
|
@@ -71,47 +85,30 @@ module RuboCop
|
|
71
85
|
end
|
72
86
|
end
|
73
87
|
|
74
|
-
def
|
75
|
-
|
76
|
-
return nil if offense_range.empty?
|
77
|
-
|
78
|
-
heredoc_nodes = processed_source.ast.each_descendant.select do |node|
|
79
|
-
node.respond_to?(:heredoc?) && node.heredoc?
|
80
|
-
end
|
81
|
-
heredoc_nodes.map { |node| node.source_range.join(node.loc.heredoc_end) }
|
82
|
-
.find { |range| range.contains?(offense_range) }
|
88
|
+
def range_overlaps_offense?(offense_range, range)
|
89
|
+
offense_range.begin_pos > range.begin_pos && range.overlaps?(offense_range)
|
83
90
|
end
|
84
91
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
percent_array = processed_source.ast.each_descendant.select do |node|
|
89
|
-
node.array_type? && node.percent_literal?
|
90
|
-
end
|
91
|
-
|
92
|
-
percent_array.map(&:source_range).find do |range|
|
93
|
-
range_overlaps_offense?(offense_range, range)
|
94
|
-
end
|
92
|
+
def surrounding_heredoc?(node)
|
93
|
+
node.type?(:str, :dstr, :xstr) && node.heredoc?
|
95
94
|
end
|
96
95
|
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
string_continuation_nodes = processed_source.ast.each_descendant.filter_map do |node|
|
101
|
-
range_by_lines(node.source_range) if string_continuation?(node)
|
102
|
-
end
|
103
|
-
|
104
|
-
string_continuation_nodes.find { |range| range_overlaps_offense?(offense_range, range) }
|
96
|
+
def heredoc_range(node)
|
97
|
+
node.source_range.join(node.loc.heredoc_end)
|
105
98
|
end
|
106
99
|
|
107
|
-
def
|
108
|
-
|
100
|
+
def surrounding_percent_array?(node)
|
101
|
+
node.array_type? && node.percent_literal?
|
109
102
|
end
|
110
103
|
|
111
104
|
def string_continuation?(node)
|
112
105
|
(node.str_type? || node.dstr_type? || node.xstr_type?) && node.source.match?(/\\\s*$/)
|
113
106
|
end
|
114
107
|
|
108
|
+
def multiline_string?(node)
|
109
|
+
node.dstr_type? && node.multiline?
|
110
|
+
end
|
111
|
+
|
115
112
|
def range_of_first_line(range)
|
116
113
|
begin_of_first_line = range.begin_pos - range.column
|
117
114
|
end_of_first_line = begin_of_first_line + range.source_line.length
|
data/lib/rubocop/cop/base.rb
CHANGED
@@ -261,6 +261,12 @@ module RuboCop
|
|
261
261
|
@config.target_ruby_version
|
262
262
|
end
|
263
263
|
|
264
|
+
# Returns a gems locked versions (i.e. from Gemfile.lock or gems.locked)
|
265
|
+
# @returns [Gem::Version | nil] The locked gem version, or nil if the gem is not present.
|
266
|
+
def target_gem_version(gem_name)
|
267
|
+
@config.gem_versions_in_target && @config.gem_versions_in_target[gem_name]
|
268
|
+
end
|
269
|
+
|
264
270
|
def parser_engine
|
265
271
|
@config.parser_engine
|
266
272
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module InternalAffairs
|
6
|
+
# Use `config.cop_enabled?('Department/CopName')` instead of
|
7
|
+
# traversing the config hash.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# # `for_cop(...)['Enabled']
|
11
|
+
#
|
12
|
+
# # bad
|
13
|
+
# config.for_cop('Department/CopName')['Enabled']
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# config.cop_enabled?('Department/CopName')
|
17
|
+
#
|
18
|
+
# @example
|
19
|
+
# # when keeping a cop's config in a local and then checking the `Enabled` key
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# cop_config = config.for_cop('Department/CopName')
|
23
|
+
# cop_config['Enabled'] && cop_config['Foo']
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# config.for_enabled_cop('Department/CopName')['Foo']
|
27
|
+
#
|
28
|
+
class CopEnabled < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'Use `%<replacement>s` instead of `%<source>s`.'
|
32
|
+
MSG_HASH = 'Consider replacing uses of `%<hash_name>s` with `config.for_enabled_cop`.'
|
33
|
+
|
34
|
+
RESTRICT_ON_SEND = [:[]].freeze
|
35
|
+
|
36
|
+
# @!method for_cop_enabled?(node)
|
37
|
+
def_node_matcher :for_cop_enabled?, <<~PATTERN
|
38
|
+
(send
|
39
|
+
(send
|
40
|
+
${(send nil? :config) (ivar :@config)} :for_cop
|
41
|
+
$(str _)) :[]
|
42
|
+
(str "Enabled"))
|
43
|
+
PATTERN
|
44
|
+
|
45
|
+
# @!method config_enabled_lookup?(node)
|
46
|
+
def_node_matcher :config_enabled_lookup?, <<~PATTERN
|
47
|
+
(send
|
48
|
+
{(lvar $_) (ivar $_) (send nil? $_)} :[]
|
49
|
+
(str "Enabled"))
|
50
|
+
PATTERN
|
51
|
+
|
52
|
+
def on_send(node)
|
53
|
+
if (config_var, cop_name = for_cop_enabled?(node))
|
54
|
+
handle_for_cop(node, config_var, cop_name)
|
55
|
+
elsif (config_var = config_enabled_lookup?(node))
|
56
|
+
return unless config_var.end_with?('_config')
|
57
|
+
|
58
|
+
handle_hash(node, config_var)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def handle_for_cop(node, config_var, cop_name)
|
65
|
+
source = node.source
|
66
|
+
quote = cop_name.loc.begin.source
|
67
|
+
cop_name = cop_name.value
|
68
|
+
|
69
|
+
replacement = "#{config_var.source}.cop_enabled?(#{quote}#{cop_name}#{quote})"
|
70
|
+
message = format(MSG, source: source, replacement: replacement)
|
71
|
+
|
72
|
+
add_offense(node, message: message) do |corrector|
|
73
|
+
corrector.replace(node, replacement)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_hash(node, config_var)
|
78
|
+
message = format(MSG_HASH, hash_name: config_var)
|
79
|
+
|
80
|
+
add_offense(node, message: message)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -21,16 +21,17 @@ module RuboCop
|
|
21
21
|
|
22
22
|
# @!method node_type_check(node)
|
23
23
|
def_node_matcher :node_type_check, <<~PATTERN
|
24
|
-
(send (
|
24
|
+
(send (call _ :type) :== (sym $_))
|
25
25
|
PATTERN
|
26
26
|
|
27
27
|
def on_send(node)
|
28
|
-
node_type_check(node) do |
|
28
|
+
node_type_check(node) do |node_type|
|
29
29
|
return unless Parser::Meta::NODE_TYPES.include?(node_type)
|
30
30
|
|
31
31
|
message = format(MSG, type: node_type)
|
32
32
|
add_offense(node, message: message) do |corrector|
|
33
|
-
range = node.
|
33
|
+
range = node.receiver.loc.selector.join(node.source_range.end)
|
34
|
+
|
34
35
|
corrector.replace(range, "#{node_type}_type?")
|
35
36
|
end
|
36
37
|
end
|
@@ -17,6 +17,7 @@ module RuboCop
|
|
17
17
|
extend AutoCorrector
|
18
18
|
|
19
19
|
MSG = 'Use `%<prefer>s`.'
|
20
|
+
PREFERRED_METHOD = 'operator_keyword?'
|
20
21
|
|
21
22
|
# @!method and_or_type(node)
|
22
23
|
def_node_matcher :and_or_type, <<~PATTERN
|
@@ -33,8 +34,9 @@ module RuboCop
|
|
33
34
|
def on_or(node)
|
34
35
|
return unless (lhs, rhs = and_or_type(node))
|
35
36
|
|
36
|
-
|
37
|
-
|
37
|
+
begin_range = lhs.receiver&.source_range || lhs.loc.selector
|
38
|
+
offense = begin_range.join(rhs.source_range.end)
|
39
|
+
prefer = lhs.receiver ? "#{lhs.receiver.source}.#{PREFERRED_METHOD}" : PREFERRED_METHOD
|
38
40
|
|
39
41
|
add_offense(offense, message: format(MSG, prefer: prefer)) do |corrector|
|
40
42
|
corrector.replace(offense, prefer)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative 'internal_affairs/cop_description'
|
4
|
+
require_relative 'internal_affairs/cop_enabled'
|
4
5
|
require_relative 'internal_affairs/create_empty_file'
|
5
6
|
require_relative 'internal_affairs/empty_line_between_expect_offense_and_correction'
|
6
7
|
require_relative 'internal_affairs/example_description'
|
@@ -141,16 +141,10 @@ module RuboCop
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def enforce_hash_argument_with_separator?
|
144
|
-
return false unless hash_argument_config['Enabled']
|
145
|
-
|
146
144
|
RuboCop::Cop::Layout::HashAlignment::SEPARATOR_ALIGNMENT_STYLES.any? do |style|
|
147
|
-
|
145
|
+
config.for_enabled_cop('Layout/HashAlignment')[style]&.include?('separator')
|
148
146
|
end
|
149
147
|
end
|
150
|
-
|
151
|
-
def hash_argument_config
|
152
|
-
config.for_cop('Layout/HashAlignment')
|
153
|
-
end
|
154
148
|
end
|
155
149
|
end
|
156
150
|
end
|
@@ -8,19 +8,18 @@ module RuboCop
|
|
8
8
|
#
|
9
9
|
# @example
|
10
10
|
#
|
11
|
-
# #
|
12
|
-
#
|
11
|
+
# # bad
|
13
12
|
# begin
|
13
|
+
#
|
14
14
|
# # ...
|
15
|
-
# end
|
16
15
|
#
|
17
|
-
#
|
16
|
+
# end
|
18
17
|
#
|
18
|
+
# # good
|
19
19
|
# begin
|
20
|
-
#
|
21
20
|
# # ...
|
22
|
-
#
|
23
21
|
# end
|
22
|
+
#
|
24
23
|
class EmptyLinesAroundBeginBody < Base
|
25
24
|
include EmptyLinesAroundBody
|
26
25
|
extend AutoCorrector
|
@@ -70,7 +70,7 @@ module RuboCop
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def check_assignment(token)
|
73
|
-
return unless
|
73
|
+
return unless aligned_with_preceding_equals_operator(token) == :no
|
74
74
|
|
75
75
|
message = format(MSG_UNALIGNED_ASGN, location: 'preceding')
|
76
76
|
add_offense(token.pos, message: message) do |corrector|
|
@@ -269,17 +269,12 @@ module RuboCop
|
|
269
269
|
end
|
270
270
|
|
271
271
|
def enforce_first_argument_with_fixed_indentation?
|
272
|
-
|
273
|
-
|
272
|
+
argument_alignment_config = config.for_enabled_cop('Layout/ArgumentAlignment')
|
274
273
|
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
275
274
|
end
|
276
275
|
|
277
276
|
def enable_layout_first_method_argument_line_break?
|
278
|
-
config.
|
279
|
-
end
|
280
|
-
|
281
|
-
def argument_alignment_config
|
282
|
-
config.for_cop('Layout/ArgumentAlignment')
|
277
|
+
config.cop_enabled?('Layout/FirstMethodArgumentLineBreak')
|
283
278
|
end
|
284
279
|
end
|
285
280
|
end
|
@@ -180,13 +180,8 @@ module RuboCop
|
|
180
180
|
end
|
181
181
|
|
182
182
|
def enforce_first_argument_with_fixed_indentation?
|
183
|
-
|
184
|
-
|
185
|
-
array_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
186
|
-
end
|
187
|
-
|
188
|
-
def array_alignment_config
|
189
|
-
config.for_cop('Layout/ArrayAlignment')
|
183
|
+
argument_alignment_config = config.for_enabled_cop('Layout/ArrayAlignment')
|
184
|
+
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
190
185
|
end
|
191
186
|
end
|
192
187
|
end
|
@@ -225,14 +225,9 @@ module RuboCop
|
|
225
225
|
end
|
226
226
|
|
227
227
|
def enforce_first_argument_with_fixed_indentation?
|
228
|
-
|
229
|
-
|
228
|
+
argument_alignment_config = config.for_enabled_cop('Layout/ArgumentAlignment')
|
230
229
|
argument_alignment_config['EnforcedStyle'] == 'with_fixed_indentation'
|
231
230
|
end
|
232
|
-
|
233
|
-
def argument_alignment_config
|
234
|
-
config.for_cop('Layout/ArgumentAlignment')
|
235
|
-
end
|
236
231
|
end
|
237
232
|
end
|
238
233
|
end
|