rubocop 1.21.0 → 1.22.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 +1 -1
- data/config/default.yml +43 -6
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +2 -0
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +1 -1
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +34 -11
- data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
- data/lib/rubocop/cop/correctors/ordered_gem_corrector.rb +11 -10
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +1 -1
- data/lib/rubocop/cop/generator.rb +14 -8
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +25 -2
- data/lib/rubocop/cop/layout/line_length.rb +7 -5
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -24
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +5 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +7 -7
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +7 -5
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +18 -5
- data/lib/rubocop/cop/lint/boolean_symbol.rb +5 -0
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +4 -4
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
- data/lib/rubocop/cop/lint/else_layout.rb +9 -5
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
- data/lib/rubocop/cop/lint/interpolation_check.rb +5 -0
- data/lib/rubocop/cop/lint/loop.rb +4 -3
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +5 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +5 -0
- data/lib/rubocop/cop/lint/numbered_parameter_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +4 -2
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +17 -0
- data/lib/rubocop/cop/lint/percent_string_array.rb +10 -0
- data/lib/rubocop/cop/lint/raise_exception.rb +4 -0
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +5 -4
- data/lib/rubocop/cop/lint/require_relative_self_path.rb +49 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +1 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/triple_quotes.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +8 -3
- data/lib/rubocop/cop/lint/useless_method_definition.rb +3 -2
- data/lib/rubocop/cop/lint/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/useless_times.rb +3 -2
- data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +5 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +6 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +5 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +7 -0
- data/lib/rubocop/cop/security/io_methods.rb +49 -0
- data/lib/rubocop/cop/security/json_load.rb +8 -7
- data/lib/rubocop/cop/security/open.rb +4 -0
- data/lib/rubocop/cop/security/yaml_load.rb +4 -0
- data/lib/rubocop/cop/style/and_or.rb +4 -3
- data/lib/rubocop/cop/style/arguments_forwarding.rb +13 -2
- data/lib/rubocop/cop/style/array_coercion.rb +21 -3
- data/lib/rubocop/cop/style/case_like_if.rb +5 -0
- data/lib/rubocop/cop/style/class_and_module_children.rb +9 -0
- data/lib/rubocop/cop/style/collection_compact.rb +7 -5
- data/lib/rubocop/cop/style/collection_methods.rb +6 -5
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +4 -1
- data/lib/rubocop/cop/style/date_time.rb +5 -0
- data/lib/rubocop/cop/style/double_negation.rb +15 -5
- data/lib/rubocop/cop/style/float_division.rb +10 -2
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +6 -1
- data/lib/rubocop/cop/style/global_std_stream.rb +4 -0
- data/lib/rubocop/cop/style/hash_each_methods.rb +5 -0
- data/lib/rubocop/cop/style/hash_transform_keys.rb +4 -6
- data/lib/rubocop/cop/style/hash_transform_values.rb +4 -6
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +18 -16
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +15 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +4 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +9 -2
- data/lib/rubocop/cop/style/line_end_concatenation.rb +13 -0
- data/lib/rubocop/cop/style/module_function.rb +8 -9
- data/lib/rubocop/cop/style/mutable_constant.rb +12 -7
- data/lib/rubocop/cop/style/numbered_parameters.rb +46 -0
- data/lib/rubocop/cop/style/numbered_parameters_limit.rb +50 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +7 -8
- data/lib/rubocop/cop/style/numeric_predicate.rb +5 -0
- data/lib/rubocop/cop/style/optional_arguments.rb +4 -0
- data/lib/rubocop/cop/style/optional_boolean_parameter.rb +14 -4
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
- data/lib/rubocop/cop/style/redundant_argument.rb +14 -7
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +4 -0
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +12 -3
- data/lib/rubocop/cop/style/redundant_freeze.rb +0 -1
- data/lib/rubocop/cop/style/redundant_self.rb +10 -0
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +4 -3
- data/lib/rubocop/cop/style/redundant_sort.rb +47 -29
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +106 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +5 -0
- data/lib/rubocop/cop/style/slicing_with_range.rb +13 -0
- data/lib/rubocop/cop/style/special_global_vars.rb +4 -0
- data/lib/rubocop/cop/style/static_class.rb +4 -3
- data/lib/rubocop/cop/style/string_chars.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +4 -0
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +3 -2
- data/lib/rubocop/cop/style/swap_values.rb +4 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +26 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +19 -0
- data/lib/rubocop/cop/style/yoda_condition.rb +20 -0
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
- data/lib/rubocop/cop/util.rb +2 -2
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +10 -5
@@ -7,26 +7,28 @@ module RuboCop
|
|
7
7
|
# each branch of a conditional expression. Such expressions should normally
|
8
8
|
# be placed outside the conditional expression - before or after it.
|
9
9
|
#
|
10
|
-
# This cop is marked unsafe auto-correction as the order of method invocations
|
11
|
-
# must be guaranteed in the following case:
|
12
|
-
#
|
13
|
-
# [source,ruby]
|
14
|
-
# ----
|
15
|
-
# if method_that_modifies_global_state # 1
|
16
|
-
# method_that_relies_on_global_state # 2
|
17
|
-
# foo # 3
|
18
|
-
# else
|
19
|
-
# method_that_relies_on_global_state # 2
|
20
|
-
# bar # 3
|
21
|
-
# end
|
22
|
-
# ----
|
23
|
-
#
|
24
|
-
# In such a case, auto-correction may change the invocation order.
|
25
|
-
#
|
26
10
|
# NOTE: The cop is poorly named and some people might think that it actually
|
27
11
|
# checks for duplicated conditional branches. The name will probably be changed
|
28
12
|
# in a future major RuboCop release.
|
29
13
|
#
|
14
|
+
# @safety
|
15
|
+
# Auto-correction is unsafe because changing the order of method invocations
|
16
|
+
# may change the behaviour of the code. For example:
|
17
|
+
#
|
18
|
+
# [source,ruby]
|
19
|
+
# ----
|
20
|
+
# if method_that_modifies_global_state # 1
|
21
|
+
# method_that_relies_on_global_state # 2
|
22
|
+
# foo # 3
|
23
|
+
# else
|
24
|
+
# method_that_relies_on_global_state # 2
|
25
|
+
# bar # 3
|
26
|
+
# end
|
27
|
+
# ----
|
28
|
+
#
|
29
|
+
# In this example, `method_that_relies_on_global_state` will be moved before
|
30
|
+
# `method_that_modifies_global_state`, which changes the behaviour of the program.
|
31
|
+
#
|
30
32
|
# @example
|
31
33
|
# # bad
|
32
34
|
# if condition
|
@@ -6,8 +6,10 @@ module RuboCop
|
|
6
6
|
# This cop checks for redundant `if` with boolean literal branches.
|
7
7
|
# It checks only conditions to return boolean value (`true` or `false`) for safe detection.
|
8
8
|
# The conditions to be checked are comparison methods, predicate methods, and double negative.
|
9
|
-
#
|
10
|
-
#
|
9
|
+
#
|
10
|
+
# @safety
|
11
|
+
# Auto-correction is unsafe because there is no guarantee that all predicate methods
|
12
|
+
# will return a boolean value. Those methods can be allowed with `AllowedMethods` config.
|
11
13
|
#
|
12
14
|
# @example
|
13
15
|
# # bad
|
@@ -23,6 +25,17 @@ module RuboCop
|
|
23
25
|
# # good
|
24
26
|
# foo == bar
|
25
27
|
#
|
28
|
+
# @example
|
29
|
+
# # bad
|
30
|
+
# if foo.do_something?
|
31
|
+
# true
|
32
|
+
# else
|
33
|
+
# false
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# # good (but potentially an unsafe correction)
|
37
|
+
# foo.do_something?
|
38
|
+
#
|
26
39
|
# @example AllowedMethods: ['nonzero?']
|
27
40
|
# # good
|
28
41
|
# num.nonzero? ? true : false
|
@@ -5,9 +5,10 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# Use `Kernel#loop` for infinite loops.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
8
|
+
# @safety
|
9
|
+
# This cop is unsafe as the rule should not necessarily apply if the loop
|
10
|
+
# body might raise a `StopIteration` exception; contrary to other infinite
|
11
|
+
# loops, `Kernel#loop` silently rescues that and returns `nil`.
|
11
12
|
#
|
12
13
|
# @example
|
13
14
|
# # bad
|
@@ -5,11 +5,18 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop check for usages of not (`not` or `!`) called on a method
|
7
7
|
# when an inverse of that method can be used instead.
|
8
|
+
#
|
8
9
|
# Methods that can be inverted by a not (`not` or `!`) should be defined
|
9
|
-
# in `InverseMethods
|
10
|
+
# in `InverseMethods`.
|
11
|
+
#
|
10
12
|
# Methods that are inverted by inverting the return
|
11
13
|
# of the block that is passed to the method should be defined in
|
12
|
-
# `InverseBlocks
|
14
|
+
# `InverseBlocks`.
|
15
|
+
#
|
16
|
+
# @safety
|
17
|
+
# This cop is unsafe because it cannot be guaranteed that the method
|
18
|
+
# and its inverse method are both defined on receiver, and also are
|
19
|
+
# actually inverse of each other.
|
13
20
|
#
|
14
21
|
# @example
|
15
22
|
# # bad
|
@@ -6,6 +6,19 @@ module RuboCop
|
|
6
6
|
# This cop checks for string literal concatenation at
|
7
7
|
# the end of a line.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because it cannot be guaranteed that the
|
11
|
+
# receiver is a string, in which case replacing `<<` with `\`
|
12
|
+
# would result in a syntax error.
|
13
|
+
#
|
14
|
+
# For example, this would be a false positive:
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# array << 'foo' <<
|
18
|
+
# 'bar' <<
|
19
|
+
# 'baz'
|
20
|
+
# ----
|
21
|
+
#
|
9
22
|
# @example
|
10
23
|
#
|
11
24
|
# # bad
|
@@ -6,7 +6,14 @@ module RuboCop
|
|
6
6
|
# This cop checks for use of `extend self` or `module_function` in a
|
7
7
|
# module.
|
8
8
|
#
|
9
|
-
# Supported styles are: module_function, extend_self, forbidden.
|
9
|
+
# Supported styles are: module_function, extend_self, forbidden. `forbidden`
|
10
|
+
# style prohibits the usage of both styles.
|
11
|
+
#
|
12
|
+
# NOTE: the cop won't be activated when the module contains any private methods.
|
13
|
+
#
|
14
|
+
# @safety
|
15
|
+
# Autocorrection is unsafe (and is disabled by default) because `extend self`
|
16
|
+
# and `module_function` do not behave exactly the same.
|
10
17
|
#
|
11
18
|
# @example EnforcedStyle: module_function (default)
|
12
19
|
# # bad
|
@@ -21,9 +28,6 @@ module RuboCop
|
|
21
28
|
# # ...
|
22
29
|
# end
|
23
30
|
#
|
24
|
-
# In case there are private methods, the cop won't be activated.
|
25
|
-
# Otherwise, it forces to change the flow of the default code.
|
26
|
-
#
|
27
31
|
# @example EnforcedStyle: module_function (default)
|
28
32
|
# # good
|
29
33
|
# module Test
|
@@ -46,8 +50,6 @@ module RuboCop
|
|
46
50
|
# # ...
|
47
51
|
# end
|
48
52
|
#
|
49
|
-
# The option `forbidden` prohibits the usage of both styles.
|
50
|
-
#
|
51
53
|
# @example EnforcedStyle: forbidden
|
52
54
|
# # bad
|
53
55
|
# module Test
|
@@ -68,9 +70,6 @@ module RuboCop
|
|
68
70
|
# private
|
69
71
|
# # ...
|
70
72
|
# end
|
71
|
-
#
|
72
|
-
# These offenses are not safe to auto-correct since there are different
|
73
|
-
# implications to each approach.
|
74
73
|
class ModuleFunction < Base
|
75
74
|
include ConfigurableEnforcedStyle
|
76
75
|
extend AutoCorrector
|
@@ -21,8 +21,17 @@ module RuboCop
|
|
21
21
|
#
|
22
22
|
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
|
23
23
|
#
|
24
|
-
# NOTE: From Ruby 3.0,
|
25
|
-
#
|
24
|
+
# NOTE: From Ruby 3.0, interpolated strings are not frozen when
|
25
|
+
# `# frozen-string-literal: true` is used, so this cop enforces explicit
|
26
|
+
# freezing for such strings.
|
27
|
+
#
|
28
|
+
# NOTE: From Ruby 3.0, this cop allows explicit freezing of constants when
|
29
|
+
# the `shareable_constant_value` directive is used.
|
30
|
+
#
|
31
|
+
# @safety
|
32
|
+
# This cop's autocorrection is unsafe since any mutations on objects that
|
33
|
+
# are made frozen will change from being accepted to raising `FrozenError`,
|
34
|
+
# and will need to be manually refactored.
|
26
35
|
#
|
27
36
|
# @example EnforcedStyle: literals (default)
|
28
37
|
# # bad
|
@@ -71,10 +80,6 @@ module RuboCop
|
|
71
80
|
# # shareable_constant_value: literal
|
72
81
|
# CONST = [1, 2, 3]
|
73
82
|
#
|
74
|
-
# NOTE: This special directive helps to create constants
|
75
|
-
# that hold only immutable objects, or Ractor-shareable
|
76
|
-
# constants. - ruby docs
|
77
|
-
#
|
78
83
|
class MutableConstant < Base
|
79
84
|
# Handles magic comment shareable_constant_value with O(n ^ 2) complexity
|
80
85
|
# n - number of lines in the source
|
@@ -93,7 +98,7 @@ module RuboCop
|
|
93
98
|
end
|
94
99
|
|
95
100
|
# Identifies the most recent magic comment with valid shareable constant values
|
96
|
-
#
|
101
|
+
# that's in scope for this node
|
97
102
|
def magic_comment_in_scope(node)
|
98
103
|
processed_source_till_node(node).reverse_each.find do |line|
|
99
104
|
MagicComment.parse(line).valid_shareable_constant_value?
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop checks for numbered parameters.
|
7
|
+
#
|
8
|
+
# It can either restrict the use of numbered parameters to
|
9
|
+
# single-lined blocks, or disallow completely numbered parameters.
|
10
|
+
#
|
11
|
+
# @example EnforcedStyle: allow_single_line (default)
|
12
|
+
# # bad
|
13
|
+
# collection.each do
|
14
|
+
# puts _1
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# collection.each { puts _1 }
|
19
|
+
#
|
20
|
+
# @example EnforcedStyle: disallow
|
21
|
+
# # bad
|
22
|
+
# collection.each { puts _1 }
|
23
|
+
#
|
24
|
+
# # good
|
25
|
+
# collection.each { |item| puts item }
|
26
|
+
#
|
27
|
+
class NumberedParameters < Base
|
28
|
+
include ConfigurableEnforcedStyle
|
29
|
+
extend TargetRubyVersion
|
30
|
+
|
31
|
+
MSG_DISALLOW = 'Avoid using numbered parameters.'
|
32
|
+
MSG_MULTI_LINE = 'Avoid using numbered parameters for multi-line blocks.'
|
33
|
+
|
34
|
+
minimum_target_ruby_version 2.7
|
35
|
+
|
36
|
+
def on_numblock(node)
|
37
|
+
if style == :disallow
|
38
|
+
add_offense(node, message: MSG_DISALLOW)
|
39
|
+
elsif node.multiline?
|
40
|
+
add_offense(node, message: MSG_MULTI_LINE)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Style
|
6
|
+
# This cop detects use of an excessive amount of numbered parameters in a
|
7
|
+
# single block. Having too many numbered parameters can make code too
|
8
|
+
# cryptic and hard to read.
|
9
|
+
#
|
10
|
+
# The cop defaults to registering an offense if there is more than 1 numbered
|
11
|
+
# parameter but this maximum can be configured by setting `Max`.
|
12
|
+
#
|
13
|
+
# @example Max: 1 (default)
|
14
|
+
# # bad
|
15
|
+
# foo { _1.call(_2, _3, _4) }
|
16
|
+
#
|
17
|
+
# # good
|
18
|
+
# foo { do_something(_1) }
|
19
|
+
class NumberedParametersLimit < Base
|
20
|
+
extend TargetRubyVersion
|
21
|
+
extend ExcludeLimit
|
22
|
+
|
23
|
+
DEFAULT_MAX_VALUE = 1
|
24
|
+
|
25
|
+
minimum_target_ruby_version 2.7
|
26
|
+
exclude_limit 'Max'
|
27
|
+
|
28
|
+
MSG = 'Avoid using more than %<max>i numbered %<parameter>s; %<count>i detected.'
|
29
|
+
|
30
|
+
def on_numblock(node)
|
31
|
+
_send_node, param_count, * = *node
|
32
|
+
return if param_count <= max_count
|
33
|
+
|
34
|
+
parameter = max_count > 1 ? 'parameters' : 'parameter'
|
35
|
+
message = format(MSG, max: max_count, parameter: parameter, count: param_count)
|
36
|
+
add_offense(node, message: message) { self.max = param_count }
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def max_count
|
42
|
+
max = cop_config.fetch('Max', DEFAULT_MAX_VALUE)
|
43
|
+
|
44
|
+
# Ruby does not allow more than 9 numbered parameters
|
45
|
+
[max, 9].min
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -58,18 +58,17 @@ module RuboCop
|
|
58
58
|
|
59
59
|
case int
|
60
60
|
when /^\d+$/
|
61
|
-
|
62
|
-
|
63
|
-
register_offense(node)
|
61
|
+
register_offense(node) { self.min_digits = int.size + 1 }
|
64
62
|
when /\d{4}/, short_group_regex
|
65
|
-
|
66
|
-
|
67
|
-
register_offense(node)
|
63
|
+
register_offense(node) { self.config_to_allow_offenses = { 'Enabled' => false } }
|
68
64
|
end
|
69
65
|
end
|
70
66
|
|
71
|
-
def register_offense(node)
|
72
|
-
add_offense(node)
|
67
|
+
def register_offense(node, &_block)
|
68
|
+
add_offense(node) do |corrector|
|
69
|
+
yield
|
70
|
+
corrector.replace(node, format_number(node))
|
71
|
+
end
|
73
72
|
end
|
74
73
|
|
75
74
|
def short_group_regex
|
@@ -16,6 +16,11 @@ module RuboCop
|
|
16
16
|
# populated with objects which can be compared with integers, but are
|
17
17
|
# not themselves `Integer` polymorphic.
|
18
18
|
#
|
19
|
+
# @safety
|
20
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
21
|
+
# defines the predicates or can be compared to a number, which may lead
|
22
|
+
# to a false positive for non-standard classes.
|
23
|
+
#
|
19
24
|
# @example EnforcedStyle: predicate (default)
|
20
25
|
# # bad
|
21
26
|
#
|
@@ -6,6 +6,10 @@ module RuboCop
|
|
6
6
|
# This cop checks for optional arguments to methods
|
7
7
|
# that do not come at the end of the argument list.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because changing a method signature will
|
11
|
+
# implicitly change behaviour.
|
12
|
+
#
|
9
13
|
# @example
|
10
14
|
# # bad
|
11
15
|
# def foo(a = 1, b, c)
|
@@ -7,6 +7,10 @@ module RuboCop
|
|
7
7
|
# boolean arguments when defining methods. `respond_to_missing?` method is allowed by default.
|
8
8
|
# These are customizable with `AllowedMethods` option.
|
9
9
|
#
|
10
|
+
# @safety
|
11
|
+
# This cop is unsafe because changing a method signature will
|
12
|
+
# implicitly change behaviour.
|
13
|
+
#
|
10
14
|
# @example
|
11
15
|
# # bad
|
12
16
|
# def some_method(bar = false)
|
@@ -33,8 +37,8 @@ module RuboCop
|
|
33
37
|
class OptionalBooleanParameter < Base
|
34
38
|
include AllowedMethods
|
35
39
|
|
36
|
-
MSG = '
|
37
|
-
|
40
|
+
MSG = 'Prefer keyword arguments for arguments with a boolean default value; ' \
|
41
|
+
'use `%<replacement>s` instead of `%<original>s`.'
|
38
42
|
|
39
43
|
def on_def(node)
|
40
44
|
return if allowed_method?(node.method_name)
|
@@ -42,11 +46,17 @@ module RuboCop
|
|
42
46
|
node.arguments.each do |arg|
|
43
47
|
next unless arg.optarg_type?
|
44
48
|
|
45
|
-
|
46
|
-
add_offense(arg) if BOOLEAN_TYPES.include?(value.type)
|
49
|
+
add_offense(arg, message: format_message(arg)) if arg.default_value.boolean_type?
|
47
50
|
end
|
48
51
|
end
|
49
52
|
alias on_defs on_def
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def format_message(argument)
|
57
|
+
source = argument.source
|
58
|
+
format(MSG, original: source, replacement: source.sub(/\s+=/, ':'))
|
59
|
+
end
|
50
60
|
end
|
51
61
|
end
|
52
62
|
end
|
@@ -3,10 +3,15 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Style
|
6
|
-
# This cop
|
7
|
-
# Hash#has_value
|
8
|
-
#
|
9
|
-
# names
|
6
|
+
# This cop checks for uses of methods `Hash#has_key?` and
|
7
|
+
# `Hash#has_value?`, and suggests using `Hash#key?` and `Hash#value?` instead.
|
8
|
+
#
|
9
|
+
# It is configurable to enforce the verbose method names, by using the
|
10
|
+
# `EnforcedStyle: verbose` configuration.
|
11
|
+
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
14
|
+
# is a `Hash` or responds to the replacement methods.
|
10
15
|
#
|
11
16
|
# @example EnforcedStyle: short (default)
|
12
17
|
# # bad
|
@@ -5,22 +5,29 @@ module RuboCop
|
|
5
5
|
module Style
|
6
6
|
# This cop checks for a redundant argument passed to certain methods.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# 1. This cop matches for method names only and hence cannot tell apart
|
11
|
-
# methods with same name in different classes.
|
12
|
-
# 2. This cop is limited to methods with single parameter.
|
13
|
-
# 3. This cop is unsafe if certain special global variables (e.g. `$;`, `$/`) are set.
|
14
|
-
# That depends on the nature of the target methods, of course.
|
8
|
+
# NOTE: This cop is limited to methods with single parameter.
|
15
9
|
#
|
16
10
|
# Method names and their redundant arguments can be configured like this:
|
17
11
|
#
|
12
|
+
# [source,yaml]
|
13
|
+
# ----
|
18
14
|
# Methods:
|
19
15
|
# join: ''
|
20
16
|
# split: ' '
|
21
17
|
# chomp: "\n"
|
22
18
|
# chomp!: "\n"
|
23
19
|
# foo: 2
|
20
|
+
# ----
|
21
|
+
#
|
22
|
+
# @safety
|
23
|
+
# This cop is unsafe because of the following limitations:
|
24
|
+
#
|
25
|
+
# 1. This cop matches by method names only and hence cannot tell apart
|
26
|
+
# methods with same name in different classes.
|
27
|
+
# 2. This cop may be unsafe if certain special global variables (e.g. `$;`, `$/`) are set.
|
28
|
+
# That depends on the nature of the target methods, of course. For example, the default
|
29
|
+
# argument to join is `$OUTPUT_FIELD_SEPARATOR` (or `$,`) rather than `''`, and if that
|
30
|
+
# global is changed, `''` is no longer a redundant argument.
|
24
31
|
#
|
25
32
|
# @example
|
26
33
|
# # bad
|
@@ -9,6 +9,10 @@ module RuboCop
|
|
9
9
|
# In such cases `fetch(key, value)` method is faster
|
10
10
|
# than `fetch(key) { value }`.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because it cannot be guaranteed that the receiver
|
14
|
+
# does not have a different implementation of `fetch`.
|
15
|
+
#
|
12
16
|
# @example SafeForConstants: false (default)
|
13
17
|
# # bad
|
14
18
|
# hash.fetch(:key) { 5 }
|
@@ -25,6 +25,7 @@ module RuboCop
|
|
25
25
|
# require_relative '../foo.so'
|
26
26
|
#
|
27
27
|
class RedundantFileExtensionInRequire < Base
|
28
|
+
include RangeHelp
|
28
29
|
extend AutoCorrector
|
29
30
|
|
30
31
|
MSG = 'Redundant `.rb` file extension detected.'
|
@@ -39,13 +40,21 @@ module RuboCop
|
|
39
40
|
require_call?(node) do |name_node|
|
40
41
|
return unless name_node.value.end_with?('.rb')
|
41
42
|
|
42
|
-
|
43
|
-
correction = name_node.value.delete_suffix('.rb')
|
43
|
+
extension_range = extension_range(name_node)
|
44
44
|
|
45
|
-
|
45
|
+
add_offense(extension_range) do |corrector|
|
46
|
+
corrector.remove(extension_range)
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def extension_range(name_node)
|
54
|
+
end_of_path_string = name_node.source_range.end_pos
|
55
|
+
|
56
|
+
range_between(end_of_path_string - 4, end_of_path_string - 1)
|
57
|
+
end
|
49
58
|
end
|
50
59
|
end
|
51
60
|
end
|
@@ -59,7 +59,6 @@ module RuboCop
|
|
59
59
|
(begin (send {float int} {:+ :- :* :** :/ :% :<<} _))
|
60
60
|
(begin (send !{(str _) array} {:+ :- :* :** :/ :%} {float int}))
|
61
61
|
(begin (send _ {:== :=== :!= :<= :>= :< :>} _))
|
62
|
-
(send (const {nil? cbase} :ENV) :[] _)
|
63
62
|
(send _ {:count :length :size} ...)
|
64
63
|
(block (send _ {:count :length :size} ...) ...)
|
65
64
|
}
|
@@ -100,6 +100,10 @@ module RuboCop
|
|
100
100
|
add_lhs_to_local_variables_scopes(rhs, lhs)
|
101
101
|
end
|
102
102
|
|
103
|
+
def on_in_pattern(node)
|
104
|
+
add_match_var_scopes(node)
|
105
|
+
end
|
106
|
+
|
103
107
|
def on_send(node)
|
104
108
|
return unless node.self_receiver? && regular_method_call?(node)
|
105
109
|
return if node.parent&.mlhs_type?
|
@@ -185,6 +189,12 @@ module RuboCop
|
|
185
189
|
add_lhs_to_local_variables_scopes(rhs, child.to_a.first)
|
186
190
|
end
|
187
191
|
end
|
192
|
+
|
193
|
+
def add_match_var_scopes(in_pattern_node)
|
194
|
+
in_pattern_node.each_descendant(:match_var) do |match_var_node|
|
195
|
+
@local_variables_scopes[in_pattern_node] << match_var_node.children.first
|
196
|
+
end
|
197
|
+
end
|
188
198
|
end
|
189
199
|
end
|
190
200
|
end
|
@@ -6,9 +6,10 @@ module RuboCop
|
|
6
6
|
# This cop checks for places where redundant assignments are made for in place
|
7
7
|
# modification methods.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe, because it can produce false positives for
|
11
|
+
# user defined methods having one of the expected names, but not modifying
|
12
|
+
# its receiver in place.
|
12
13
|
#
|
13
14
|
# @example
|
14
15
|
# # bad
|
@@ -12,6 +12,33 @@ module RuboCop
|
|
12
12
|
# `Enumerable#max_by` can replace `Enumerable#sort_by` calls
|
13
13
|
# after which only the first or last element is used.
|
14
14
|
#
|
15
|
+
# @safety
|
16
|
+
# This cop is unsafe, because `sort...last` and `max` may not return the
|
17
|
+
# same element in all cases.
|
18
|
+
#
|
19
|
+
# In an enumerable where there are multiple elements where `a <=> b == 0`,
|
20
|
+
# or where the transformation done by the `sort_by` block has the
|
21
|
+
# same result, `sort.last` and `max` (or `sort_by.last` and `max_by`)
|
22
|
+
# will return different elements. `sort.last` will return the last
|
23
|
+
# element but `max` will return the first element.
|
24
|
+
#
|
25
|
+
# For example:
|
26
|
+
#
|
27
|
+
# [source,ruby]
|
28
|
+
# ----
|
29
|
+
# class MyString < String; end
|
30
|
+
# strings = [MyString.new('test'), 'test']
|
31
|
+
# strings.sort.last.class #=> String
|
32
|
+
# strings.max.class #=> MyString
|
33
|
+
# ----
|
34
|
+
#
|
35
|
+
# [source,ruby]
|
36
|
+
# ----
|
37
|
+
# words = %w(dog horse mouse)
|
38
|
+
# words.sort_by { |word| word.length }.last #=> 'mouse'
|
39
|
+
# words.max_by { |word| word.length } #=> 'horse'
|
40
|
+
# ----
|
41
|
+
#
|
15
42
|
# @example
|
16
43
|
# # bad
|
17
44
|
# [2, 1, 3].sort.first
|
@@ -75,48 +102,39 @@ module RuboCop
|
|
75
102
|
MATCHER
|
76
103
|
|
77
104
|
def on_send(node)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
ancestor = node.parent
|
82
|
-
elsif (sort_node, sorter, accessor = redundant_sort?(node.parent&.parent))
|
83
|
-
return if use_size_method_in_block?(sort_node)
|
84
|
-
|
85
|
-
ancestor = node.parent.parent
|
86
|
-
else
|
87
|
-
return
|
88
|
-
end
|
105
|
+
ancestor, sort_node, sorter, accessor =
|
106
|
+
find_redundant_sort(node.parent, node.parent&.parent)
|
107
|
+
return unless ancestor
|
89
108
|
|
90
109
|
register_offense(ancestor, sort_node, sorter, accessor)
|
91
110
|
end
|
92
111
|
|
93
112
|
private
|
94
113
|
|
95
|
-
def
|
96
|
-
|
97
|
-
|
114
|
+
def find_redundant_sort(*nodes)
|
115
|
+
nodes.each do |node|
|
116
|
+
if (sort_node, sorter, accessor = redundant_sort?(node))
|
117
|
+
return [node, sort_node, sorter, accessor]
|
118
|
+
end
|
119
|
+
end
|
98
120
|
|
99
|
-
|
121
|
+
nil
|
100
122
|
end
|
101
123
|
|
102
|
-
def register_offense(
|
103
|
-
message = message(
|
124
|
+
def register_offense(node, sort_node, sorter, accessor)
|
125
|
+
message = message(node, sorter, accessor)
|
104
126
|
|
105
|
-
add_offense(offense_range(sort_node,
|
106
|
-
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
def autocorrect(corrector, node, sort_node, sorter, accessor)
|
111
|
-
# Remove accessor, e.g. `first` or `[-1]`.
|
112
|
-
corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
|
127
|
+
add_offense(offense_range(sort_node, node), message: message) do |corrector|
|
128
|
+
# Remove accessor, e.g. `first` or `[-1]`.
|
129
|
+
corrector.remove(range_between(accessor_start(node), node.loc.expression.end_pos))
|
113
130
|
|
114
|
-
|
115
|
-
|
131
|
+
# Replace "sort" or "sort_by" with the appropriate min/max method.
|
132
|
+
corrector.replace(sort_node.loc.selector, suggestion(sorter, accessor, arg_value(node)))
|
133
|
+
end
|
116
134
|
end
|
117
135
|
|
118
|
-
def offense_range(sort_node,
|
119
|
-
range_between(sort_node.loc.selector.begin_pos,
|
136
|
+
def offense_range(sort_node, node)
|
137
|
+
range_between(sort_node.loc.selector.begin_pos, node.loc.expression.end_pos)
|
120
138
|
end
|
121
139
|
|
122
140
|
def message(node, sorter, accessor)
|