rubocop 1.50.1 → 1.51.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/README.md +3 -3
- data/config/default.yml +20 -3
- data/lib/rubocop/config.rb +4 -0
- data/lib/rubocop/config_obsoletion.rb +2 -2
- data/lib/rubocop/cop/base.rb +4 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +1 -1
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +1 -1
- data/lib/rubocop/cop/gemspec/development_dependencies.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +25 -34
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +7 -19
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +42 -52
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +38 -55
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/multiline_array_line_breaks.rb +8 -27
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +7 -26
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +4 -21
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +6 -30
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +2 -0
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +12 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +2 -2
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +5 -2
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +1 -1
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +2 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +23 -9
- data/lib/rubocop/cop/lint/useless_assignment.rb +56 -1
- data/lib/rubocop/cop/lint/void.rb +62 -6
- data/lib/rubocop/cop/mixin/comments_help.rb +6 -2
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +22 -7
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +11 -3
- data/lib/rubocop/cop/style/attr.rb +11 -1
- data/lib/rubocop/cop/style/collection_compact.rb +13 -6
- data/lib/rubocop/cop/style/colon_method_call.rb +2 -2
- data/lib/rubocop/cop/style/combinable_loops.rb +26 -6
- data/lib/rubocop/cop/style/conditional_assignment.rb +2 -2
- data/lib/rubocop/cop/style/copyright.rb +5 -2
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +62 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +19 -8
- data/lib/rubocop/cop/style/if_inside_else.rb +6 -0
- data/lib/rubocop/cop/style/if_unless_modifier.rb +3 -0
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +9 -5
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +6 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +5 -1
- data/lib/rubocop/cop/style/regexp_literal.rb +11 -2
- data/lib/rubocop/cop/style/require_order.rb +9 -4
- data/lib/rubocop/cop/style/semicolon.rb +12 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +2 -2
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +4 -0
- data/lib/rubocop/cop/variable_force/variable_table.rb +2 -2
- data/lib/rubocop/result_cache.rb +1 -1
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/target_ruby.rb +3 -2
- data/lib/rubocop/version.rb +3 -3
- data/lib/rubocop.rb +1 -0
- metadata +5 -4
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Ensures that each key in a multi-line hash
|
|
7
7
|
# starts on a separate line.
|
|
8
8
|
#
|
|
9
|
-
# @example
|
|
9
|
+
# @example
|
|
10
10
|
#
|
|
11
11
|
# # bad
|
|
12
12
|
# {
|
|
@@ -14,11 +14,6 @@ module RuboCop
|
|
|
14
14
|
# c: 3
|
|
15
15
|
# }
|
|
16
16
|
#
|
|
17
|
-
# # bad
|
|
18
|
-
# { a: 1, b: {
|
|
19
|
-
# c: 3,
|
|
20
|
-
# }}
|
|
21
|
-
#
|
|
22
17
|
# # good
|
|
23
18
|
# {
|
|
24
19
|
# a: 1,
|
|
@@ -34,34 +29,20 @@ module RuboCop
|
|
|
34
29
|
# }
|
|
35
30
|
# }
|
|
36
31
|
#
|
|
37
|
-
# @example AllowMultilineFinalElement:
|
|
32
|
+
# @example AllowMultilineFinalElement: false (default)
|
|
38
33
|
#
|
|
39
34
|
# # bad
|
|
40
|
-
# {
|
|
41
|
-
# a: 1, b: 2,
|
|
42
|
-
# c: 3
|
|
43
|
-
# }
|
|
44
|
-
#
|
|
45
|
-
# # good
|
|
46
35
|
# { a: 1, b: {
|
|
47
36
|
# c: 3,
|
|
48
37
|
# }}
|
|
49
38
|
#
|
|
50
|
-
#
|
|
51
|
-
# {
|
|
52
|
-
# a: 1,
|
|
53
|
-
# b: 2,
|
|
54
|
-
# c: 3
|
|
55
|
-
# }
|
|
56
|
-
#
|
|
39
|
+
# @example AllowMultilineFinalElement: true
|
|
57
40
|
#
|
|
58
41
|
# # good
|
|
59
|
-
# {
|
|
60
|
-
#
|
|
61
|
-
#
|
|
62
|
-
#
|
|
63
|
-
# }
|
|
64
|
-
# }
|
|
42
|
+
# { a: 1, b: {
|
|
43
|
+
# c: 3,
|
|
44
|
+
# }}
|
|
45
|
+
#
|
|
65
46
|
class MultilineHashKeyLineBreaks < Base
|
|
66
47
|
include MultilineElementLineBreaks
|
|
67
48
|
extend AutoCorrector
|
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
|
9
9
|
# NOTE: This cop does not move the first argument, if you want that to
|
|
10
10
|
# be on a separate line, see `Layout/FirstMethodArgumentLineBreak`.
|
|
11
11
|
#
|
|
12
|
-
# @example
|
|
12
|
+
# @example
|
|
13
13
|
#
|
|
14
14
|
# # bad
|
|
15
15
|
# foo(a, b,
|
|
@@ -31,6 +31,8 @@ module RuboCop
|
|
|
31
31
|
# # good
|
|
32
32
|
# foo(a, b, c)
|
|
33
33
|
#
|
|
34
|
+
# @example AllowMultilineFinalElement: false (default)
|
|
35
|
+
#
|
|
34
36
|
# # good
|
|
35
37
|
# foo(
|
|
36
38
|
# a,
|
|
@@ -42,26 +44,6 @@ module RuboCop
|
|
|
42
44
|
#
|
|
43
45
|
# @example AllowMultilineFinalElement: true
|
|
44
46
|
#
|
|
45
|
-
# # bad
|
|
46
|
-
# foo(a, b,
|
|
47
|
-
# c
|
|
48
|
-
# )
|
|
49
|
-
#
|
|
50
|
-
# # good
|
|
51
|
-
# foo(a, b, {
|
|
52
|
-
# foo: "bar",
|
|
53
|
-
# })
|
|
54
|
-
#
|
|
55
|
-
# # good
|
|
56
|
-
# foo(
|
|
57
|
-
# a,
|
|
58
|
-
# b,
|
|
59
|
-
# c
|
|
60
|
-
# )
|
|
61
|
-
#
|
|
62
|
-
# # good
|
|
63
|
-
# foo(a, b, c)
|
|
64
|
-
#
|
|
65
47
|
# # good
|
|
66
48
|
# foo(
|
|
67
49
|
# a,
|
|
@@ -70,6 +52,7 @@ module RuboCop
|
|
|
70
52
|
# foo: "bar",
|
|
71
53
|
# }
|
|
72
54
|
# )
|
|
55
|
+
#
|
|
73
56
|
class MultilineMethodArgumentLineBreaks < Base
|
|
74
57
|
include MultilineElementLineBreaks
|
|
75
58
|
extend AutoCorrector
|
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
|
9
9
|
# NOTE: This cop does not move the first argument, if you want that to
|
|
10
10
|
# be on a separate line, see `Layout/FirstMethodParameterLineBreak`.
|
|
11
11
|
#
|
|
12
|
-
# @example
|
|
12
|
+
# @example
|
|
13
13
|
#
|
|
14
14
|
# # bad
|
|
15
15
|
# def foo(a, b,
|
|
@@ -17,12 +17,6 @@ module RuboCop
|
|
|
17
17
|
# )
|
|
18
18
|
# end
|
|
19
19
|
#
|
|
20
|
-
# # bad
|
|
21
|
-
# def foo(a, b = {
|
|
22
|
-
# foo: "bar",
|
|
23
|
-
# })
|
|
24
|
-
# end
|
|
25
|
-
#
|
|
26
20
|
# # good
|
|
27
21
|
# def foo(
|
|
28
22
|
# a,
|
|
@@ -44,40 +38,22 @@ module RuboCop
|
|
|
44
38
|
# def foo(a, b, c)
|
|
45
39
|
# end
|
|
46
40
|
#
|
|
47
|
-
# @example AllowMultilineFinalElement:
|
|
41
|
+
# @example AllowMultilineFinalElement: false (default)
|
|
48
42
|
#
|
|
49
43
|
# # bad
|
|
50
|
-
# def foo(a, b,
|
|
51
|
-
# c
|
|
52
|
-
# )
|
|
53
|
-
# end
|
|
54
|
-
#
|
|
55
|
-
# # good
|
|
56
44
|
# def foo(a, b = {
|
|
57
45
|
# foo: "bar",
|
|
58
46
|
# })
|
|
59
47
|
# end
|
|
60
48
|
#
|
|
61
|
-
#
|
|
62
|
-
# def foo(
|
|
63
|
-
# a,
|
|
64
|
-
# b,
|
|
65
|
-
# c
|
|
66
|
-
# )
|
|
67
|
-
# end
|
|
49
|
+
# @example AllowMultilineFinalElement: true
|
|
68
50
|
#
|
|
69
51
|
# # good
|
|
70
|
-
# def foo(
|
|
71
|
-
#
|
|
72
|
-
#
|
|
73
|
-
# foo: "bar",
|
|
74
|
-
# }
|
|
75
|
-
# )
|
|
52
|
+
# def foo(a, b = {
|
|
53
|
+
# foo: "bar",
|
|
54
|
+
# })
|
|
76
55
|
# end
|
|
77
56
|
#
|
|
78
|
-
# # good
|
|
79
|
-
# def foo(a, b, c)
|
|
80
|
-
# end
|
|
81
57
|
class MultilineMethodParameterLineBreaks < Base
|
|
82
58
|
include MultilineElementLineBreaks
|
|
83
59
|
extend AutoCorrector
|
|
@@ -236,6 +236,8 @@ module RuboCop
|
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
def offense(begin_pos, end_pos, msg, style_param = 'EnforcedStyle')
|
|
239
|
+
return if begin_pos > end_pos
|
|
240
|
+
|
|
239
241
|
range = range_between(begin_pos, end_pos)
|
|
240
242
|
add_offense(range, message: msg) do |corrector|
|
|
241
243
|
case range.source
|
|
@@ -52,6 +52,8 @@ module RuboCop
|
|
|
52
52
|
# expect { do_something }.to not_change { object.attribute }
|
|
53
53
|
#
|
|
54
54
|
class AmbiguousBlockAssociation < Base
|
|
55
|
+
extend AutoCorrector
|
|
56
|
+
|
|
55
57
|
include AllowedMethods
|
|
56
58
|
include AllowedPattern
|
|
57
59
|
|
|
@@ -68,7 +70,9 @@ module RuboCop
|
|
|
68
70
|
|
|
69
71
|
message = message(node)
|
|
70
72
|
|
|
71
|
-
add_offense(node, message: message)
|
|
73
|
+
add_offense(node, message: message) do |corrector|
|
|
74
|
+
wrap_in_parentheses(corrector, node)
|
|
75
|
+
end
|
|
72
76
|
end
|
|
73
77
|
alias on_csend on_send
|
|
74
78
|
|
|
@@ -89,6 +93,13 @@ module RuboCop
|
|
|
89
93
|
|
|
90
94
|
format(MSG, param: block_param.source, method: block_param.send_node.source)
|
|
91
95
|
end
|
|
96
|
+
|
|
97
|
+
def wrap_in_parentheses(corrector, node)
|
|
98
|
+
range = node.loc.selector.end.join(node.first_argument.source_range.begin)
|
|
99
|
+
|
|
100
|
+
corrector.replace(range, '(')
|
|
101
|
+
corrector.insert_after(node.last_argument, ')')
|
|
102
|
+
end
|
|
92
103
|
end
|
|
93
104
|
end
|
|
94
105
|
end
|
|
@@ -8,9 +8,9 @@ module RuboCop
|
|
|
8
8
|
#
|
|
9
9
|
# [source,console]
|
|
10
10
|
# ----
|
|
11
|
-
#
|
|
11
|
+
# $ cat example.rb
|
|
12
12
|
# ERB.new('hi', nil, '-', '@output_buffer')
|
|
13
|
-
#
|
|
13
|
+
# $ ruby -rerb example.rb
|
|
14
14
|
# example.rb:1: warning: Passing safe_level with the 2nd argument of ERB.new is
|
|
15
15
|
# deprecated. Do not use it, and specify other arguments as keyword arguments.
|
|
16
16
|
# example.rb:1: warning: Passing trim_mode with the 3rd argument of ERB.new is
|
|
@@ -6,6 +6,9 @@ module RuboCop
|
|
|
6
6
|
#
|
|
7
7
|
# This cop checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
|
|
8
8
|
#
|
|
9
|
+
# When an array of IO objects waiting for an exception (the third argument of `IO.select`)
|
|
10
|
+
# is used as an argument, there is no alternative API, so offenses are not registered.
|
|
11
|
+
#
|
|
9
12
|
# NOTE: When the method is successful the return value of `IO.select` is `[[IO]]`,
|
|
10
13
|
# and the return value of `io.wait_readable` and `io.wait_writable` are `self`.
|
|
11
14
|
# They are not autocorrected when assigning a return value because these types are different.
|
|
@@ -42,8 +45,8 @@ module RuboCop
|
|
|
42
45
|
PATTERN
|
|
43
46
|
|
|
44
47
|
def on_send(node)
|
|
45
|
-
read, write,
|
|
46
|
-
return
|
|
48
|
+
read, write, excepts, timeout = *io_select(node)
|
|
49
|
+
return if excepts && !excepts.children.empty?
|
|
47
50
|
return unless scheduler_compatible?(read, write) || scheduler_compatible?(write, read)
|
|
48
51
|
|
|
49
52
|
preferred = preferred_method(read, write, timeout)
|
|
@@ -6,7 +6,7 @@ module RuboCop
|
|
|
6
6
|
# Checks uses of lambda without a literal block.
|
|
7
7
|
# It emulates the following warning in Ruby 3.0:
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# $ ruby -vwe 'lambda(&proc {})'
|
|
10
10
|
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
|
11
11
|
# -e:1: warning: lambda without a literal block is deprecated; use the proc without
|
|
12
12
|
# lambda instead
|
|
@@ -6,13 +6,13 @@ module RuboCop
|
|
|
6
6
|
# Checks for uses of numbered parameter assignment.
|
|
7
7
|
# It emulates the following warning in Ruby 2.7:
|
|
8
8
|
#
|
|
9
|
-
#
|
|
9
|
+
# $ ruby -ve '_1 = :value'
|
|
10
10
|
# ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
|
|
11
11
|
# -e:1: warning: `_1' is reserved for numbered parameter; consider another name
|
|
12
12
|
#
|
|
13
13
|
# Assigning to a numbered parameter (from `_1` to `_9`) causes an error in Ruby 3.0.
|
|
14
14
|
#
|
|
15
|
-
#
|
|
15
|
+
# $ ruby -ve '_1 = :value'
|
|
16
16
|
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
|
17
17
|
# -e:1: _1 is reserved for numbered parameter
|
|
18
18
|
#
|
|
@@ -65,13 +65,13 @@ module RuboCop
|
|
|
65
65
|
def on_when(node)
|
|
66
66
|
regexp_conditions = node.conditions.select(&:regexp_type?)
|
|
67
67
|
|
|
68
|
-
@valid_ref = regexp_conditions.
|
|
68
|
+
@valid_ref = regexp_conditions.filter_map { |condition| check_regexp(condition) }.max
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def on_in_pattern(node)
|
|
72
72
|
regexp_patterns = regexp_patterns(node)
|
|
73
73
|
|
|
74
|
-
@valid_ref = regexp_patterns.
|
|
74
|
+
@valid_ref = regexp_patterns.filter_map { |pattern| check_regexp(pattern) }.max
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def on_nth_ref(node)
|
|
@@ -8,25 +8,39 @@ module RuboCop
|
|
|
8
8
|
# always ignored. This is detected automatically since Ruby 2.7.
|
|
9
9
|
#
|
|
10
10
|
# @example
|
|
11
|
+
# # bad
|
|
12
|
+
# return 1
|
|
11
13
|
#
|
|
12
|
-
# #
|
|
13
|
-
# return
|
|
14
|
+
# # good
|
|
15
|
+
# return
|
|
14
16
|
class TopLevelReturnWithArgument < Base
|
|
15
|
-
|
|
16
|
-
# top-level return node's ancestors should not be of block, def, or
|
|
17
|
-
# defs type.
|
|
17
|
+
extend AutoCorrector
|
|
18
18
|
|
|
19
19
|
MSG = 'Top level return with argument detected.'
|
|
20
20
|
|
|
21
21
|
def on_return(return_node)
|
|
22
|
-
|
|
22
|
+
return unless top_level_return_with_any_argument?(return_node)
|
|
23
|
+
|
|
24
|
+
add_offense(return_node) do |corrector|
|
|
25
|
+
remove_arguments(corrector, return_node)
|
|
26
|
+
end
|
|
23
27
|
end
|
|
24
28
|
|
|
25
29
|
private
|
|
26
30
|
|
|
27
|
-
def
|
|
28
|
-
|
|
29
|
-
|
|
31
|
+
def top_level_return_with_any_argument?(return_node)
|
|
32
|
+
top_level_return?(return_node) && return_node.arguments?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def remove_arguments(corrector, return_node)
|
|
36
|
+
corrector.replace(return_node, 'return')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# This cop works by validating the ancestors of the return node. A
|
|
40
|
+
# top-level return node's ancestors should not be of block, def, or
|
|
41
|
+
# defs type.
|
|
42
|
+
def top_level_return?(return_node)
|
|
43
|
+
return_node.each_ancestor(:block, :def, :defs).none?
|
|
30
44
|
end
|
|
31
45
|
end
|
|
32
46
|
end
|
|
@@ -13,6 +13,12 @@ module RuboCop
|
|
|
13
13
|
# reassignments and properly handles varied cases such as branch, loop,
|
|
14
14
|
# rescue, ensure, etc.
|
|
15
15
|
#
|
|
16
|
+
# @safety
|
|
17
|
+
# This cop's autocorrection is unsafe because removing assignment from
|
|
18
|
+
# operator assignment can cause NameError if this assignment has been used to declare
|
|
19
|
+
# local variable. For example, replacing `a ||= 1` to `a || 1` may cause
|
|
20
|
+
# "undefined local variable or method `a' for main:Object (NameError)".
|
|
21
|
+
#
|
|
16
22
|
# @example
|
|
17
23
|
#
|
|
18
24
|
# # bad
|
|
@@ -31,6 +37,10 @@ module RuboCop
|
|
|
31
37
|
# do_something(some_var)
|
|
32
38
|
# end
|
|
33
39
|
class UselessAssignment < Base
|
|
40
|
+
extend AutoCorrector
|
|
41
|
+
|
|
42
|
+
include RangeHelp
|
|
43
|
+
|
|
34
44
|
MSG = 'Useless assignment to variable - `%<variable>s`.'
|
|
35
45
|
|
|
36
46
|
def self.joining_forces
|
|
@@ -55,7 +65,9 @@ module RuboCop
|
|
|
55
65
|
assignment.node.loc.name
|
|
56
66
|
end
|
|
57
67
|
|
|
58
|
-
add_offense(location, message: message)
|
|
68
|
+
add_offense(location, message: message) do |corrector|
|
|
69
|
+
autocorrect(corrector, assignment)
|
|
70
|
+
end
|
|
59
71
|
end
|
|
60
72
|
end
|
|
61
73
|
|
|
@@ -119,6 +131,49 @@ module RuboCop
|
|
|
119
131
|
|
|
120
132
|
node.receiver.nil? && !node.arguments?
|
|
121
133
|
end
|
|
134
|
+
|
|
135
|
+
def autocorrect(corrector, assignment)
|
|
136
|
+
if assignment.exception_assignment?
|
|
137
|
+
remove_exception_assignment_part(corrector, assignment.node)
|
|
138
|
+
elsif assignment.multiple_assignment?
|
|
139
|
+
rename_variable_with_underscore(corrector, assignment.node)
|
|
140
|
+
elsif assignment.operator_assignment?
|
|
141
|
+
remove_trailing_character_from_operator(corrector, assignment.node)
|
|
142
|
+
elsif assignment.regexp_named_capture?
|
|
143
|
+
replace_named_capture_group_with_non_capturing_group(corrector, assignment.node,
|
|
144
|
+
assignment.variable.name)
|
|
145
|
+
else
|
|
146
|
+
remove_local_variable_assignment_part(corrector, assignment.node)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def remove_exception_assignment_part(corrector, node)
|
|
151
|
+
corrector.remove(
|
|
152
|
+
range_between(
|
|
153
|
+
(node.parent.children.first&.source_range || node.parent.location.keyword).end_pos,
|
|
154
|
+
node.source_range.end_pos
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def rename_variable_with_underscore(corrector, node)
|
|
160
|
+
corrector.replace(node, '_')
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def remove_trailing_character_from_operator(corrector, node)
|
|
164
|
+
corrector.remove(node.parent.location.operator.end.adjust(begin_pos: -1))
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def replace_named_capture_group_with_non_capturing_group(corrector, node, variable_name)
|
|
168
|
+
corrector.replace(
|
|
169
|
+
node.children.first,
|
|
170
|
+
node.children.first.source.sub(/\(\?<#{variable_name}>/, '(?:')
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def remove_local_variable_assignment_part(corrector, node)
|
|
175
|
+
corrector.replace(node, node.expression.source)
|
|
176
|
+
end
|
|
122
177
|
end
|
|
123
178
|
end
|
|
124
179
|
end
|
|
@@ -41,6 +41,10 @@ module RuboCop
|
|
|
41
41
|
# do_something(some_array)
|
|
42
42
|
# end
|
|
43
43
|
class Void < Base
|
|
44
|
+
extend AutoCorrector
|
|
45
|
+
|
|
46
|
+
include RangeHelp
|
|
47
|
+
|
|
44
48
|
OP_MSG = 'Operator `%<op>s` used in void context.'
|
|
45
49
|
VAR_MSG = 'Variable `%<var>s` used in void context.'
|
|
46
50
|
LIT_MSG = 'Literal `%<lit>s` used in void context.'
|
|
@@ -100,31 +104,43 @@ module RuboCop
|
|
|
100
104
|
def check_void_op(node)
|
|
101
105
|
return unless node.send_type? && OPERATORS.include?(node.method_name)
|
|
102
106
|
|
|
103
|
-
add_offense(node.loc.selector,
|
|
107
|
+
add_offense(node.loc.selector,
|
|
108
|
+
message: format(OP_MSG, op: node.method_name)) do |corrector|
|
|
109
|
+
autocorrect_void_op(corrector, node)
|
|
110
|
+
end
|
|
104
111
|
end
|
|
105
112
|
|
|
106
113
|
def check_var(node)
|
|
107
114
|
return unless node.variable? || node.const_type?
|
|
108
115
|
|
|
109
|
-
add_offense(node.loc.name,
|
|
116
|
+
add_offense(node.loc.name,
|
|
117
|
+
message: format(VAR_MSG, var: node.loc.name.source)) do |corrector|
|
|
118
|
+
autocorrect_void_var(corrector, node)
|
|
119
|
+
end
|
|
110
120
|
end
|
|
111
121
|
|
|
112
122
|
def check_literal(node)
|
|
113
123
|
return if !node.literal? || node.xstr_type? || node.range_type?
|
|
114
124
|
|
|
115
|
-
add_offense(node, message: format(LIT_MSG, lit: node.source))
|
|
125
|
+
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
|
126
|
+
autocorrect_void_literal(corrector, node)
|
|
127
|
+
end
|
|
116
128
|
end
|
|
117
129
|
|
|
118
130
|
def check_self(node)
|
|
119
131
|
return unless node.self_type?
|
|
120
132
|
|
|
121
|
-
add_offense(node, message: SELF_MSG)
|
|
133
|
+
add_offense(node, message: SELF_MSG) do |corrector|
|
|
134
|
+
autocorrect_void_self(corrector, node)
|
|
135
|
+
end
|
|
122
136
|
end
|
|
123
137
|
|
|
124
138
|
def check_void_expression(node)
|
|
125
139
|
return unless node.defined_type? || node.lambda_or_proc?
|
|
126
140
|
|
|
127
|
-
add_offense(node, message: format(EXPRESSION_MSG, expression: node.source))
|
|
141
|
+
add_offense(node, message: format(EXPRESSION_MSG, expression: node.source)) do |corrector|
|
|
142
|
+
autocorrect_void_expression(corrector, node)
|
|
143
|
+
end
|
|
128
144
|
end
|
|
129
145
|
|
|
130
146
|
def check_nonmutating(node)
|
|
@@ -139,7 +155,10 @@ module RuboCop
|
|
|
139
155
|
"#{method_name}!"
|
|
140
156
|
end
|
|
141
157
|
add_offense(node,
|
|
142
|
-
message: format(NONMUTATING_MSG, method: method_name,
|
|
158
|
+
message: format(NONMUTATING_MSG, method: method_name,
|
|
159
|
+
suggest: suggestion)) do |corrector|
|
|
160
|
+
autocorrect_nonmutating_send(corrector, node, suggestion)
|
|
161
|
+
end
|
|
143
162
|
end
|
|
144
163
|
|
|
145
164
|
def in_void_context?(node)
|
|
@@ -149,6 +168,43 @@ module RuboCop
|
|
|
149
168
|
|
|
150
169
|
VOID_CONTEXT_TYPES.include?(parent.type) && parent.void_context?
|
|
151
170
|
end
|
|
171
|
+
|
|
172
|
+
def autocorrect_void_op(corrector, node)
|
|
173
|
+
if node.arguments.empty?
|
|
174
|
+
corrector.replace(node, node.receiver.source)
|
|
175
|
+
else
|
|
176
|
+
corrector.replace(
|
|
177
|
+
range_with_surrounding_space(range: node.loc.selector, side: :both,
|
|
178
|
+
newlines: false),
|
|
179
|
+
"\n"
|
|
180
|
+
)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def autocorrect_void_var(corrector, node)
|
|
185
|
+
corrector.remove(range_with_surrounding_space(range: node.loc.name, side: :left))
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def autocorrect_void_literal(corrector, node)
|
|
189
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def autocorrect_void_self(corrector, node)
|
|
193
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def autocorrect_void_expression(corrector, node)
|
|
197
|
+
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def autocorrect_nonmutating_send(corrector, node, suggestion)
|
|
201
|
+
send_node = if node.send_type?
|
|
202
|
+
node
|
|
203
|
+
else
|
|
204
|
+
node.send_node
|
|
205
|
+
end
|
|
206
|
+
corrector.replace(send_node.loc.selector, suggestion)
|
|
207
|
+
end
|
|
152
208
|
end
|
|
153
209
|
end
|
|
154
210
|
end
|
|
@@ -62,12 +62,16 @@ module RuboCop
|
|
|
62
62
|
# Returns the end line of a node, which might be a comment and not part of the AST
|
|
63
63
|
# End line is considered either the line at which another node starts, or
|
|
64
64
|
# the line at which the parent node ends.
|
|
65
|
-
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
65
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch
|
|
66
66
|
def find_end_line(node)
|
|
67
67
|
if node.if_type? && node.else?
|
|
68
68
|
node.loc.else.line
|
|
69
69
|
elsif node.if_type? && node.ternary?
|
|
70
70
|
node.else_branch.loc.line
|
|
71
|
+
elsif node.if_type? && node.elsif?
|
|
72
|
+
node.each_ancestor(:if).find(&:if?).loc.end.line
|
|
73
|
+
elsif node.block_type? || node.numblock_type?
|
|
74
|
+
node.loc.end.line
|
|
71
75
|
elsif (next_sibling = node.right_sibling) && next_sibling.is_a?(AST::Node)
|
|
72
76
|
next_sibling.loc.line
|
|
73
77
|
elsif (parent = node.parent)
|
|
@@ -76,7 +80,7 @@ module RuboCop
|
|
|
76
80
|
node.loc.end.line
|
|
77
81
|
end
|
|
78
82
|
end
|
|
79
|
-
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
83
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Lint/DuplicateBranch
|
|
80
84
|
end
|
|
81
85
|
end
|
|
82
86
|
end
|