rubocop 1.56.2 → 1.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +12 -6
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +3 -1
- data/lib/rubocop/cop/bundler/duplicated_group.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/example_description.rb +42 -22
- data/lib/rubocop/cop/internal_affairs/redundant_method_dispatch_node.rb +11 -2
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +2 -0
- data/lib/rubocop/cop/layout/dot_position.rb +1 -5
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +41 -8
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +3 -0
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +18 -3
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_parens.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +10 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/mixed_case_range.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +0 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +20 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +11 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +37 -10
- data/lib/rubocop/cop/metrics/block_length.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +2 -2
- data/lib/rubocop/cop/metrics/method_length.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -2
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +5 -7
- data/lib/rubocop/cop/style/arguments_forwarding.rb +8 -6
- data/lib/rubocop/cop/style/array_intersect.rb +13 -5
- data/lib/rubocop/cop/style/class_equality_comparison.rb +5 -0
- data/lib/rubocop/cop/style/collection_methods.rb +2 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/empty_case_condition.rb +6 -1
- data/lib/rubocop/cop/style/for.rb +1 -1
- data/lib/rubocop/cop/style/format_string.rb +24 -3
- data/lib/rubocop/cop/style/guard_clause.rb +26 -0
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +17 -3
- data/lib/rubocop/cop/style/multiline_block_chain.rb +1 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +1 -1
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +3 -11
- data/lib/rubocop/cop/style/operator_method_call.rb +6 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +9 -1
- data/lib/rubocop/cop/style/redundant_conditional.rb +1 -9
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +86 -5
- data/lib/rubocop/cop/style/redundant_exception.rb +32 -12
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +18 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +21 -5
- data/lib/rubocop/cop/style/return_nil.rb +6 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +65 -0
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +3 -1
- data/lib/rubocop/cop/style/symbol_array.rb +10 -11
- data/lib/rubocop/cop/style/yoda_expression.rb +8 -7
- data/lib/rubocop/file_finder.rb +4 -7
- data/lib/rubocop/magic_comment.rb +12 -10
- data/lib/rubocop/rspec/shared_contexts.rb +2 -3
- data/lib/rubocop/server/cache.rb +1 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- metadata +10 -9
@@ -13,25 +13,68 @@ module RuboCop
|
|
13
13
|
# # good
|
14
14
|
# do_something(foo: bar, baz: qux)
|
15
15
|
#
|
16
|
+
# # bad
|
17
|
+
# do_something(**{foo: bar, baz: qux}.merge(options))
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# do_something(foo: bar, baz: qux, **options)
|
21
|
+
#
|
16
22
|
class RedundantDoubleSplatHashBraces < Base
|
17
23
|
extend AutoCorrector
|
18
24
|
|
19
25
|
MSG = 'Remove the redundant double splat and braces, use keyword arguments directly.'
|
26
|
+
MERGE_METHODS = %i[merge merge!].freeze
|
20
27
|
|
28
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
21
29
|
def on_hash(node)
|
22
30
|
return if node.pairs.empty? || node.pairs.any?(&:hash_rocket?)
|
23
31
|
return unless (parent = node.parent)
|
24
|
-
return
|
32
|
+
return if parent.call_type? && !merge_method?(parent)
|
33
|
+
return unless (kwsplat = node.each_ancestor(:kwsplat).first)
|
34
|
+
return if allowed_double_splat_receiver?(kwsplat)
|
25
35
|
|
26
|
-
add_offense(
|
27
|
-
corrector
|
28
|
-
corrector.remove(opening_brace(node))
|
29
|
-
corrector.remove(closing_brace(node))
|
36
|
+
add_offense(kwsplat) do |corrector|
|
37
|
+
autocorrect(corrector, node, kwsplat)
|
30
38
|
end
|
31
39
|
end
|
40
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
32
41
|
|
33
42
|
private
|
34
43
|
|
44
|
+
def allowed_double_splat_receiver?(kwsplat)
|
45
|
+
return false unless kwsplat.children.first.call_type?
|
46
|
+
|
47
|
+
root_receiver = root_receiver(kwsplat.children.first)
|
48
|
+
|
49
|
+
!root_receiver&.hash_type?
|
50
|
+
end
|
51
|
+
|
52
|
+
def autocorrect(corrector, node, kwsplat)
|
53
|
+
corrector.remove(kwsplat.loc.operator)
|
54
|
+
corrector.remove(opening_brace(node))
|
55
|
+
corrector.remove(closing_brace(node))
|
56
|
+
|
57
|
+
merge_methods = select_merge_method_nodes(kwsplat)
|
58
|
+
return if merge_methods.empty?
|
59
|
+
|
60
|
+
autocorrect_merge_methods(corrector, merge_methods, kwsplat)
|
61
|
+
end
|
62
|
+
|
63
|
+
def root_receiver(node)
|
64
|
+
receiver = node.receiver
|
65
|
+
if receiver&.receiver
|
66
|
+
root_receiver(receiver)
|
67
|
+
else
|
68
|
+
receiver
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def select_merge_method_nodes(kwsplat)
|
73
|
+
extract_send_methods(kwsplat).select do |node|
|
74
|
+
merge_method?(node)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
35
78
|
def opening_brace(node)
|
36
79
|
node.loc.begin.join(node.children.first.source_range.begin)
|
37
80
|
end
|
@@ -39,6 +82,44 @@ module RuboCop
|
|
39
82
|
def closing_brace(node)
|
40
83
|
node.children.last.source_range.end.join(node.loc.end)
|
41
84
|
end
|
85
|
+
|
86
|
+
def autocorrect_merge_methods(corrector, merge_methods, kwsplat)
|
87
|
+
range = range_of_merge_methods(merge_methods)
|
88
|
+
|
89
|
+
new_kwsplat_arguments = extract_send_methods(kwsplat).map do |descendant|
|
90
|
+
convert_to_new_arguments(descendant)
|
91
|
+
end
|
92
|
+
new_source = new_kwsplat_arguments.compact.reverse.unshift('').join(', ')
|
93
|
+
|
94
|
+
corrector.replace(range, new_source)
|
95
|
+
end
|
96
|
+
|
97
|
+
def range_of_merge_methods(merge_methods)
|
98
|
+
begin_merge_method = merge_methods.last
|
99
|
+
end_merge_method = merge_methods.first
|
100
|
+
|
101
|
+
begin_merge_method.loc.dot.begin.join(end_merge_method.source_range.end)
|
102
|
+
end
|
103
|
+
|
104
|
+
def extract_send_methods(kwsplat)
|
105
|
+
kwsplat.each_descendant(:send, :csend)
|
106
|
+
end
|
107
|
+
|
108
|
+
def convert_to_new_arguments(node)
|
109
|
+
return unless merge_method?(node)
|
110
|
+
|
111
|
+
node.arguments.map do |arg|
|
112
|
+
if arg.hash_type?
|
113
|
+
arg.source
|
114
|
+
else
|
115
|
+
"**#{arg.source}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def merge_method?(node)
|
121
|
+
MERGE_METHODS.include?(node.method_name)
|
122
|
+
end
|
42
123
|
end
|
43
124
|
end
|
44
125
|
end
|
@@ -5,17 +5,21 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Checks for RuntimeError as the argument of raise/fail.
|
7
7
|
#
|
8
|
-
# It checks for code like this:
|
9
|
-
#
|
10
8
|
# @example
|
11
|
-
# #
|
9
|
+
# # bad
|
12
10
|
# raise RuntimeError, 'message'
|
13
|
-
#
|
14
|
-
# # Bad
|
15
11
|
# raise RuntimeError.new('message')
|
16
12
|
#
|
17
|
-
# #
|
13
|
+
# # good
|
18
14
|
# raise 'message'
|
15
|
+
#
|
16
|
+
# # bad - message is not a string
|
17
|
+
# raise RuntimeError, Object.new
|
18
|
+
# raise RuntimeError.new(Object.new)
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# raise Object.new.to_s
|
22
|
+
#
|
19
23
|
class RedundantException < Base
|
20
24
|
extend AutoCorrector
|
21
25
|
|
@@ -30,26 +34,42 @@ module RuboCop
|
|
30
34
|
fix_exploded(node) || fix_compact(node)
|
31
35
|
end
|
32
36
|
|
37
|
+
private
|
38
|
+
|
33
39
|
def fix_exploded(node)
|
34
40
|
exploded?(node) do |command, message|
|
35
41
|
add_offense(node, message: MSG_1) do |corrector|
|
36
|
-
|
37
|
-
corrector.replace(node, "#{command}(#{message.source})")
|
38
|
-
else
|
39
|
-
corrector.replace(node, "#{command} #{message.source}")
|
40
|
-
end
|
42
|
+
corrector.replace(node, replaced_exploded(node, command, message))
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
44
46
|
|
47
|
+
def replaced_exploded(node, command, message)
|
48
|
+
arg = string_message?(message) ? message.source : "#{message.source}.to_s"
|
49
|
+
arg = node.parenthesized? ? "(#{arg})" : " #{arg}"
|
50
|
+
"#{command}#{arg}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def string_message?(message)
|
54
|
+
message.str_type? || message.dstr_type? || message.xstr_type?
|
55
|
+
end
|
56
|
+
|
45
57
|
def fix_compact(node)
|
46
58
|
compact?(node) do |new_call, message|
|
47
59
|
add_offense(node, message: MSG_2) do |corrector|
|
48
|
-
corrector.replace(new_call, message
|
60
|
+
corrector.replace(new_call, replaced_compact(message))
|
49
61
|
end
|
50
62
|
end
|
51
63
|
end
|
52
64
|
|
65
|
+
def replaced_compact(message)
|
66
|
+
if string_message?(message)
|
67
|
+
message.source
|
68
|
+
else
|
69
|
+
"#{message.source}.to_s"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
53
73
|
# @!method exploded?(node)
|
54
74
|
def_node_matcher :exploded?, <<~PATTERN
|
55
75
|
(send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_)
|
@@ -6,6 +6,12 @@ module RuboCop
|
|
6
6
|
# Identifies usages of `any?`, `empty?` or `none?` predicate methods
|
7
7
|
# chained to `select`/`filter`/`find_all` and change them to use predicate method instead.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop's autocorrection is unsafe because `array.select.any?` evaluates all elements
|
11
|
+
# through the `select` method, while `array.any?` uses short-circuit evaluation.
|
12
|
+
# In other words, `array.select.any?` guarantees the evaluation of every element,
|
13
|
+
# but `array.any?` does not necessarily evaluate all of them.
|
14
|
+
#
|
9
15
|
# @example
|
10
16
|
# # bad
|
11
17
|
# arr.select { |x| x > 1 }.any?
|
@@ -28,6 +34,9 @@ module RuboCop
|
|
28
34
|
# # good
|
29
35
|
# arr.select { |x| x > 1 }.many?
|
30
36
|
#
|
37
|
+
# # good
|
38
|
+
# arr.select { |x| x > 1 }.present?
|
39
|
+
#
|
31
40
|
# @example AllCops:ActiveSupportExtensionsEnabled: true
|
32
41
|
# # bad
|
33
42
|
# arr.select { |x| x > 1 }.many?
|
@@ -35,12 +44,18 @@ module RuboCop
|
|
35
44
|
# # good
|
36
45
|
# arr.many? { |x| x > 1 }
|
37
46
|
#
|
47
|
+
# # bad
|
48
|
+
# arr.select { |x| x > 1 }.present?
|
49
|
+
#
|
50
|
+
# # good
|
51
|
+
# arr.any? { |x| x > 1 }
|
52
|
+
#
|
38
53
|
class RedundantFilterChain < Base
|
39
54
|
extend AutoCorrector
|
40
55
|
|
41
56
|
MSG = 'Use `%<prefer>s` instead of `%<first_method>s.%<second_method>s`.'
|
42
57
|
|
43
|
-
RAILS_METHODS = %i[many?].freeze
|
58
|
+
RAILS_METHODS = %i[many? present?].freeze
|
44
59
|
RESTRICT_ON_SEND = (%i[any? empty? none? one?] + RAILS_METHODS).freeze
|
45
60
|
|
46
61
|
# @!method select_predicate?(node)
|
@@ -58,7 +73,8 @@ module RuboCop
|
|
58
73
|
empty?: :none?,
|
59
74
|
none?: :none?,
|
60
75
|
one?: :one?,
|
61
|
-
many?: :many
|
76
|
+
many?: :many?,
|
77
|
+
present?: :any?
|
62
78
|
}.freeze
|
63
79
|
private_constant :REPLACEMENT_METHODS
|
64
80
|
|
@@ -126,16 +126,32 @@ module RuboCop
|
|
126
126
|
|
127
127
|
def check(begin_node)
|
128
128
|
node = begin_node.children.first
|
129
|
-
return offense(begin_node, 'a keyword') if keyword_with_redundant_parentheses?(node)
|
130
|
-
return offense(begin_node, 'a literal') if disallowed_literal?(begin_node, node)
|
131
|
-
return offense(begin_node, 'a variable') if node.variable?
|
132
|
-
return offense(begin_node, 'a constant') if node.const_type?
|
133
129
|
|
134
|
-
|
130
|
+
if (message = find_offense_message(begin_node, node))
|
131
|
+
return offense(begin_node, message)
|
132
|
+
end
|
135
133
|
|
136
134
|
check_send(begin_node, node) if node.call_type?
|
137
135
|
end
|
138
136
|
|
137
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
138
|
+
def find_offense_message(begin_node, node)
|
139
|
+
return 'a keyword' if keyword_with_redundant_parentheses?(node)
|
140
|
+
return 'a literal' if disallowed_literal?(begin_node, node)
|
141
|
+
return 'a variable' if node.variable?
|
142
|
+
return 'a constant' if node.const_type?
|
143
|
+
return 'an interpolated expression' if interpolation?(begin_node)
|
144
|
+
|
145
|
+
return if begin_node.chained? || !begin_node.parent.nil?
|
146
|
+
|
147
|
+
if node.and_type? || node.or_type?
|
148
|
+
'a logical expression'
|
149
|
+
elsif node.respond_to?(:comparison_method?) && node.comparison_method?
|
150
|
+
'a comparison expression'
|
151
|
+
end
|
152
|
+
end
|
153
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
154
|
+
|
139
155
|
# @!method interpolation?(node)
|
140
156
|
def_node_matcher :interpolation?, '[^begin ^^dstr]'
|
141
157
|
|
@@ -3,9 +3,13 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# Enforces consistency between
|
6
|
+
# Enforces consistency between `return nil` and `return`.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# This cop is disabled by default. Because there seems to be a perceived semantic difference
|
9
|
+
# between `return` and `return nil`. The former can be seen as just halting evaluation,
|
10
|
+
# while the latter might be used when the return value is of specific concern.
|
11
|
+
#
|
12
|
+
# Supported styles are `return` and `return_nil`.
|
9
13
|
#
|
10
14
|
# @example EnforcedStyle: return (default)
|
11
15
|
# # bad
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# Checks for single-line `do`...`end` block.
|
7
|
+
#
|
8
|
+
# In practice a single line `do`...`end` is autocorrected when `EnforcedStyle: semantic`
|
9
|
+
# in `Style/BlockDelimiters`. The autocorrection maintains the `do` ... `end` syntax to
|
10
|
+
# preserve semantics and does not change it to `{`...`}` block.
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
#
|
14
|
+
# # bad
|
15
|
+
# foo do |arg| bar(arg) end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# foo do |arg|
|
19
|
+
# bar(arg)
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# ->(arg) do bar(arg) end
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# ->(arg) { bar(arg) }
|
27
|
+
#
|
28
|
+
class SingleLineDoEndBlock < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'Prefer multiline `do`...`end` block.'
|
32
|
+
|
33
|
+
def on_block(node)
|
34
|
+
return if !node.single_line? || node.braces?
|
35
|
+
|
36
|
+
add_offense(node) do |corrector|
|
37
|
+
corrector.insert_after(do_line(node), "\n")
|
38
|
+
|
39
|
+
node_body = node.body
|
40
|
+
|
41
|
+
if node_body.respond_to?(:heredoc?) && node_body.heredoc?
|
42
|
+
corrector.remove(node.loc.end)
|
43
|
+
corrector.insert_after(node_body.loc.heredoc_end, "\nend")
|
44
|
+
else
|
45
|
+
corrector.insert_after(node_body, "\n")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
alias on_numblock on_block
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def do_line(node)
|
54
|
+
if node.numblock_type? || node.arguments.children.empty? || node.send_node.lambda_literal?
|
55
|
+
node.loc.begin
|
56
|
+
else
|
57
|
+
node.arguments
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def x(corrector, node); end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -173,7 +173,9 @@ module RuboCop
|
|
173
173
|
end
|
174
174
|
|
175
175
|
def correct_for_comment(corrector, node, if_branch)
|
176
|
-
comments = processed_source.ast_with_comments[if_branch]
|
176
|
+
comments = processed_source.ast_with_comments[if_branch].select do |comment|
|
177
|
+
comment.loc.line < if_branch.condition.first_line
|
178
|
+
end
|
177
179
|
comment_text = comments.map(&:text).join("\n") << "\n"
|
178
180
|
|
179
181
|
corrector.insert_before(node.loc.keyword, comment_text) unless comments.empty?
|
@@ -50,6 +50,14 @@ module RuboCop
|
|
50
50
|
PERCENT_MSG = 'Use `%i` or `%I` for an array of symbols.'
|
51
51
|
ARRAY_MSG = 'Use %<prefer>s for an array of symbols.'
|
52
52
|
DELIMITERS = ['[', ']', '(', ')'].freeze
|
53
|
+
SPECIAL_GVARS = %w[
|
54
|
+
$! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
|
55
|
+
$-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
|
56
|
+
].freeze
|
57
|
+
REDEFINABLE_OPERATORS = %w(
|
58
|
+
| ^ & <=> == === =~ > >= < <= << >>
|
59
|
+
+ - * / % ** ~ +@ -@ [] []= ` ! != !~
|
60
|
+
).freeze
|
53
61
|
|
54
62
|
class << self
|
55
63
|
attr_accessor :largest_brackets
|
@@ -109,15 +117,6 @@ module RuboCop
|
|
109
117
|
end
|
110
118
|
|
111
119
|
def symbol_without_quote?(string)
|
112
|
-
special_gvars = %w[
|
113
|
-
$! $" $$ $& $' $* $+ $, $/ $; $: $. $< $= $> $? $@ $\\ $_ $` $~ $0
|
114
|
-
$-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w
|
115
|
-
]
|
116
|
-
redefinable_operators = %w(
|
117
|
-
| ^ & <=> == === =~ > >= < <= << >>
|
118
|
-
+ - * / % ** ~ +@ -@ [] []= ` ! != !~
|
119
|
-
)
|
120
|
-
|
121
120
|
# method name
|
122
121
|
/\A[a-zA-Z_]\w*[!?]?\z/.match?(string) ||
|
123
122
|
# instance / class variable
|
@@ -125,8 +124,8 @@ module RuboCop
|
|
125
124
|
# global variable
|
126
125
|
/\A\$[1-9]\d*\z/.match?(string) ||
|
127
126
|
/\A\$[a-zA-Z_]\w*\z/.match?(string) ||
|
128
|
-
|
129
|
-
|
127
|
+
SPECIAL_GVARS.include?(string) ||
|
128
|
+
REDEFINABLE_OPERATORS.include?(string)
|
130
129
|
end
|
131
130
|
end
|
132
131
|
end
|
@@ -19,22 +19,23 @@ module RuboCop
|
|
19
19
|
# differently on different classes, and are not guaranteed to
|
20
20
|
# have the same result if reversed.
|
21
21
|
#
|
22
|
-
# @example SupportedOperators: ['*', '+', '&'']
|
22
|
+
# @example SupportedOperators: ['*', '+', '&', '|', '^'] (default)
|
23
23
|
# # bad
|
24
|
-
# 1 + x
|
25
24
|
# 10 * y
|
25
|
+
# 1 + x
|
26
26
|
# 1 & z
|
27
|
+
# 1 | x
|
28
|
+
# 1 ^ x
|
27
29
|
# 1 + CONST
|
28
30
|
#
|
29
31
|
# # good
|
30
|
-
# 60 * 24
|
31
|
-
# x + 1
|
32
32
|
# y * 10
|
33
|
+
# x + 1
|
33
34
|
# z & 1
|
35
|
+
# x | 1
|
36
|
+
# x ^ 1
|
34
37
|
# CONST + 1
|
35
|
-
#
|
36
|
-
# # good
|
37
|
-
# 1 | x
|
38
|
+
# 60 * 24
|
38
39
|
#
|
39
40
|
class YodaExpression < Base
|
40
41
|
extend AutoCorrector
|
data/lib/rubocop/file_finder.rb
CHANGED
@@ -6,12 +6,8 @@ module RuboCop
|
|
6
6
|
# Common methods for finding files.
|
7
7
|
# @api private
|
8
8
|
module FileFinder
|
9
|
-
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.root_level?(path, stop_dir)
|
14
|
-
(@root_level || stop_dir) == path.to_s
|
9
|
+
class << self
|
10
|
+
attr_accessor :root_level
|
15
11
|
end
|
16
12
|
|
17
13
|
def find_file_upwards(filename, start_dir, stop_dir = nil)
|
@@ -34,7 +30,8 @@ module RuboCop
|
|
34
30
|
file = dir + filename
|
35
31
|
yield(file.to_s) if file.exist?
|
36
32
|
|
37
|
-
|
33
|
+
dir = dir.to_s
|
34
|
+
break if dir == stop_dir || dir == FileFinder.root_level
|
38
35
|
end
|
39
36
|
end
|
40
37
|
end
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
class MagicComment
|
8
8
|
# IRB's pattern for matching magic comment tokens.
|
9
9
|
# @see https://github.com/ruby/ruby/blob/b4a55c1/lib/irb/magic-file.rb#L5
|
10
|
-
TOKEN =
|
10
|
+
TOKEN = '(?<token>[[:alnum:]\-_]+)'
|
11
11
|
KEYWORDS = {
|
12
12
|
encoding: '(?:en)?coding',
|
13
13
|
frozen_string_literal: 'frozen[_-]string[_-]literal',
|
@@ -129,7 +129,7 @@ module RuboCop
|
|
129
129
|
# @return [String] if pattern matched
|
130
130
|
# @return [nil] otherwise
|
131
131
|
def extract(pattern)
|
132
|
-
@comment[pattern,
|
132
|
+
@comment[pattern, :token]
|
133
133
|
end
|
134
134
|
|
135
135
|
# Parent to Vim and Emacs magic comment handling.
|
@@ -157,10 +157,10 @@ module RuboCop
|
|
157
157
|
# @return [String] extracted value if it is found
|
158
158
|
# @return [nil] otherwise
|
159
159
|
def match(keyword)
|
160
|
-
pattern = /\A#{keyword}\s*#{self.class::OPERATOR}\s
|
160
|
+
pattern = /\A#{keyword}\s*#{self.class::OPERATOR}\s*#{TOKEN}\z/
|
161
161
|
|
162
162
|
tokens.each do |token|
|
163
|
-
next unless (value = token[pattern,
|
163
|
+
next unless (value = token[pattern, :token])
|
164
164
|
|
165
165
|
return value.downcase
|
166
166
|
end
|
@@ -188,7 +188,7 @@ module RuboCop
|
|
188
188
|
# @see https://www.gnu.org/software/emacs/manual/html_node/emacs/Specify-Coding.html
|
189
189
|
# @see https://github.com/ruby/ruby/blob/3f306dc/parse.y#L6873-L6892 Emacs handling in parse.y
|
190
190
|
class EmacsComment < EditorComment
|
191
|
-
REGEXP = /-\*-(
|
191
|
+
REGEXP = /-\*-(?<token>.+)-\*-/.freeze
|
192
192
|
FORMAT = '# -*- %s -*-'
|
193
193
|
SEPARATOR = ';'
|
194
194
|
OPERATOR = ':'
|
@@ -216,7 +216,7 @@ module RuboCop
|
|
216
216
|
#
|
217
217
|
# comment.encoding # => 'ascii-8bit'
|
218
218
|
class VimComment < EditorComment
|
219
|
-
REGEXP = /#\s*vim:\s*(
|
219
|
+
REGEXP = /#\s*vim:\s*(?<token>.+)/.freeze
|
220
220
|
FORMAT = '# vim: %s'
|
221
221
|
SEPARATOR = ', '
|
222
222
|
OPERATOR = '='
|
@@ -259,9 +259,11 @@ module RuboCop
|
|
259
259
|
# comment2.frozen_string_literal # => nil
|
260
260
|
# comment2.encoding # => 'utf-8'
|
261
261
|
class SimpleComment < MagicComment
|
262
|
+
FSTRING_LITERAL_COMMENT = 'frozen_string_literal:\s*(true|false)'
|
263
|
+
|
262
264
|
# Match `encoding` or `coding`
|
263
265
|
def encoding
|
264
|
-
extract(/\A\s
|
266
|
+
extract(/\A\s*\#\s*(#{FSTRING_LITERAL_COMMENT})?\s*#{KEYWORDS[:encoding]}: (#{TOKEN})/io)
|
265
267
|
end
|
266
268
|
|
267
269
|
# Rewrite the comment without a given token type
|
@@ -283,15 +285,15 @@ module RuboCop
|
|
283
285
|
# Case-insensitive and dashes/underscores are acceptable.
|
284
286
|
# @see https://github.com/ruby/ruby/blob/78b95b4/parse.y#L7134-L7138
|
285
287
|
def extract_frozen_string_literal
|
286
|
-
extract(/\A\s*#\s*#{KEYWORDS[:frozen_string_literal]}:\s
|
288
|
+
extract(/\A\s*#\s*#{KEYWORDS[:frozen_string_literal]}:\s*#{TOKEN}\s*\z/io)
|
287
289
|
end
|
288
290
|
|
289
291
|
def extract_shareable_constant_value
|
290
|
-
extract(/\A\s*#\s*#{KEYWORDS[:shareable_constant_value]}:\s
|
292
|
+
extract(/\A\s*#\s*#{KEYWORDS[:shareable_constant_value]}:\s*#{TOKEN}\s*\z/io)
|
291
293
|
end
|
292
294
|
|
293
295
|
def extract_typed
|
294
|
-
extract(/\A\s*#\s*#{KEYWORDS[:typed]}:\s
|
296
|
+
extract(/\A\s*#\s*#{KEYWORDS[:typed]}:\s*#{TOKEN}\s*\z/io)
|
295
297
|
end
|
296
298
|
end
|
297
299
|
end
|
@@ -11,6 +11,8 @@ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLe
|
|
11
11
|
# Make sure to expand all symlinks in the path first. Otherwise we may
|
12
12
|
# get mismatched pathnames when loading config files later on.
|
13
13
|
tmpdir = File.realpath(tmpdir)
|
14
|
+
# Make upwards search for .rubocop.yml files stop at this directory.
|
15
|
+
RuboCop::FileFinder.root_level = tmpdir
|
14
16
|
|
15
17
|
virtual_home = File.expand_path(File.join(tmpdir, 'home'))
|
16
18
|
Dir.mkdir(virtual_home)
|
@@ -21,9 +23,6 @@ RSpec.shared_context 'isolated environment' do # rubocop:disable Metrics/BlockLe
|
|
21
23
|
root = example.metadata[:root]
|
22
24
|
working_dir = root ? File.join(base_dir, 'work', root) : File.join(base_dir, 'work')
|
23
25
|
|
24
|
-
# Make upwards search for .rubocop.yml files stop at this directory.
|
25
|
-
RuboCop::FileFinder.root_level = working_dir
|
26
|
-
|
27
26
|
begin
|
28
27
|
FileUtils.mkdir_p(working_dir)
|
29
28
|
|
data/lib/rubocop/server/cache.rb
CHANGED
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -580,6 +580,7 @@ require_relative 'rubocop/cop/style/redundant_regexp_constructor'
|
|
580
580
|
require_relative 'rubocop/cop/style/redundant_self_assignment'
|
581
581
|
require_relative 'rubocop/cop/style/redundant_self_assignment_branch'
|
582
582
|
require_relative 'rubocop/cop/style/require_order'
|
583
|
+
require_relative 'rubocop/cop/style/single_line_do_end_block'
|
583
584
|
require_relative 'rubocop/cop/style/sole_nested_conditional'
|
584
585
|
require_relative 'rubocop/cop/style/static_class'
|
585
586
|
require_relative 'rubocop/cop/style/map_compact_with_conditional_block'
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubocop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.57.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bozhidar Batsov
|
8
8
|
- Jonas Arvidsson
|
9
9
|
- Yuji Nakayama
|
10
|
-
autorequire:
|
10
|
+
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2023-
|
13
|
+
date: 2023-10-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: base64
|
@@ -74,14 +74,14 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 3.2.2.
|
77
|
+
version: 3.2.2.4
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
82
|
- - ">="
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: 3.2.2.
|
84
|
+
version: 3.2.2.4
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
name: rainbow
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
@@ -895,6 +895,7 @@ files:
|
|
895
895
|
- lib/rubocop/cop/style/signal_exception.rb
|
896
896
|
- lib/rubocop/cop/style/single_argument_dig.rb
|
897
897
|
- lib/rubocop/cop/style/single_line_block_params.rb
|
898
|
+
- lib/rubocop/cop/style/single_line_do_end_block.rb
|
898
899
|
- lib/rubocop/cop/style/single_line_methods.rb
|
899
900
|
- lib/rubocop/cop/style/slicing_with_range.rb
|
900
901
|
- lib/rubocop/cop/style/sole_nested_conditional.rb
|
@@ -1038,10 +1039,10 @@ metadata:
|
|
1038
1039
|
homepage_uri: https://rubocop.org/
|
1039
1040
|
changelog_uri: https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md
|
1040
1041
|
source_code_uri: https://github.com/rubocop/rubocop/
|
1041
|
-
documentation_uri: https://docs.rubocop.org/rubocop/1.
|
1042
|
+
documentation_uri: https://docs.rubocop.org/rubocop/1.57/
|
1042
1043
|
bug_tracker_uri: https://github.com/rubocop/rubocop/issues
|
1043
1044
|
rubygems_mfa_required: 'true'
|
1044
|
-
post_install_message:
|
1045
|
+
post_install_message:
|
1045
1046
|
rdoc_options: []
|
1046
1047
|
require_paths:
|
1047
1048
|
- lib
|
@@ -1056,8 +1057,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1056
1057
|
- !ruby/object:Gem::Version
|
1057
1058
|
version: '0'
|
1058
1059
|
requirements: []
|
1059
|
-
rubygems_version: 3.
|
1060
|
-
signing_key:
|
1060
|
+
rubygems_version: 3.3.7
|
1061
|
+
signing_key:
|
1061
1062
|
specification_version: 4
|
1062
1063
|
summary: Automatic Ruby code style checking tool.
|
1063
1064
|
test_files: []
|