rubocop 1.24.1 → 1.25.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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +14 -11
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +10 -3
- data/lib/rubocop/cop/generator.rb +4 -3
- data/lib/rubocop/cop/layout/argument_alignment.rb +36 -9
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +5 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +6 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_regexp_literal.rb +5 -1
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +6 -5
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +32 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +27 -13
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/style/collection_compact.rb +3 -3
- data/lib/rubocop/cop/style/hash_syntax.rb +14 -0
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +12 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -6
- data/lib/rubocop/cop/style/sample.rb +5 -3
- data/lib/rubocop/cop/style/swap_values.rb +2 -0
- data/lib/rubocop/cop/style/ternary_parentheses.rb +16 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -2
- data/lib/rubocop/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54b88752efa8bb84dc034391460b9071f31179dcb279550a209d31829e7b8c93
|
4
|
+
data.tar.gz: 31115cff5fdbf562dee62cf7e07033205d150b61ac5fd11476708f21e67000cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acdaf069659a775853b20e05734e85cd65c0c8734b09e568d4360dc9a7440a49ec8e47928b0da78866e1326a588638d18f2564e6e94023bb17b2f39493555027
|
7
|
+
data.tar.gz: 2765d9c9c10966c485be6cd70190b69a25aa99800c8d483bd67c1fdfe3dc5d13bb97cb1ca7f9f663776869acda5a426bc797f3b40adda17e0241ff8b62a374f1
|
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.25', require: false
|
57
57
|
```
|
58
58
|
|
59
59
|
See [our versioning policy](https://docs.rubocop.org/rubocop/versioning.html) for further details.
|
@@ -244,5 +244,5 @@ RuboCop's changelog is available [here](CHANGELOG.md).
|
|
244
244
|
|
245
245
|
## Copyright
|
246
246
|
|
247
|
-
Copyright (c) 2012-
|
247
|
+
Copyright (c) 2012-2022 Bozhidar Batsov. See [LICENSE.txt](LICENSE.txt) for
|
248
248
|
further details.
|
data/config/default.yml
CHANGED
@@ -430,13 +430,13 @@ Layout/ClassStructure:
|
|
430
430
|
- prepend
|
431
431
|
- extend
|
432
432
|
ExpectedOrder:
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
433
|
+
- module_inclusion
|
434
|
+
- constants
|
435
|
+
- public_class_methods
|
436
|
+
- initializer
|
437
|
+
- public_methods
|
438
|
+
- protected_methods
|
439
|
+
- private_methods
|
440
440
|
|
441
441
|
Layout/ClosingHeredocIndentation:
|
442
442
|
Description: 'Checks the indentation of here document closings.'
|
@@ -1900,7 +1900,7 @@ Lint/NestedPercentLiteral:
|
|
1900
1900
|
VersionAdded: '0.52'
|
1901
1901
|
|
1902
1902
|
Lint/NextWithoutAccumulator:
|
1903
|
-
Description:
|
1903
|
+
Description: >-
|
1904
1904
|
Do not omit the accumulator when calling `next`
|
1905
1905
|
in a `reduce`/`inject` block.
|
1906
1906
|
Enabled: true
|
@@ -2496,6 +2496,7 @@ Naming/BlockForwarding:
|
|
2496
2496
|
SupportedStyles:
|
2497
2497
|
- anonymous
|
2498
2498
|
- explicit
|
2499
|
+
BlockForwardingName: block
|
2499
2500
|
|
2500
2501
|
Naming/BlockParameterName:
|
2501
2502
|
Description: >-
|
@@ -3152,7 +3153,7 @@ Style/ClassMethodsDefinitions:
|
|
3152
3153
|
StyleGuide: '#def-self-class-methods'
|
3153
3154
|
Enabled: false
|
3154
3155
|
VersionAdded: '0.89'
|
3155
|
-
EnforcedStyle:
|
3156
|
+
EnforcedStyle: def_self
|
3156
3157
|
SupportedStyles:
|
3157
3158
|
- def_self
|
3158
3159
|
- self_class
|
@@ -3698,6 +3699,8 @@ Style/HashSyntax:
|
|
3698
3699
|
- always
|
3699
3700
|
# forces use of explicit hash literal value.
|
3700
3701
|
- never
|
3702
|
+
# accepts both shorthand and explicit use of hash literal value.
|
3703
|
+
- either
|
3701
3704
|
# Force hashes that have a symbol value to use hash rockets
|
3702
3705
|
UseHashRocketsWithSymbolValues: false
|
3703
3706
|
# Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style
|
@@ -3812,8 +3815,8 @@ Style/InverseMethods:
|
|
3812
3815
|
:>: :<=
|
3813
3816
|
# `ActiveSupport` defines some common inverse methods. They are listed below,
|
3814
3817
|
# and not enabled by default.
|
3815
|
-
|
3816
|
-
|
3818
|
+
# :present?: :blank?,
|
3819
|
+
# :include?: :exclude?
|
3817
3820
|
# `InverseBlocks` are methods that are inverted by inverting the return
|
3818
3821
|
# of the block that is passed to the method
|
3819
3822
|
InverseBlocks:
|
@@ -68,8 +68,11 @@ module RuboCop
|
|
68
68
|
|
69
69
|
# @!method defined_ruby_version(node)
|
70
70
|
def_node_matcher :defined_ruby_version, <<~PATTERN
|
71
|
-
{
|
72
|
-
|
71
|
+
{
|
72
|
+
$(str _)
|
73
|
+
$(array (str _) (str _))
|
74
|
+
(send (const (const nil? :Gem) :Requirement) :new $str+)
|
75
|
+
}
|
73
76
|
PATTERN
|
74
77
|
|
75
78
|
def on_new_investigation
|
@@ -97,7 +100,11 @@ module RuboCop
|
|
97
100
|
def extract_ruby_version(required_ruby_version)
|
98
101
|
return unless required_ruby_version
|
99
102
|
|
100
|
-
if required_ruby_version.
|
103
|
+
if required_ruby_version.is_a?(Array)
|
104
|
+
required_ruby_version = required_ruby_version.detect do |v|
|
105
|
+
/[>=]/.match?(v.str_content)
|
106
|
+
end
|
107
|
+
elsif required_ruby_version.array_type?
|
101
108
|
required_ruby_version = required_ruby_version.children.detect do |v|
|
102
109
|
/[>=]/.match?(v.str_content)
|
103
110
|
end
|
@@ -182,7 +182,8 @@ module RuboCop
|
|
182
182
|
end
|
183
183
|
|
184
184
|
def generate(template)
|
185
|
-
format(template, department: badge.department,
|
185
|
+
format(template, department: badge.department.to_s.gsub('/', '::'),
|
186
|
+
cop_name: badge.cop_name)
|
186
187
|
end
|
187
188
|
|
188
189
|
def spec_path
|
@@ -209,8 +210,8 @@ module RuboCop
|
|
209
210
|
return 'rspec' if camel_case_string == 'RSpec'
|
210
211
|
|
211
212
|
camel_case_string
|
212
|
-
.gsub(
|
213
|
-
.gsub(
|
213
|
+
.gsub(%r{([^A-Z/])([A-Z]+)}, '\1_\2')
|
214
|
+
.gsub(%r{([A-Z])([A-Z][^A-Z\d/]+)}, '\1_\2')
|
214
215
|
.downcase
|
215
216
|
end
|
216
217
|
end
|
@@ -53,23 +53,50 @@ module RuboCop
|
|
53
53
|
'following the first line of a multi-line method call.'
|
54
54
|
|
55
55
|
def on_send(node)
|
56
|
-
|
57
|
-
return if !multiple_arguments?(node, first_arg) || (node.send_type? && node.method?(:[]=))
|
56
|
+
return if !multiple_arguments?(node) || (node.send_type? && node.method?(:[]=))
|
58
57
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
else
|
63
|
-
check_alignment(node.arguments, base_column(node, first_arg))
|
64
|
-
end
|
58
|
+
items = flattened_arguments(node)
|
59
|
+
|
60
|
+
check_alignment(items, base_column(node, items.first))
|
65
61
|
end
|
62
|
+
|
66
63
|
alias on_csend on_send
|
67
64
|
|
68
65
|
private
|
69
66
|
|
70
|
-
def
|
67
|
+
def flattened_arguments(node)
|
68
|
+
if fixed_indentation?
|
69
|
+
arguments_with_last_arg_pairs(node)
|
70
|
+
else
|
71
|
+
arguments_or_first_arg_pairs(node)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def arguments_with_last_arg_pairs(node)
|
76
|
+
items = node.arguments[0..-2]
|
77
|
+
last_arg = node.arguments.last
|
78
|
+
|
79
|
+
if last_arg.hash_type? && !last_arg.braces?
|
80
|
+
items += last_arg.pairs
|
81
|
+
else
|
82
|
+
items << last_arg
|
83
|
+
end
|
84
|
+
items
|
85
|
+
end
|
86
|
+
|
87
|
+
def arguments_or_first_arg_pairs(node)
|
88
|
+
first_arg = node.first_argument
|
89
|
+
if first_arg.hash_type? && !first_arg.braces?
|
90
|
+
first_arg.pairs
|
91
|
+
else
|
92
|
+
node.arguments
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def multiple_arguments?(node)
|
71
97
|
return true if node.arguments.size >= 2
|
72
98
|
|
99
|
+
first_argument = node.first_argument
|
73
100
|
first_argument&.hash_type? && first_argument.pairs.count >= 2
|
74
101
|
end
|
75
102
|
|
@@ -81,7 +81,7 @@ module RuboCop
|
|
81
81
|
|
82
82
|
locations.each do |loc|
|
83
83
|
line = loc.line
|
84
|
-
next if line == line_of_def_or_kwbegin
|
84
|
+
next if line == line_of_def_or_kwbegin || last_rescue_and_end_on_same_line(body)
|
85
85
|
|
86
86
|
keyword = loc.source
|
87
87
|
# below the keyword
|
@@ -91,6 +91,10 @@ module RuboCop
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
def last_rescue_and_end_on_same_line(body)
|
95
|
+
body.rescue_type? && body.resbody_branches.last.loc.line == body.parent.loc.end.line
|
96
|
+
end
|
97
|
+
|
94
98
|
def message(location, keyword)
|
95
99
|
format(MSG, location: location, keyword: keyword)
|
96
100
|
end
|
@@ -222,11 +222,16 @@ module RuboCop
|
|
222
222
|
node.pairs.any? &&
|
223
223
|
node.parent&.call_type?
|
224
224
|
|
225
|
+
left_sibling = argument_before_hash(node)
|
225
226
|
parent_loc = node.parent.loc
|
226
|
-
selector = parent_loc.selector || parent_loc.expression
|
227
|
+
selector = left_sibling || parent_loc.selector || parent_loc.expression
|
227
228
|
same_line?(selector, node.pairs.first)
|
228
229
|
end
|
229
230
|
|
231
|
+
def argument_before_hash(hash_node)
|
232
|
+
hash_node.left_sibling.respond_to?(:loc) ? hash_node.left_sibling : nil
|
233
|
+
end
|
234
|
+
|
230
235
|
def reset!
|
231
236
|
self.offenses_by = {}
|
232
237
|
self.column_deltas = Hash.new { |hash, key| hash[key] = {} }
|
@@ -143,7 +143,7 @@ module RuboCop
|
|
143
143
|
return true
|
144
144
|
end
|
145
145
|
|
146
|
-
do_keyword_line == selector
|
146
|
+
do_keyword_line == selector&.line && rescue_keyword_column == selector.column
|
147
147
|
end
|
148
148
|
|
149
149
|
def aligned_with_leading_dot?(do_keyword_line, send_node_loc, rescue_keyword_column)
|
@@ -30,7 +30,11 @@ module RuboCop
|
|
30
30
|
|
31
31
|
def on_new_investigation
|
32
32
|
processed_source.diagnostics.each do |diagnostic|
|
33
|
-
|
33
|
+
if target_ruby_version >= 3.0
|
34
|
+
next unless diagnostic.reason == :ambiguous_regexp
|
35
|
+
else
|
36
|
+
next unless diagnostic.reason == :ambiguous_literal
|
37
|
+
end
|
34
38
|
|
35
39
|
offense_node = find_offense_node_by(diagnostic)
|
36
40
|
|
@@ -33,11 +33,12 @@ module RuboCop
|
|
33
33
|
# @!method io_select(node)
|
34
34
|
def_node_matcher :io_select, <<~PATTERN
|
35
35
|
(send
|
36
|
-
(const {nil? cbase} :IO) :select
|
36
|
+
(const {nil? cbase} :IO) :select $...)
|
37
37
|
PATTERN
|
38
38
|
|
39
39
|
def on_send(node)
|
40
|
-
|
40
|
+
read, write, _excepts, timeout = *io_select(node)
|
41
|
+
return unless read
|
41
42
|
return unless scheduler_compatible?(read, write) || scheduler_compatible?(write, read)
|
42
43
|
|
43
44
|
preferred = preferred_method(read, write, timeout)
|
@@ -51,13 +52,13 @@ module RuboCop
|
|
51
52
|
private
|
52
53
|
|
53
54
|
def scheduler_compatible?(io1, io2)
|
54
|
-
return false unless io1
|
55
|
+
return false unless io1&.array_type? && io1.values.size == 1
|
55
56
|
|
56
|
-
io2
|
57
|
+
io2&.array_type? ? io2.values.empty? : (io2.nil? || io2.nil_type?)
|
57
58
|
end
|
58
59
|
|
59
60
|
def preferred_method(read, write, timeout)
|
60
|
-
timeout_argument = timeout.
|
61
|
+
timeout_argument = timeout.nil? ? '' : "(#{timeout.source})"
|
61
62
|
|
62
63
|
if read.array_type? && read.values[0]
|
63
64
|
"#{read.values[0].source}.wait_readable#{timeout_argument}"
|
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
EXPLICIT_HASH_VALUE_MSG = 'Explicit the hash value.'
|
9
9
|
|
10
10
|
def on_pair(node)
|
11
|
-
return if
|
11
|
+
return if ignore_hash_shorthand_syntax?(node)
|
12
12
|
|
13
13
|
hash_key_source = node.key.source
|
14
14
|
|
@@ -31,12 +31,17 @@ module RuboCop
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
+
def ignore_hash_shorthand_syntax?(pair_node)
|
35
|
+
target_ruby_version <= 3.0 || enforced_shorthand_syntax == 'either' ||
|
36
|
+
!pair_node.parent.hash_type?
|
37
|
+
end
|
38
|
+
|
34
39
|
def enforced_shorthand_syntax
|
35
40
|
cop_config.fetch('EnforcedShorthandSyntax', 'always')
|
36
41
|
end
|
37
42
|
|
38
43
|
def require_hash_value?(hash_key_source, node)
|
39
|
-
return true if
|
44
|
+
return true if require_hash_value_for_around_hash_literal?(node)
|
40
45
|
|
41
46
|
hash_value = node.value
|
42
47
|
return true unless hash_value.send_type? || hash_value.lvar_type?
|
@@ -44,12 +49,33 @@ module RuboCop
|
|
44
49
|
hash_key_source != hash_value.source || hash_key_source.end_with?('!', '?')
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
52
|
+
def require_hash_value_for_around_hash_literal?(node)
|
48
53
|
return false unless (ancestor = node.parent.parent)
|
49
|
-
return false
|
54
|
+
return false if ancestor.send_type? && ancestor.method?(:[])
|
55
|
+
|
56
|
+
!node.parent.braces? && !use_element_of_hash_literal_as_receiver?(ancestor, node.parent) &&
|
57
|
+
(use_modifier_form_without_parenthesized_method_call?(ancestor) ||
|
58
|
+
without_parentheses_call_expr_follows?(ancestor))
|
59
|
+
end
|
60
|
+
|
61
|
+
def use_element_of_hash_literal_as_receiver?(ancestor, parent)
|
62
|
+
# `{value:}.do_something` is a valid syntax.
|
63
|
+
ancestor.send_type? && ancestor.receiver == parent
|
64
|
+
end
|
65
|
+
|
66
|
+
def use_modifier_form_without_parenthesized_method_call?(ancestor)
|
67
|
+
return false if ancestor.respond_to?(:parenthesized?) && ancestor.parenthesized?
|
68
|
+
return false unless (parent = ancestor.parent)
|
69
|
+
|
70
|
+
parent.respond_to?(:modifier_form?) && parent.modifier_form?
|
71
|
+
end
|
72
|
+
|
73
|
+
def without_parentheses_call_expr_follows?(ancestor)
|
74
|
+
right_sibling = ancestor.right_sibling
|
75
|
+
right_sibling ||= ancestor.each_ancestor.find(&:assignment?)&.right_sibling
|
76
|
+
return false unless right_sibling
|
50
77
|
|
51
|
-
ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized? &&
|
52
|
-
right_sibling.respond_to?(:parenthesized?) && !right_sibling.parenthesized?
|
78
|
+
ancestor.respond_to?(:parenthesized?) && !ancestor.parenthesized? && !!right_sibling
|
53
79
|
end
|
54
80
|
end
|
55
81
|
end
|
@@ -9,6 +9,9 @@ module RuboCop
|
|
9
9
|
# by `do_something(&)`.
|
10
10
|
#
|
11
11
|
# It also supports the opposite style by alternative `explicit` option.
|
12
|
+
# You can specify the block variable name for auto-correction with `BlockForwardingName`.
|
13
|
+
# The default variable name is `block`. If the name is already in use, it will not be
|
14
|
+
# auto-corrected.
|
12
15
|
#
|
13
16
|
# @example EnforcedStyle: anonymous (default)
|
14
17
|
#
|
@@ -50,12 +53,13 @@ module RuboCop
|
|
50
53
|
last_argument = node.arguments.last
|
51
54
|
return if expected_block_forwarding_style?(node, last_argument)
|
52
55
|
|
53
|
-
register_offense(last_argument)
|
56
|
+
register_offense(last_argument, node)
|
54
57
|
|
55
58
|
node.each_descendant(:block_pass) do |block_pass_node|
|
56
|
-
next if block_pass_node.children.first&.sym_type?
|
59
|
+
next if block_pass_node.children.first&.sym_type? ||
|
60
|
+
last_argument.source != block_pass_node.source
|
57
61
|
|
58
|
-
register_offense(block_pass_node)
|
62
|
+
register_offense(block_pass_node, node)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
alias on_defs on_def
|
@@ -66,7 +70,7 @@ module RuboCop
|
|
66
70
|
if style == :anonymous
|
67
71
|
!explicit_block_argument?(last_argument) ||
|
68
72
|
use_kwarg_in_method_definition?(node) ||
|
69
|
-
use_block_argument_as_local_variable?(node, last_argument)
|
73
|
+
use_block_argument_as_local_variable?(node, last_argument.source[1..-1])
|
70
74
|
else
|
71
75
|
!anonymous_block_argument?(last_argument)
|
72
76
|
end
|
@@ -84,22 +88,32 @@ module RuboCop
|
|
84
88
|
node.blockarg_type? && !node.name.nil?
|
85
89
|
end
|
86
90
|
|
91
|
+
def register_offense(block_argument, node)
|
92
|
+
add_offense(block_argument, message: format(MSG, style: style)) do |corrector|
|
93
|
+
if style == :anonymous
|
94
|
+
corrector.replace(block_argument, '&')
|
95
|
+
|
96
|
+
arguments = block_argument.parent
|
97
|
+
|
98
|
+
add_parentheses(arguments, corrector) unless arguments.parenthesized_call?
|
99
|
+
else
|
100
|
+
unless use_block_argument_as_local_variable?(node, block_forwarding_name)
|
101
|
+
corrector.replace(block_argument, "&#{block_forwarding_name}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
87
107
|
def use_block_argument_as_local_variable?(node, last_argument)
|
88
108
|
return if node.body.nil?
|
89
109
|
|
90
110
|
node.body.each_descendant(:lvar).any? do |lvar|
|
91
|
-
!lvar.parent.block_pass_type? && lvar.source == last_argument
|
111
|
+
!lvar.parent.block_pass_type? && lvar.source == last_argument
|
92
112
|
end
|
93
113
|
end
|
94
114
|
|
95
|
-
def
|
96
|
-
|
97
|
-
corrector.replace(block_argument, '&')
|
98
|
-
|
99
|
-
arguments = block_argument.parent
|
100
|
-
|
101
|
-
add_parentheses(arguments, corrector) unless arguments.parenthesized_call?
|
102
|
-
end
|
115
|
+
def block_forwarding_name
|
116
|
+
cop_config.fetch('BlockForwardingName', 'block')
|
103
117
|
end
|
104
118
|
end
|
105
119
|
end
|
@@ -41,7 +41,7 @@ module RuboCop
|
|
41
41
|
|
42
42
|
# @!method reject_method_with_block_pass?(node)
|
43
43
|
def_node_matcher :reject_method_with_block_pass?, <<~PATTERN
|
44
|
-
(send
|
44
|
+
(send !nil? {:reject :reject!}
|
45
45
|
(block_pass
|
46
46
|
(sym :nil?)))
|
47
47
|
PATTERN
|
@@ -50,7 +50,7 @@ module RuboCop
|
|
50
50
|
def_node_matcher :reject_method?, <<~PATTERN
|
51
51
|
(block
|
52
52
|
(send
|
53
|
-
|
53
|
+
!nil? {:reject :reject!})
|
54
54
|
$(args ...)
|
55
55
|
(send
|
56
56
|
$(lvar _) :nil?))
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
60
60
|
def_node_matcher :select_method?, <<~PATTERN
|
61
61
|
(block
|
62
62
|
(send
|
63
|
-
|
63
|
+
!nil? {:select :select!})
|
64
64
|
$(args ...)
|
65
65
|
(send
|
66
66
|
(send
|
@@ -23,6 +23,12 @@ module RuboCop
|
|
23
23
|
# It can enforce either the use of the explicit hash value syntax or
|
24
24
|
# the use of Ruby 3.1's hash value shorthand syntax.
|
25
25
|
#
|
26
|
+
# The supported styles are:
|
27
|
+
#
|
28
|
+
# * always - forces use of the 3.1 syntax (e.g. {foo:})
|
29
|
+
# * never - forces use of explicit hash literal value
|
30
|
+
# * either - accepts both shorthand and explicit use of hash literal value
|
31
|
+
#
|
26
32
|
# @example EnforcedStyle: ruby19 (default)
|
27
33
|
# # bad
|
28
34
|
# {:a => 2}
|
@@ -75,6 +81,14 @@ module RuboCop
|
|
75
81
|
# # good
|
76
82
|
# {foo: foo, bar: bar}
|
77
83
|
#
|
84
|
+
# @example EnforcedShorthandSyntax: either
|
85
|
+
#
|
86
|
+
# # good
|
87
|
+
# {foo: foo, bar: bar}
|
88
|
+
#
|
89
|
+
# # good
|
90
|
+
# {foo:, bar:}
|
91
|
+
#
|
78
92
|
class HashSyntax < Base
|
79
93
|
include ConfigurableEnforcedStyle
|
80
94
|
include HashShorthandSyntax
|
@@ -48,14 +48,21 @@ module RuboCop
|
|
48
48
|
node.each_ancestor(:def, :defs).any?(&:endless?) && node.arguments.any?
|
49
49
|
end
|
50
50
|
|
51
|
-
# Require hash value omission be enclosed in parentheses to prevent the following issue:
|
52
|
-
# https://bugs.ruby-lang.org/issues/18396.
|
53
51
|
def require_parentheses_for_hash_value_omission?(node)
|
54
|
-
return unless (last_argument = node.last_argument)
|
52
|
+
return false unless (last_argument = node.last_argument)
|
53
|
+
return false if !last_argument.hash_type? || !last_argument.pairs.last&.value_omission?
|
55
54
|
|
56
|
-
|
55
|
+
modifier_form?(node) || exist_next_line_expression?(node)
|
56
|
+
end
|
57
57
|
|
58
|
-
|
58
|
+
def modifier_form?(node)
|
59
|
+
node.parent.respond_to?(:modifier_form?) && node.parent.modifier_form?
|
60
|
+
end
|
61
|
+
|
62
|
+
# Require hash value omission be enclosed in parentheses to prevent the following issue:
|
63
|
+
# https://bugs.ruby-lang.org/issues/18396.
|
64
|
+
def exist_next_line_expression?(node)
|
65
|
+
node.parent&.assignment? ? node.parent.right_sibling : node.right_sibling
|
59
66
|
end
|
60
67
|
|
61
68
|
def syntax_like_method_call?(node)
|
@@ -47,7 +47,7 @@ module RuboCop
|
|
47
47
|
# allowed when forwarding arguments with the triple-dot syntax introduced
|
48
48
|
# in Ruby 2.7 as omitting them starts an endless range.
|
49
49
|
# And Ruby 3.1's hash omission syntax has a case that requires parentheses
|
50
|
-
# because the issue https://bugs.ruby-lang.org/issues/18396.
|
50
|
+
# because of the following issue: https://bugs.ruby-lang.org/issues/18396.
|
51
51
|
#
|
52
52
|
# @example EnforcedStyle: require_parentheses (default)
|
53
53
|
#
|
@@ -97,7 +97,7 @@ module RuboCop
|
|
97
97
|
offense_range = node.loc.begin
|
98
98
|
|
99
99
|
add_offense(offense_range) do |corrector|
|
100
|
-
if
|
100
|
+
if node.parent&.assignment?
|
101
101
|
replace_begin_with_statement(corrector, offense_range, node)
|
102
102
|
else
|
103
103
|
corrector.remove(offense_range)
|
@@ -170,11 +170,7 @@ module RuboCop
|
|
170
170
|
end
|
171
171
|
|
172
172
|
def valid_begin_assignment?(node)
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
|
-
def any_ancestor_assignment_node?(node)
|
177
|
-
node.each_ancestor.any?(&:assignment?)
|
173
|
+
node.parent&.assignment? && !node.children.one?
|
178
174
|
end
|
179
175
|
end
|
180
176
|
end
|
@@ -91,11 +91,12 @@ module RuboCop
|
|
91
91
|
second.int_type? ? second.to_a.first : :unknown
|
92
92
|
end
|
93
93
|
|
94
|
-
|
94
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
95
|
+
def range_size(range_node)
|
95
96
|
vals = range_node.to_a
|
96
|
-
return :unknown unless vals.all?
|
97
|
+
return :unknown unless vals.all? { |val| val.nil? || val.int_type? }
|
97
98
|
|
98
|
-
low, high = vals.map { |val| val.children[0] }
|
99
|
+
low, high = vals.map { |val| val.nil? ? 0 : val.children[0] }
|
99
100
|
return :unknown unless low.zero? && high >= 0
|
100
101
|
|
101
102
|
case range_node.type
|
@@ -105,6 +106,7 @@ module RuboCop
|
|
105
106
|
(low..high).size
|
106
107
|
end
|
107
108
|
end
|
109
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
108
110
|
|
109
111
|
def source_range(shuffle_node, node)
|
110
112
|
Parser::Source::Range.new(shuffle_node.source_range.source_buffer,
|
@@ -67,7 +67,10 @@ module RuboCop
|
|
67
67
|
MSG_COMPLEX = '%<command>s parentheses for ternary expressions with complex conditions.'
|
68
68
|
|
69
69
|
def on_if(node)
|
70
|
-
|
70
|
+
condition = node.condition
|
71
|
+
|
72
|
+
return if only_closing_parenthesis_is_last_line?(condition)
|
73
|
+
return if condition_as_parenthesized_one_line_pattern_matching?(condition)
|
71
74
|
return unless node.ternary? && !infinite_loop? && offense?(node)
|
72
75
|
|
73
76
|
message = message(node)
|
@@ -77,11 +80,22 @@ module RuboCop
|
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
83
|
+
private
|
84
|
+
|
80
85
|
def only_closing_parenthesis_is_last_line?(condition)
|
81
86
|
condition.source.split("\n").last == ')'
|
82
87
|
end
|
83
88
|
|
84
|
-
|
89
|
+
def condition_as_parenthesized_one_line_pattern_matching?(condition)
|
90
|
+
return false unless condition.parenthesized_call?
|
91
|
+
return false unless (first_child = condition.children.first)
|
92
|
+
|
93
|
+
if target_ruby_version >= 3.0
|
94
|
+
first_child.match_pattern_p_type?
|
95
|
+
else
|
96
|
+
first_child.match_pattern_type? # For Ruby 2.7's one line pattern matching AST.
|
97
|
+
end
|
98
|
+
end
|
85
99
|
|
86
100
|
def autocorrect(corrector, node)
|
87
101
|
condition = node.condition
|
@@ -121,9 +121,14 @@ module RuboCop
|
|
121
121
|
output_buffer.puts "# Offense count: #{offense_count}" if show_offense_counts?
|
122
122
|
|
123
123
|
cop_class = Cop::Registry.global.find_by_cop_name(cop_name)
|
124
|
-
output_buffer.puts '# Cop supports --auto-correct.' if cop_class&.support_autocorrect?
|
125
|
-
|
126
124
|
default_cfg = default_config(cop_name)
|
125
|
+
|
126
|
+
if supports_safe_auto_correct?(cop_class, default_cfg)
|
127
|
+
output_buffer.puts '# Cop supports --auto-correct.'
|
128
|
+
elsif supports_unsafe_autocorrect?(cop_class, default_cfg)
|
129
|
+
output_buffer.puts '# Cop supports --auto-correct-all.'
|
130
|
+
end
|
131
|
+
|
127
132
|
return unless default_cfg
|
128
133
|
|
129
134
|
params = cop_config_params(default_cfg, cfg)
|
@@ -132,6 +137,15 @@ module RuboCop
|
|
132
137
|
output_cop_param_comments(output_buffer, params, default_cfg)
|
133
138
|
end
|
134
139
|
|
140
|
+
def supports_safe_auto_correct?(cop_class, default_cfg)
|
141
|
+
cop_class&.support_autocorrect? &&
|
142
|
+
(default_cfg.nil? || default_cfg['Safe'] || default_cfg['Safe'].nil?)
|
143
|
+
end
|
144
|
+
|
145
|
+
def supports_unsafe_autocorrect?(cop_class, default_cfg)
|
146
|
+
cop_class&.support_autocorrect? && !default_cfg.nil? && default_cfg['Safe'] == false
|
147
|
+
end
|
148
|
+
|
135
149
|
def cop_config_params(default_cfg, cfg)
|
136
150
|
default_cfg.keys -
|
137
151
|
%w[Description StyleGuide Reference Enabled Exclude Safe
|
data/lib/rubocop/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.25.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2022-02-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: parallel
|
@@ -32,14 +32,14 @@ dependencies:
|
|
32
32
|
requirements:
|
33
33
|
- - ">="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 3.
|
35
|
+
version: 3.1.0.0
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 3.
|
42
|
+
version: 3.1.0.0
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: rainbow
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -911,7 +911,7 @@ metadata:
|
|
911
911
|
homepage_uri: https://rubocop.org/
|
912
912
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
913
913
|
source_code_uri: https://github.com/rubocop/rubocop/
|
914
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
914
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.25/
|
915
915
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
916
916
|
rubygems_mfa_required: 'true'
|
917
917
|
post_install_message:
|