rubocop 1.25.0 → 1.26.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 +25 -15
- data/lib/rubocop/cli.rb +1 -1
- data/lib/rubocop/cop/badge.rb +7 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +4 -3
- data/lib/rubocop/cop/generator.rb +2 -7
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +46 -0
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- 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/multiline_operation_indentation.rb +7 -8
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- data/lib/rubocop/cop/lint/inherit_exception.rb +19 -28
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +3 -2
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +5 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +3 -2
- data/lib/rubocop/cop/lint/useless_times.rb +13 -9
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +27 -13
- data/lib/rubocop/cop/mixin/line_length_help.rb +17 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +3 -1
- data/lib/rubocop/cop/naming/method_parameter_name.rb +1 -1
- data/lib/rubocop/cop/security/yaml_load.rb +9 -3
- data/lib/rubocop/cop/style/def_with_parentheses.rb +16 -11
- data/lib/rubocop/cop/style/for.rb +4 -0
- data/lib/rubocop/cop/style/lambda_call.rb +12 -20
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +11 -5
- data/lib/rubocop/cop/style/nested_file_dirname.rb +66 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +3 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -6
- data/lib/rubocop/cop/style/select_by_regexp.rb +6 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +50 -12
- data/lib/rubocop/cop/style/string_concatenation.rb +7 -1
- data/lib/rubocop/cop/style/swap_values.rb +2 -0
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +1 -1
- data/lib/rubocop/cop/style/unless_else.rb +4 -0
- data/lib/rubocop/cop/variable_force.rb +1 -5
- data/lib/rubocop/cops_documentation_generator.rb +2 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +16 -2
- data/lib/rubocop/options.rb +8 -2
- data/lib/rubocop/rspec/shared_contexts.rb +4 -0
- data/lib/rubocop/runner.rb +1 -1
- data/lib/rubocop/target_ruby.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +1 -0
- metadata +7 -5
@@ -7,17 +7,21 @@ module RuboCop
|
|
7
7
|
# potential security issues leading to remote code execution when
|
8
8
|
# loading from an untrusted source.
|
9
9
|
#
|
10
|
+
# NOTE: Ruby 3.1+ (Psych 4) uses `Psych.load` as `Psych.safe_load` by default.
|
11
|
+
#
|
10
12
|
# @safety
|
11
13
|
# The behaviour of the code might change depending on what was
|
12
14
|
# in the YAML payload, since `YAML.safe_load` is more restrictive.
|
13
15
|
#
|
14
16
|
# @example
|
15
17
|
# # bad
|
16
|
-
# YAML.load("---
|
18
|
+
# YAML.load("--- !ruby/object:Foo {}") # Psych 3 is unsafe by default
|
17
19
|
#
|
18
20
|
# # good
|
19
|
-
# YAML.safe_load("---
|
20
|
-
# YAML.
|
21
|
+
# YAML.safe_load("--- !ruby/object:Foo {}", [Foo]) # Ruby 2.5 (Psych 3)
|
22
|
+
# YAML.safe_load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.0- (Psych 3)
|
23
|
+
# YAML.load("--- !ruby/object:Foo {}", permitted_classes: [Foo]) # Ruby 3.1+ (Psych 4)
|
24
|
+
# YAML.dump(foo)
|
21
25
|
#
|
22
26
|
class YAMLLoad < Base
|
23
27
|
extend AutoCorrector
|
@@ -31,6 +35,8 @@ module RuboCop
|
|
31
35
|
PATTERN
|
32
36
|
|
33
37
|
def on_send(node)
|
38
|
+
return if target_ruby_version >= 3.1
|
39
|
+
|
34
40
|
yaml_load(node) do
|
35
41
|
add_offense(node.loc.selector) do |corrector|
|
36
42
|
corrector.replace(node.loc.selector, 'safe_load')
|
@@ -11,27 +11,33 @@ module RuboCop
|
|
11
11
|
#
|
12
12
|
# # bad
|
13
13
|
# def foo()
|
14
|
-
#
|
14
|
+
# do_something
|
15
15
|
# end
|
16
16
|
#
|
17
17
|
# # good
|
18
18
|
# def foo
|
19
|
-
#
|
19
|
+
# do_something
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
# #
|
23
|
-
# def foo()
|
22
|
+
# # bad
|
23
|
+
# def foo() = do_something
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# def foo = do_something
|
27
|
+
#
|
28
|
+
# # good (without parentheses it's a syntax error)
|
29
|
+
# def foo() do_something end
|
24
30
|
#
|
25
31
|
# @example
|
26
32
|
#
|
27
33
|
# # bad
|
28
34
|
# def Baz.foo()
|
29
|
-
#
|
35
|
+
# do_something
|
30
36
|
# end
|
31
37
|
#
|
32
38
|
# # good
|
33
39
|
# def Baz.foo
|
34
|
-
#
|
40
|
+
# do_something
|
35
41
|
# end
|
36
42
|
class DefWithParentheses < Base
|
37
43
|
extend AutoCorrector
|
@@ -39,12 +45,11 @@ module RuboCop
|
|
39
45
|
MSG = "Omit the parentheses in defs when the method doesn't accept any arguments."
|
40
46
|
|
41
47
|
def on_def(node)
|
42
|
-
return if node.single_line?
|
43
|
-
return unless !node.arguments? && (
|
48
|
+
return if node.single_line? && !node.endless?
|
49
|
+
return unless !node.arguments? && (node_arguments = node.arguments.source_range)
|
44
50
|
|
45
|
-
add_offense(
|
46
|
-
corrector.remove(
|
47
|
-
corrector.remove(node.arguments.loc.end)
|
51
|
+
add_offense(node_arguments) do |corrector|
|
52
|
+
corrector.remove(node_arguments)
|
48
53
|
end
|
49
54
|
end
|
50
55
|
alias on_defs on_def
|
@@ -22,45 +22,37 @@ module RuboCop
|
|
22
22
|
include ConfigurableEnforcedStyle
|
23
23
|
extend AutoCorrector
|
24
24
|
|
25
|
+
MSG = 'Prefer the use of `%<prefer>s` over `%<current>s`.'
|
25
26
|
RESTRICT_ON_SEND = %i[call].freeze
|
26
27
|
|
27
28
|
def on_send(node)
|
28
29
|
return unless node.receiver
|
29
30
|
|
30
31
|
if offense?(node)
|
31
|
-
|
32
|
+
prefer = prefer(node)
|
33
|
+
current = node.source
|
34
|
+
|
35
|
+
add_offense(node, message: format(MSG, prefer: prefer, current: current)) do |corrector|
|
32
36
|
opposite_style_detected
|
33
|
-
|
37
|
+
corrector.replace(node, prefer)
|
34
38
|
end
|
35
39
|
else
|
36
40
|
correct_style_detected
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
40
|
-
def autocorrect(corrector, node)
|
41
|
-
if explicit_style?
|
42
|
-
receiver = node.receiver.source
|
43
|
-
replacement = node.source.sub("#{receiver}.", "#{receiver}.call")
|
44
|
-
|
45
|
-
corrector.replace(node, replacement)
|
46
|
-
else
|
47
|
-
add_parentheses(node, corrector) unless node.parenthesized?
|
48
|
-
corrector.remove(node.loc.selector)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
44
|
private
|
53
45
|
|
54
46
|
def offense?(node)
|
55
47
|
(explicit_style? && node.implicit_call?) || (implicit_style? && !node.implicit_call?)
|
56
48
|
end
|
57
49
|
|
58
|
-
def
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
50
|
+
def prefer(node)
|
51
|
+
receiver = node.receiver.source
|
52
|
+
arguments = node.arguments.map(&:source).join(', ')
|
53
|
+
method = explicit_style? ? "call(#{arguments})" : "(#{arguments})"
|
54
|
+
|
55
|
+
"#{receiver}.#{method}"
|
64
56
|
end
|
65
57
|
|
66
58
|
def implicit_style?
|
@@ -48,15 +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
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
|
-
|
57
|
-
|
55
|
+
modifier_form?(node) || exist_next_line_expression?(node)
|
56
|
+
end
|
58
57
|
|
59
|
-
|
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
|
60
66
|
end
|
61
67
|
|
62
68
|
def syntax_like_method_call?(node)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for nested `File.dirname`.
|
7
|
+
# It replaces nested `File.dirname` with the level argument introduced in Ruby 3.1.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# File.dirname(File.dirname(path))
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# File.dirname(path, 2)
|
16
|
+
#
|
17
|
+
class NestedFileDirname < Base
|
18
|
+
include RangeHelp
|
19
|
+
extend AutoCorrector
|
20
|
+
extend TargetRubyVersion
|
21
|
+
|
22
|
+
MSG = 'Use `dirname(%<path>s, %<level>s)` instead.'
|
23
|
+
RESTRICT_ON_SEND = %i[dirname].freeze
|
24
|
+
|
25
|
+
minimum_target_ruby_version 3.1
|
26
|
+
|
27
|
+
# @!method file_dirname?(node)
|
28
|
+
def_node_matcher :file_dirname?, <<~PATTERN
|
29
|
+
(send
|
30
|
+
(const {cbase nil?} :File) :dirname ...)
|
31
|
+
PATTERN
|
32
|
+
|
33
|
+
def on_send(node)
|
34
|
+
return if file_dirname?(node.parent) || !file_dirname?(node.first_argument)
|
35
|
+
|
36
|
+
path, level = path_with_dir_level(node, 1)
|
37
|
+
return if level < 2
|
38
|
+
|
39
|
+
message = format(MSG, path: path, level: level)
|
40
|
+
range = offense_range(node)
|
41
|
+
|
42
|
+
add_offense(range, message: message) do |corrector|
|
43
|
+
corrector.replace(range, "dirname(#{path}, #{level})")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def path_with_dir_level(node, level)
|
50
|
+
first_argument = node.first_argument
|
51
|
+
|
52
|
+
if file_dirname?(first_argument)
|
53
|
+
level += 1
|
54
|
+
path_with_dir_level(first_argument, level)
|
55
|
+
else
|
56
|
+
[first_argument.source, level]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def offense_range(node)
|
61
|
+
range_between(node.loc.selector.begin_pos, node.source_range.end_pos)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -54,8 +54,9 @@ module RuboCop
|
|
54
54
|
private
|
55
55
|
|
56
56
|
def format_message(argument)
|
57
|
-
|
58
|
-
|
57
|
+
replacement = "#{argument.name}: #{argument.default_value.source}"
|
58
|
+
|
59
|
+
format(MSG, original: argument.source, replacement: replacement)
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
@@ -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
|
@@ -69,6 +69,11 @@ module RuboCop
|
|
69
69
|
}
|
70
70
|
PATTERN
|
71
71
|
|
72
|
+
# @!method env_const?(node)
|
73
|
+
def_node_matcher :env_const?, <<~PATTERN
|
74
|
+
(const {nil? cbase} :ENV)
|
75
|
+
PATTERN
|
76
|
+
|
72
77
|
# @!method calls_lvar?(node, name)
|
73
78
|
def_node_matcher :calls_lvar?, <<~PATTERN
|
74
79
|
{
|
@@ -94,7 +99,7 @@ module RuboCop
|
|
94
99
|
def receiver_allowed?(node)
|
95
100
|
return false unless node
|
96
101
|
|
97
|
-
node.hash_type? || creates_hash?(node)
|
102
|
+
node.hash_type? || creates_hash?(node) || env_const?(node)
|
98
103
|
end
|
99
104
|
|
100
105
|
def register_offense(node, block_node, regexp)
|
@@ -15,6 +15,11 @@ module RuboCop
|
|
15
15
|
# end
|
16
16
|
# end
|
17
17
|
#
|
18
|
+
# # bad
|
19
|
+
# if condition_b
|
20
|
+
# do_something
|
21
|
+
# end if condition_a
|
22
|
+
#
|
18
23
|
# # good
|
19
24
|
# if condition_a && condition_b
|
20
25
|
# do_something
|
@@ -26,12 +31,21 @@ module RuboCop
|
|
26
31
|
# do_something if condition_b
|
27
32
|
# end
|
28
33
|
#
|
34
|
+
# # bad
|
35
|
+
# if condition_b
|
36
|
+
# do_something
|
37
|
+
# end if condition_a
|
38
|
+
#
|
29
39
|
# @example AllowModifier: true
|
30
40
|
# # good
|
31
41
|
# if condition_a
|
32
42
|
# do_something if condition_b
|
33
43
|
# end
|
34
44
|
#
|
45
|
+
# # good
|
46
|
+
# if condition_b
|
47
|
+
# do_something
|
48
|
+
# end if condition_a
|
35
49
|
class SoleNestedConditional < Base
|
36
50
|
include RangeHelp
|
37
51
|
extend AutoCorrector
|
@@ -47,7 +61,7 @@ module RuboCop
|
|
47
61
|
|
48
62
|
if_branch = node.if_branch
|
49
63
|
return if use_variable_assignment_in_condition?(node.condition, if_branch)
|
50
|
-
return unless offending_branch?(if_branch)
|
64
|
+
return unless offending_branch?(node, if_branch)
|
51
65
|
|
52
66
|
message = format(MSG, conditional_type: node.keyword)
|
53
67
|
add_offense(if_branch.loc.keyword, message: message) do |corrector|
|
@@ -72,13 +86,13 @@ module RuboCop
|
|
72
86
|
end
|
73
87
|
end
|
74
88
|
|
75
|
-
def offending_branch?(branch)
|
89
|
+
def offending_branch?(node, branch)
|
76
90
|
return false unless branch
|
77
91
|
|
78
92
|
branch.if_type? &&
|
79
93
|
!branch.else? &&
|
80
94
|
!branch.ternary? &&
|
81
|
-
!(branch.modifier_form? && allow_modifier?)
|
95
|
+
!((node.modifier_form? || branch.modifier_form?) && allow_modifier?)
|
82
96
|
end
|
83
97
|
|
84
98
|
def autocorrect(corrector, node, if_branch)
|
@@ -86,6 +100,14 @@ module RuboCop
|
|
86
100
|
corrector.wrap(node.condition, '(', ')')
|
87
101
|
end
|
88
102
|
|
103
|
+
if outer_condition_modify_form?(node, if_branch)
|
104
|
+
autocorrect_outer_condition_modify_form(corrector, node, if_branch)
|
105
|
+
else
|
106
|
+
autocorrect_outer_condition_basic(corrector, node, if_branch)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def autocorrect_outer_condition_basic(corrector, node, if_branch)
|
89
111
|
correct_from_unless_to_if(corrector, node) if node.unless?
|
90
112
|
|
91
113
|
and_operator = if_branch.unless? ? ' && !' : ' && '
|
@@ -97,11 +119,17 @@ module RuboCop
|
|
97
119
|
end
|
98
120
|
end
|
99
121
|
|
100
|
-
def
|
122
|
+
def autocorrect_outer_condition_modify_form(corrector, node, if_branch)
|
123
|
+
correct_from_unless_to_if(corrector, if_branch, is_modify_form: true) if if_branch.unless?
|
124
|
+
correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
|
125
|
+
end
|
126
|
+
|
127
|
+
def correct_from_unless_to_if(corrector, node, is_modify_form: false)
|
101
128
|
corrector.replace(node.loc.keyword, 'if')
|
102
129
|
|
103
130
|
condition = node.condition
|
104
|
-
if condition.send_type? && condition.comparison_method? && !condition.parenthesized?
|
131
|
+
if (condition.send_type? && condition.comparison_method? && !condition.parenthesized?) ||
|
132
|
+
(is_modify_form && wrap_condition?(condition))
|
105
133
|
corrector.wrap(node.condition, '!(', ')')
|
106
134
|
else
|
107
135
|
corrector.insert_before(node.condition, '!')
|
@@ -113,7 +141,7 @@ module RuboCop
|
|
113
141
|
correct_outer_condition(corrector, outer_condition)
|
114
142
|
|
115
143
|
condition = if_branch.condition
|
116
|
-
corrector.insert_after(outer_condition,
|
144
|
+
corrector.insert_after(outer_condition, "#{and_operator}#{replace_condition(condition)}")
|
117
145
|
|
118
146
|
range = range_between(if_branch.loc.keyword.begin_pos, condition.source_range.end_pos)
|
119
147
|
corrector.remove(range_with_surrounding_space(range: range, newlines: false))
|
@@ -129,6 +157,16 @@ module RuboCop
|
|
129
157
|
corrector.wrap(if_branch.condition, '(', ')') if wrap_condition?(if_branch.condition)
|
130
158
|
end
|
131
159
|
|
160
|
+
def correct_for_outer_condition_modify_form_style(corrector, node, if_branch)
|
161
|
+
condition = if_branch.condition
|
162
|
+
corrector.insert_before(condition,
|
163
|
+
"#{'!' if node.unless?}#{replace_condition(node.condition)} && ")
|
164
|
+
|
165
|
+
corrector.remove(node.condition.loc.expression)
|
166
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.keyword, newlines: false))
|
167
|
+
corrector.replace(if_branch.loc.keyword, 'if')
|
168
|
+
end
|
169
|
+
|
132
170
|
def correct_for_comment(corrector, node, if_branch)
|
133
171
|
return if config.for_cop('Style/IfUnlessModifier')['Enabled']
|
134
172
|
|
@@ -165,17 +203,17 @@ module RuboCop
|
|
165
203
|
(node.send_type? && node.arguments.any? && !node.parenthesized?)
|
166
204
|
end
|
167
205
|
|
168
|
-
def
|
169
|
-
|
170
|
-
"#{and_operator}(#{condition.source})"
|
171
|
-
else
|
172
|
-
"#{and_operator}#{condition.source}"
|
173
|
-
end
|
206
|
+
def replace_condition(condition)
|
207
|
+
wrap_condition?(condition) ? "(#{condition.source})" : condition.source
|
174
208
|
end
|
175
209
|
|
176
210
|
def allow_modifier?
|
177
211
|
cop_config['AllowModifier']
|
178
212
|
end
|
213
|
+
|
214
|
+
def outer_condition_modify_form?(node, if_branch)
|
215
|
+
node.condition.loc.expression.begin_pos > if_branch.condition.loc.expression.begin_pos
|
216
|
+
end
|
179
217
|
end
|
180
218
|
end
|
181
219
|
end
|
@@ -134,7 +134,13 @@ module RuboCop
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def uncorrectable?(part)
|
137
|
-
part.multiline? || (part
|
137
|
+
part.multiline? || heredoc?(part) || part.each_descendant(:block).any?
|
138
|
+
end
|
139
|
+
|
140
|
+
def heredoc?(node)
|
141
|
+
return false unless node.str_type? || node.dstr_type?
|
142
|
+
|
143
|
+
node.heredoc?
|
138
144
|
end
|
139
145
|
|
140
146
|
def corrected_ancestor?(node)
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# last item of all non-empty, multiline array literals.
|
11
11
|
# * `comma`: Requires a comma after last item in an array,
|
12
12
|
# but only when each item is on its own line.
|
13
|
-
# * `no_comma`: Does not
|
13
|
+
# * `no_comma`: Does not require a comma after the
|
14
14
|
# last item in an array
|
15
15
|
#
|
16
16
|
# @example EnforcedStyleForMultiline: consistent_comma
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
# last item of all non-empty, multiline hash literals.
|
11
11
|
# * `comma`: Requires a comma after the last item in a hash,
|
12
12
|
# but only when each item is on its own line.
|
13
|
-
# * `no_comma`: Does not
|
13
|
+
# * `no_comma`: Does not require a comma after the
|
14
14
|
# last item in a hash
|
15
15
|
#
|
16
16
|
# @example EnforcedStyleForMultiline: consistent_comma
|
@@ -32,10 +32,14 @@ module RuboCop
|
|
32
32
|
body_range = range_between_condition_and_else(node, node.condition)
|
33
33
|
else_range = range_between_else_and_end(node)
|
34
34
|
|
35
|
+
next if part_of_ignored_node?(node)
|
36
|
+
|
35
37
|
corrector.replace(node.loc.keyword, 'if')
|
36
38
|
corrector.replace(body_range, else_range.source)
|
37
39
|
corrector.replace(else_range, body_range.source)
|
38
40
|
end
|
41
|
+
|
42
|
+
ignore_node(node)
|
39
43
|
end
|
40
44
|
|
41
45
|
def range_between_condition_and_else(node, condition)
|
@@ -186,11 +186,7 @@ module RuboCop
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def regexp_captured_names(node)
|
189
|
-
|
190
|
-
child.children.first
|
191
|
-
end.join || ''
|
192
|
-
|
193
|
-
regexp = Regexp.new(regexp_string)
|
189
|
+
regexp = node.to_regexp
|
194
190
|
|
195
191
|
regexp.named_captures.keys
|
196
192
|
end
|
@@ -191,8 +191,8 @@ class CopsDocumentationGenerator # rubocop:disable Metrics/ClassLength
|
|
191
191
|
|
192
192
|
def wrap_backtick(value)
|
193
193
|
if value.is_a?(String)
|
194
|
-
# Use `+` to prevent text like `**/*.gemspec` from being bold.
|
195
|
-
value.
|
194
|
+
# Use `+` to prevent text like `**/*.gemspec`, `spec/**/*` from being bold.
|
195
|
+
value.include?('*') ? "`+#{value}+`" : "`#{value}`"
|
196
196
|
else
|
197
197
|
"`#{value}`"
|
198
198
|
end
|
@@ -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 '# This cop supports safe auto-correction (--auto-correct).'
|
128
|
+
elsif supports_unsafe_autocorrect?(cop_class, default_cfg)
|
129
|
+
output_buffer.puts '# This cop supports unsafe auto-correction (--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/options.rb
CHANGED
@@ -467,8 +467,14 @@ module RuboCop
|
|
467
467
|
'This option applies to the previously',
|
468
468
|
'specified --format, or the default format',
|
469
469
|
'if no format is specified.'],
|
470
|
-
fail_level: ['Minimum severity
|
471
|
-
'
|
470
|
+
fail_level: ['Minimum severity for exit with error code.',
|
471
|
+
' [A] autocorrect',
|
472
|
+
' [I] info',
|
473
|
+
' [R] refactor',
|
474
|
+
' [C] convention',
|
475
|
+
' [W] warning',
|
476
|
+
' [E] error',
|
477
|
+
' [F] fatal'],
|
472
478
|
display_time: 'Display elapsed time in seconds.',
|
473
479
|
display_only_failed: ['Only output offense messages. Omit passing',
|
474
480
|
'cops. Only valid for --format junit.'],
|
data/lib/rubocop/runner.rb
CHANGED
@@ -8,7 +8,7 @@ module RuboCop
|
|
8
8
|
class Runner # rubocop:disable Metrics/ClassLength
|
9
9
|
# An exception indicating that the inspection loop got stuck correcting
|
10
10
|
# offenses back and forth.
|
11
|
-
class InfiniteCorrectionLoop <
|
11
|
+
class InfiniteCorrectionLoop < StandardError
|
12
12
|
attr_reader :offenses
|
13
13
|
|
14
14
|
def initialize(path, offenses_by_iteration, loop_start: -1)
|
data/lib/rubocop/target_ruby.rb
CHANGED
@@ -4,7 +4,7 @@ module RuboCop
|
|
4
4
|
# The kind of Ruby that code inspected by RuboCop is written in.
|
5
5
|
# @api private
|
6
6
|
class TargetRuby
|
7
|
-
KNOWN_RUBIES = [2.5, 2.6, 2.7, 3.0, 3.1].freeze
|
7
|
+
KNOWN_RUBIES = [2.5, 2.6, 2.7, 3.0, 3.1, 3.2].freeze
|
8
8
|
DEFAULT_VERSION = KNOWN_RUBIES.first
|
9
9
|
|
10
10
|
OBSOLETE_RUBIES = {
|
data/lib/rubocop/version.rb
CHANGED
data/lib/rubocop.rb
CHANGED
@@ -552,6 +552,7 @@ require_relative 'rubocop/cop/style/negated_if'
|
|
552
552
|
require_relative 'rubocop/cop/style/negated_if_else_condition'
|
553
553
|
require_relative 'rubocop/cop/style/negated_unless'
|
554
554
|
require_relative 'rubocop/cop/style/negated_while'
|
555
|
+
require_relative 'rubocop/cop/style/nested_file_dirname'
|
555
556
|
require_relative 'rubocop/cop/style/nested_modifier'
|
556
557
|
require_relative 'rubocop/cop/style/nested_parenthesized_calls'
|
557
558
|
require_relative 'rubocop/cop/style/nested_ternary_operator'
|