rubocop 1.5.2 → 1.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +3 -2
- data/config/default.yml +112 -16
- data/config/obsoletion.yml +196 -0
- data/lib/rubocop.rb +20 -1
- data/lib/rubocop/cli/command/suggest_extensions.rb +16 -44
- data/lib/rubocop/comment_config.rb +6 -6
- data/lib/rubocop/config.rb +8 -5
- data/lib/rubocop/config_loader.rb +11 -7
- data/lib/rubocop/config_loader_resolver.rb +21 -4
- data/lib/rubocop/config_obsoletion.rb +64 -262
- data/lib/rubocop/config_obsoletion/changed_enforced_styles.rb +33 -0
- data/lib/rubocop/config_obsoletion/changed_parameter.rb +21 -0
- data/lib/rubocop/config_obsoletion/cop_rule.rb +34 -0
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +44 -0
- data/lib/rubocop/config_obsoletion/parameter_rule.rb +44 -0
- data/lib/rubocop/config_obsoletion/removed_cop.rb +41 -0
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +34 -0
- data/lib/rubocop/config_obsoletion/rule.rb +41 -0
- data/lib/rubocop/config_obsoletion/split_cop.rb +27 -0
- data/lib/rubocop/config_validator.rb +11 -4
- data/lib/rubocop/cop/base.rb +17 -15
- data/lib/rubocop/cop/cop.rb +2 -2
- data/lib/rubocop/cop/correctors/string_literal_corrector.rb +6 -8
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +3 -2
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +145 -0
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +19 -3
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +14 -0
- data/lib/rubocop/cop/layout/line_length.rb +6 -16
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -10
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +2 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +62 -0
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +13 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +2 -2
- data/lib/rubocop/cop/lint/ambiguous_assignment.rb +59 -0
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +7 -2
- data/lib/rubocop/cop/lint/deprecated_constants.rb +75 -0
- data/lib/rubocop/cop/lint/duplicate_branch.rb +64 -2
- data/lib/rubocop/cop/lint/lambda_without_literal_block.rb +44 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +10 -6
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +2 -1
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +50 -0
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +50 -17
- data/lib/rubocop/cop/lint/shadowed_exception.rb +1 -11
- data/lib/rubocop/cop/lint/unreachable_loop.rb +17 -0
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/allowed_identifiers.rb +18 -0
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -10
- data/lib/rubocop/cop/mixin/first_element_line_break.rb +1 -1
- data/lib/rubocop/cop/mixin/string_help.rb +4 -1
- data/lib/rubocop/cop/mixin/uncommunicative_name.rb +5 -1
- data/lib/rubocop/cop/naming/accessor_method_name.rb +15 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +59 -5
- data/lib/rubocop/cop/naming/variable_name.rb +2 -0
- data/lib/rubocop/cop/naming/variable_number.rb +1 -8
- data/lib/rubocop/cop/registry.rb +10 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +3 -1
- data/lib/rubocop/cop/style/character_literal.rb +10 -11
- data/lib/rubocop/cop/style/collection_methods.rb +14 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +22 -5
- data/lib/rubocop/cop/style/empty_literal.rb +6 -2
- data/lib/rubocop/cop/style/endless_method.rb +102 -0
- data/lib/rubocop/cop/style/explicit_block_argument.rb +10 -0
- data/lib/rubocop/cop/style/float_division.rb +44 -1
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/hash_except.rb +95 -0
- data/lib/rubocop/cop/style/hash_like_case.rb +2 -1
- data/lib/rubocop/cop/style/if_inside_else.rb +8 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +4 -0
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -1
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +12 -2
- data/lib/rubocop/cop/style/lambda_call.rb +2 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +7 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +16 -6
- data/lib/rubocop/cop/style/method_def_parentheses.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +26 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +3 -1
- data/lib/rubocop/cop/style/mutable_constant.rb +13 -3
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +4 -0
- data/lib/rubocop/cop/style/perl_backrefs.rb +86 -9
- data/lib/rubocop/cop/style/raise_args.rb +5 -2
- data/lib/rubocop/cop/style/redundant_argument.rb +21 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +8 -4
- data/lib/rubocop/cop/style/redundant_return.rb +1 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +30 -7
- data/lib/rubocop/cop/style/single_line_methods.rb +34 -2
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +15 -9
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -13
- data/lib/rubocop/cop/style/string_concatenation.rb +20 -1
- data/lib/rubocop/cop/style/string_literals.rb +14 -8
- data/lib/rubocop/cop/style/string_literals_in_interpolation.rb +4 -3
- data/lib/rubocop/cop/style/symbol_proc.rb +5 -4
- data/lib/rubocop/cop/style/while_until_modifier.rb +2 -4
- data/lib/rubocop/cop/util.rb +3 -1
- data/lib/rubocop/formatter/emacs_style_formatter.rb +2 -0
- data/lib/rubocop/formatter/simple_text_formatter.rb +2 -0
- data/lib/rubocop/formatter/tap_formatter.rb +2 -0
- data/lib/rubocop/lockfile.rb +40 -0
- data/lib/rubocop/options.rb +9 -9
- data/lib/rubocop/rspec/cop_helper.rb +0 -4
- data/lib/rubocop/rspec/expect_offense.rb +34 -22
- data/lib/rubocop/runner.rb +16 -1
- data/lib/rubocop/target_finder.rb +4 -2
- data/lib/rubocop/target_ruby.rb +47 -11
- data/lib/rubocop/util.rb +16 -0
- data/lib/rubocop/version.rb +8 -2
- metadata +28 -7
@@ -112,13 +112,13 @@ module RuboCop
|
|
112
112
|
|
113
113
|
def incorrect_style_detected(token1, token2,
|
114
114
|
expect_space, is_empty_braces)
|
115
|
-
return unless ambiguous_or_unexpected_style_detected(style, token1.text == token2.text)
|
116
|
-
|
117
115
|
brace = (token1.text == '{' ? token1 : token2).pos
|
118
116
|
range = expect_space ? brace : space_range(brace)
|
117
|
+
detected_style = expect_space ? 'no_space' : 'space'
|
119
118
|
|
120
119
|
add_offense(range, message: message(brace, is_empty_braces, expect_space)) do |corrector|
|
121
120
|
autocorrect(corrector, range)
|
121
|
+
ambiguous_or_unexpected_style_detected(detected_style, token1.text == token2.text)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for mistyped shorthand assignments.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# # bad
|
10
|
+
# x =- y
|
11
|
+
# x =+ y
|
12
|
+
# x =* y
|
13
|
+
# x =! y
|
14
|
+
#
|
15
|
+
# # good
|
16
|
+
# x -= y # or x = -y
|
17
|
+
# x += y # or x = +y
|
18
|
+
# x *= y # or x = *y
|
19
|
+
# x != y # or x = !y
|
20
|
+
#
|
21
|
+
class AmbiguousAssignment < Base
|
22
|
+
include RangeHelp
|
23
|
+
|
24
|
+
MSG = 'Suspicious assignment detected. Did you mean `%<op>s`?'
|
25
|
+
|
26
|
+
SIMPLE_ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn casgn].freeze
|
27
|
+
|
28
|
+
MISTAKES = {
|
29
|
+
'=-' => '-=',
|
30
|
+
'=+' => '+=',
|
31
|
+
'=*' => '*=',
|
32
|
+
'=!' => '!='
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
def on_asgn(node)
|
36
|
+
return unless (rhs = rhs(node))
|
37
|
+
|
38
|
+
range = range_between(node.loc.operator.end_pos - 1, rhs.source_range.begin_pos + 1)
|
39
|
+
source = range.source
|
40
|
+
return unless MISTAKES.key?(source)
|
41
|
+
|
42
|
+
add_offense(range, message: format(MSG, op: MISTAKES[source]))
|
43
|
+
end
|
44
|
+
|
45
|
+
SIMPLE_ASSIGNMENT_TYPES.each { |asgn_type| alias_method :"on_#{asgn_type}", :on_asgn }
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def rhs(node)
|
50
|
+
if node.casgn_type?
|
51
|
+
node.children[2]
|
52
|
+
else
|
53
|
+
node.children[1]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -17,6 +17,7 @@ module RuboCop
|
|
17
17
|
#
|
18
18
|
# @example
|
19
19
|
# # bad
|
20
|
+
# x / x
|
20
21
|
# x.top >= x.top
|
21
22
|
#
|
22
23
|
# if a.x != 0 && a.x != 0
|
@@ -27,15 +28,19 @@ module RuboCop
|
|
27
28
|
# left_child || left_child
|
28
29
|
# end
|
29
30
|
#
|
31
|
+
# # good
|
32
|
+
# x + x
|
33
|
+
# 1 << 1
|
34
|
+
#
|
30
35
|
class BinaryOperatorWithIdenticalOperands < Base
|
31
36
|
MSG = 'Binary operator `%<op>s` has identical operands.'
|
32
|
-
|
37
|
+
ALLOWED_MATH_OPERATORS = %i[+ * ** << >>].to_set.freeze
|
33
38
|
|
34
39
|
def on_send(node)
|
35
40
|
return unless node.binary_operation?
|
36
41
|
|
37
42
|
lhs, operation, rhs = *node
|
38
|
-
return if
|
43
|
+
return if ALLOWED_MATH_OPERATORS.include?(node.method_name)
|
39
44
|
|
40
45
|
add_offense(node, message: format(MSG, op: operation)) if lhs == rhs
|
41
46
|
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks for deprecated constants.
|
7
|
+
#
|
8
|
+
# It has `DeprecatedConstants` config. If there is an alternative method, you can set
|
9
|
+
# alternative value as `Alternative`. And you can set the deprecated version as
|
10
|
+
# `DeprecatedVersion`. These options can be omitted if they are not needed.
|
11
|
+
#
|
12
|
+
# DeprecatedConstants:
|
13
|
+
# 'DEPRECATED_CONSTANT':
|
14
|
+
# Alternative: 'alternative_value'
|
15
|
+
# DeprecatedVersion: 'deprecated_version'
|
16
|
+
#
|
17
|
+
# By default, `NIL`, `TRUE`, `FALSE` and `Random::DEFAULT` are configured.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
#
|
21
|
+
# # bad
|
22
|
+
# NIL
|
23
|
+
# TRUE
|
24
|
+
# FALSE
|
25
|
+
# Random::DEFAULT # Return value of Ruby 2 is `Random` instance, Ruby 3.0 is `Random` class.
|
26
|
+
#
|
27
|
+
# # good
|
28
|
+
# nil
|
29
|
+
# true
|
30
|
+
# false
|
31
|
+
# Random.new # `::DEFAULT` has been deprecated in Ruby 3, `.new` is compatible with Ruby 2.
|
32
|
+
#
|
33
|
+
class DeprecatedConstants < Base
|
34
|
+
extend AutoCorrector
|
35
|
+
|
36
|
+
SUGGEST_GOOD_MSG = 'Use `%<good>s` instead of `%<bad>s`%<deprecated_message>s.'
|
37
|
+
DO_NOT_USE_MSG = 'Do not use `%<bad>s`%<deprecated_message>s.'
|
38
|
+
|
39
|
+
def on_const(node)
|
40
|
+
constant = node.absolute? ? consntant_name(node, node.short_name.to_s) : node.source
|
41
|
+
return unless (deprecated_constant = deprecated_constants[constant])
|
42
|
+
|
43
|
+
alternative = deprecated_constant['Alternative']
|
44
|
+
version = deprecated_constant['DeprecatedVersion']
|
45
|
+
|
46
|
+
add_offense(node, message: message(alternative, node.source, version)) do |corrector|
|
47
|
+
corrector.replace(node, alternative)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def consntant_name(node, nested_constant_name)
|
54
|
+
return nested_constant_name unless node.namespace.const_type?
|
55
|
+
|
56
|
+
consntant_name(node.namespace, "#{node.namespace.short_name}::#{nested_constant_name}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def message(good, bad, deprecated_version)
|
60
|
+
deprecated_message = ", deprecated since Ruby #{deprecated_version}" if deprecated_version
|
61
|
+
|
62
|
+
if good
|
63
|
+
format(SUGGEST_GOOD_MSG, good: good, bad: bad, deprecated_message: deprecated_message)
|
64
|
+
else
|
65
|
+
format(DO_NOT_USE_MSG, bad: bad, deprecated_message: deprecated_message)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def deprecated_constants
|
70
|
+
cop_config.fetch('DeprecatedConstants', {})
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -6,6 +6,15 @@ module RuboCop
|
|
6
6
|
# This cop checks that there are no repeated bodies
|
7
7
|
# within `if/unless`, `case-when` and `rescue` constructs.
|
8
8
|
#
|
9
|
+
# With `IgnoreLiteralBranches: true`, branches are not registered
|
10
|
+
# as offenses if they return a basic literal value (string, symbol,
|
11
|
+
# integer, float, rational, complex, `true`, `false`, or `nil`), or
|
12
|
+
# return an array, hash, regexp or range that only contains one of
|
13
|
+
# the above basic literal values.
|
14
|
+
#
|
15
|
+
# With `IgnoreConstantBranches: true`, branches are not registered
|
16
|
+
# as offenses if they return a constant value.
|
17
|
+
#
|
9
18
|
# @example
|
10
19
|
# # bad
|
11
20
|
# if foo
|
@@ -56,14 +65,33 @@ module RuboCop
|
|
56
65
|
# handle_error
|
57
66
|
# end
|
58
67
|
#
|
68
|
+
# @example IgnoreLiteralBranches: true
|
69
|
+
# # good
|
70
|
+
# case size
|
71
|
+
# when "small" then 100
|
72
|
+
# when "medium" then 250
|
73
|
+
# when "large" then 1000
|
74
|
+
# else 250
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# @example IgnoreLiteralBranches: true
|
78
|
+
# # good
|
79
|
+
# case size
|
80
|
+
# when "small" then SMALL_SIZE
|
81
|
+
# when "medium" then MEDIUM_SIZE
|
82
|
+
# when "large" then LARGE_SIZE
|
83
|
+
# else MEDIUM_SIZE
|
84
|
+
# end
|
85
|
+
#
|
59
86
|
class DuplicateBranch < Base
|
60
87
|
include RescueNode
|
61
88
|
|
62
89
|
MSG = 'Duplicate branch body detected.'
|
63
90
|
|
64
91
|
def on_branching_statement(node)
|
65
|
-
branches
|
66
|
-
|
92
|
+
branches(node).each_with_object(Set.new) do |branch, previous|
|
93
|
+
next unless consider_branch?(branch)
|
94
|
+
|
67
95
|
add_offense(offense_range(branch)) unless previous.add?(branch)
|
68
96
|
end
|
69
97
|
end
|
@@ -87,6 +115,40 @@ module RuboCop
|
|
87
115
|
parent.source_range
|
88
116
|
end
|
89
117
|
end
|
118
|
+
|
119
|
+
def branches(node)
|
120
|
+
node.branches.compact
|
121
|
+
end
|
122
|
+
|
123
|
+
def consider_branch?(branch)
|
124
|
+
return false if ignore_literal_branches? && literal_branch?(branch)
|
125
|
+
return false if ignore_constant_branches? && const_branch?(branch)
|
126
|
+
|
127
|
+
true
|
128
|
+
end
|
129
|
+
|
130
|
+
def ignore_literal_branches?
|
131
|
+
cop_config.fetch('IgnoreLiteralBranches', false)
|
132
|
+
end
|
133
|
+
|
134
|
+
def ignore_constant_branches?
|
135
|
+
cop_config.fetch('IgnoreConstantBranches', false)
|
136
|
+
end
|
137
|
+
|
138
|
+
def literal_branch?(branch) # rubocop:disable Metrics/CyclomaticComplexity
|
139
|
+
return false if !branch.literal? || branch.xstr_type?
|
140
|
+
return true if branch.basic_literal?
|
141
|
+
|
142
|
+
branch.each_descendant.all? do |node|
|
143
|
+
node.basic_literal? ||
|
144
|
+
node.pair_type? || # hash keys and values are contained within a `pair` node
|
145
|
+
(node.const_type? && ignore_constant_branches?)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def const_branch?(branch)
|
150
|
+
branch.const_type?
|
151
|
+
end
|
90
152
|
end
|
91
153
|
end
|
92
154
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop checks uses of lambda without a literal block.
|
7
|
+
# It emulates the following warning in Ruby 3.0:
|
8
|
+
#
|
9
|
+
# % ruby -vwe 'lambda(&proc {})'
|
10
|
+
# ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-darwin19]
|
11
|
+
# -e:1: warning: lambda without a literal block is deprecated; use the proc without
|
12
|
+
# lambda instead
|
13
|
+
#
|
14
|
+
# This way, proc object is never converted to lambda.
|
15
|
+
# Auto-correction replaces with compatible proc argument.
|
16
|
+
#
|
17
|
+
# @example
|
18
|
+
#
|
19
|
+
# # bad
|
20
|
+
# lambda(&proc { do_something })
|
21
|
+
# lambda(&Proc.new { do_something })
|
22
|
+
#
|
23
|
+
# # good
|
24
|
+
# proc { do_something }
|
25
|
+
# Proc.new { do_something }
|
26
|
+
# lambda { do_something } # If you use lambda.
|
27
|
+
#
|
28
|
+
class LambdaWithoutLiteralBlock < Base
|
29
|
+
extend AutoCorrector
|
30
|
+
|
31
|
+
MSG = 'lambda without a literal block is deprecated; use the proc without lambda instead.'
|
32
|
+
RESTRICT_ON_SEND = %i[lambda].freeze
|
33
|
+
|
34
|
+
def on_send(node)
|
35
|
+
return if node.parent&.block_type? || !node.first_argument
|
36
|
+
|
37
|
+
add_offense(node) do |corrector|
|
38
|
+
corrector.replace(node, node.first_argument.source.delete('&'))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -11,6 +11,11 @@ module RuboCop
|
|
11
11
|
# that are hard to debug. To ensure this doesn't happen,
|
12
12
|
# always sort the list.
|
13
13
|
#
|
14
|
+
# `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
|
15
|
+
# So all bad cases are acceptable when Ruby 3.0 or higher are used.
|
16
|
+
#
|
17
|
+
# This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
18
|
+
#
|
14
19
|
# @example
|
15
20
|
#
|
16
21
|
# # bad
|
@@ -23,8 +28,6 @@ module RuboCop
|
|
23
28
|
# require file
|
24
29
|
# end
|
25
30
|
#
|
26
|
-
# @example
|
27
|
-
#
|
28
31
|
# # bad
|
29
32
|
# Dir.glob(Rails.root.join(__dir__, 'test', '*.rb')) do |file|
|
30
33
|
# require file
|
@@ -35,28 +38,28 @@ module RuboCop
|
|
35
38
|
# require file
|
36
39
|
# end
|
37
40
|
#
|
38
|
-
# @example
|
39
|
-
#
|
40
41
|
# # bad
|
41
42
|
# Dir['./lib/**/*.rb'].each(&method(:require))
|
42
43
|
#
|
43
44
|
# # good
|
44
45
|
# Dir['./lib/**/*.rb'].sort.each(&method(:require))
|
45
46
|
#
|
46
|
-
# @example
|
47
|
-
#
|
48
47
|
# # bad
|
49
48
|
# Dir.glob(Rails.root.join('test', '*.rb'), &method(:require))
|
50
49
|
#
|
51
50
|
# # good
|
52
51
|
# Dir.glob(Rails.root.join('test', '*.rb')).sort.each(&method(:require))
|
53
52
|
#
|
53
|
+
# # good - Respect intent if `sort` keyword option is specified in Ruby 3.0 or higher.
|
54
|
+
# Dir.glob(Rails.root.join(__dir__, 'test', '*.rb'), sort: false).each(&method(:require))
|
55
|
+
#
|
54
56
|
class NonDeterministicRequireOrder < Base
|
55
57
|
extend AutoCorrector
|
56
58
|
|
57
59
|
MSG = 'Sort files before requiring them.'
|
58
60
|
|
59
61
|
def on_block(node)
|
62
|
+
return if target_ruby_version >= 3.0
|
60
63
|
return unless node.body
|
61
64
|
return unless unsorted_dir_loop?(node.send_node)
|
62
65
|
|
@@ -70,6 +73,7 @@ module RuboCop
|
|
70
73
|
end
|
71
74
|
|
72
75
|
def on_block_pass(node)
|
76
|
+
return if target_ruby_version >= 3.0
|
73
77
|
return unless method_require?(node)
|
74
78
|
return unless unsorted_dir_pass?(node.parent)
|
75
79
|
|
@@ -61,7 +61,8 @@ module RuboCop
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def comment_range_with_surrounding_space(range)
|
64
|
-
if previous_line_blank?(range)
|
64
|
+
if previous_line_blank?(range) &&
|
65
|
+
processed_source.comment_config.comment_only_line?(range.line)
|
65
66
|
# When the previous line is blank, it should be retained
|
66
67
|
range_with_surrounding_space(range: range, side: :right)
|
67
68
|
else
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Sort globbed results by default in Ruby 3.0.
|
7
|
+
# This cop checks for redundant `sort` method to `Dir.glob` and `Dir[]`.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# Dir.glob('./lib/**/*.rb').sort.each do |file|
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# Dir['./lib/**/*.rb'].sort.each do |file|
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# # good
|
19
|
+
# Dir.glob('./lib/**/*.rb').each do |file|
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# Dir['./lib/**/*.rb'].each do |file|
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
class RedundantDirGlobSort < Base
|
26
|
+
extend AutoCorrector
|
27
|
+
extend TargetRubyVersion
|
28
|
+
|
29
|
+
minimum_target_ruby_version 3.0
|
30
|
+
|
31
|
+
MSG = 'Remove redundant `sort`.'
|
32
|
+
RESTRICT_ON_SEND = %i[sort].freeze
|
33
|
+
GLOB_METHODS = %i[glob []].freeze
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
return unless (receiver = node.receiver)
|
37
|
+
return unless receiver.receiver&.const_type? && receiver.receiver.short_name == :Dir
|
38
|
+
return unless GLOB_METHODS.include?(receiver.method_name)
|
39
|
+
|
40
|
+
selector = node.loc.selector
|
41
|
+
|
42
|
+
add_offense(selector) do |corrector|
|
43
|
+
corrector.remove(selector)
|
44
|
+
corrector.remove(node.loc.dot)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -8,47 +8,66 @@ module RuboCop
|
|
8
8
|
# @example
|
9
9
|
#
|
10
10
|
# # bad
|
11
|
-
#
|
12
11
|
# a = *[1, 2, 3]
|
13
12
|
# a = *'a'
|
14
13
|
# a = *1
|
15
|
-
#
|
16
|
-
# begin
|
17
|
-
# foo
|
18
|
-
# rescue *[StandardError, ApplicationError]
|
19
|
-
# bar
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# case foo
|
23
|
-
# when *[1, 2, 3]
|
24
|
-
# bar
|
25
|
-
# else
|
26
|
-
# baz
|
27
|
-
# end
|
28
|
-
#
|
29
|
-
# @example
|
14
|
+
# ['a', 'b', *%w(c d e), 'f', 'g']
|
30
15
|
#
|
31
16
|
# # good
|
32
|
-
#
|
33
17
|
# c = [1, 2, 3]
|
34
18
|
# a = *c
|
35
19
|
# a, b = *c
|
36
20
|
# a, *b = *c
|
37
21
|
# a = *1..10
|
38
22
|
# a = ['a']
|
23
|
+
# ['a', 'b', 'c', 'd', 'e', 'f', 'g']
|
39
24
|
#
|
25
|
+
# # bad
|
26
|
+
# do_something(*['foo', 'bar', 'baz'])
|
27
|
+
#
|
28
|
+
# # good
|
29
|
+
# do_something('foo', 'bar', 'baz')
|
30
|
+
#
|
31
|
+
# # bad
|
32
|
+
# begin
|
33
|
+
# foo
|
34
|
+
# rescue *[StandardError, ApplicationError]
|
35
|
+
# bar
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # good
|
40
39
|
# begin
|
41
40
|
# foo
|
42
41
|
# rescue StandardError, ApplicationError
|
43
42
|
# bar
|
44
43
|
# end
|
45
44
|
#
|
45
|
+
# # bad
|
46
|
+
# case foo
|
47
|
+
# when *[1, 2, 3]
|
48
|
+
# bar
|
49
|
+
# else
|
50
|
+
# baz
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # good
|
46
54
|
# case foo
|
47
55
|
# when 1, 2, 3
|
48
56
|
# bar
|
49
57
|
# else
|
50
58
|
# baz
|
51
59
|
# end
|
60
|
+
#
|
61
|
+
# @example AllowPercentLiteralArrayArgument: true (default)
|
62
|
+
#
|
63
|
+
# # good
|
64
|
+
# do_something(*%w[foo bar baz])
|
65
|
+
#
|
66
|
+
# @example AllowPercentLiteralArrayArgument: false
|
67
|
+
#
|
68
|
+
# # bad
|
69
|
+
# do_something(*%w[foo bar baz])
|
70
|
+
#
|
52
71
|
class RedundantSplatExpansion < Base
|
53
72
|
extend AutoCorrector
|
54
73
|
|
@@ -75,6 +94,9 @@ module RuboCop
|
|
75
94
|
redundant_splat_expansion(node) do
|
76
95
|
if array_splat?(node) &&
|
77
96
|
(method_argument?(node) || part_of_an_array?(node))
|
97
|
+
return if allow_percent_literal_array_argument? &&
|
98
|
+
use_percent_literal_array_argument?(node)
|
99
|
+
|
78
100
|
add_offense(node, message: ARRAY_PARAM_MSG) do |corrector|
|
79
101
|
autocorrect(corrector, node)
|
80
102
|
end
|
@@ -170,6 +192,17 @@ module RuboCop
|
|
170
192
|
elements.join(', ')
|
171
193
|
end
|
172
194
|
end
|
195
|
+
|
196
|
+
def use_percent_literal_array_argument?(node)
|
197
|
+
argument = node.children.first
|
198
|
+
|
199
|
+
node.parent.send_type? &&
|
200
|
+
(argument.percent_literal?(:string) || argument.percent_literal?(:symbol))
|
201
|
+
end
|
202
|
+
|
203
|
+
def allow_percent_literal_array_argument?
|
204
|
+
cop_config.fetch('AllowPercentLiteralArrayArgument', true)
|
205
|
+
end
|
173
206
|
end
|
174
207
|
end
|
175
208
|
end
|