rubocop 1.19.1 → 1.22.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 +86 -14
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +4 -2
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_filename.rb +103 -0
- data/lib/rubocop/cop/bundler/insecure_protocol_source.rb +45 -21
- data/lib/rubocop/cop/bundler/ordered_gems.rb +3 -12
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +2 -2
- data/lib/rubocop/cop/correctors/line_break_corrector.rb +1 -1
- 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/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/class_structure.rb +2 -1
- data/lib/rubocop/cop/layout/dot_position.rb +31 -4
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +8 -6
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +15 -4
- data/lib/rubocop/cop/layout/space_after_not.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_equals_in_parameter_default.rb +2 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +2 -2
- data/lib/rubocop/cop/layout/space_before_brackets.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -24
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +111 -0
- data/lib/rubocop/cop/lint/ambiguous_range.rb +8 -8
- 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/debugger.rb +2 -4
- 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/empty_in_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +12 -3
- data/lib/rubocop/cop/lint/incompatible_io_select_with_fiber_scheduler.rb +67 -0
- 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 +12 -1
- 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 +50 -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/unused_method_argument.rb +2 -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 +4 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +6 -0
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +1 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +57 -34
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/documentation_comment.rb +5 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -1
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- 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/mixin/preceding_following_alignment.rb +9 -1
- data/lib/rubocop/cop/mixin/string_literals_help.rb +5 -1
- data/lib/rubocop/cop/naming/ascii_identifiers.rb +0 -3
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/constant_name.rb +1 -1
- data/lib/rubocop/cop/naming/inclusive_language.rb +9 -9
- 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/accessor_grouping.rb +2 -2
- data/lib/rubocop/cop/style/and_or.rb +5 -0
- 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/ascii_comments.rb +0 -3
- data/lib/rubocop/cop/style/block_delimiters.rb +23 -6
- data/lib/rubocop/cop/style/case_equality.rb +6 -9
- 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 +8 -6
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/comment_annotation.rb +25 -39
- 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/document_dynamic_eval_definition.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +23 -8
- data/lib/rubocop/cop/style/double_negation.rb +15 -5
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/explicit_block_argument.rb +21 -11
- data/lib/rubocop/cop/style/float_division.rb +10 -2
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +7 -2
- 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_except.rb +4 -3
- 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 +18 -4
- 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/lambda_call.rb +1 -1
- data/lib/rubocop/cop/style/line_end_concatenation.rb +13 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +6 -6
- data/lib/rubocop/cop/style/module_function.rb +8 -9
- data/lib/rubocop/cop/style/mutable_constant.rb +73 -6
- data/lib/rubocop/cop/style/negated_if.rb +1 -1
- data/lib/rubocop/cop/style/negated_unless.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +2 -2
- data/lib/rubocop/cop/style/not.rb +2 -2
- 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/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +2 -2
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +9 -4
- data/lib/rubocop/cop/style/quoted_symbols.rb +10 -6
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +19 -9
- data/lib/rubocop/cop/style/redundant_condition.rb +2 -3
- 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 +4 -4
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_percent_q.rb +2 -3
- 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_self_assignment_branch.rb +1 -1
- data/lib/rubocop/cop/style/redundant_sort.rb +51 -18
- data/lib/rubocop/cop/style/regexp_literal.rb +3 -3
- data/lib/rubocop/cop/style/return_nil.rb +2 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +13 -2
- data/lib/rubocop/cop/style/select_by_regexp.rb +133 -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 +5 -5
- data/lib/rubocop/cop/style/string_chars.rb +4 -2
- data/lib/rubocop/cop/style/string_concatenation.rb +5 -1
- data/lib/rubocop/cop/style/string_hash_keys.rb +4 -0
- data/lib/rubocop/cop/style/struct_inheritance.rb +4 -0
- 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/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -7
- data/lib/rubocop/cop/style/zero_length_predicate.rb +6 -0
- data/lib/rubocop/cop/util.rb +4 -3
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/result_cache.rb +3 -3
- data/lib/rubocop/rspec/cop_helper.rb +1 -1
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/runner.rb +2 -3
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +10 -2
- metadata +17 -9
@@ -49,7 +49,7 @@ module RuboCop
|
|
49
49
|
return unless bad_method?(block) && semantically_except_method?(node, block)
|
50
50
|
|
51
51
|
except_key = except_key(block)
|
52
|
-
return
|
52
|
+
return if except_key.nil? || !safe_to_register_offense?(block, except_key)
|
53
53
|
|
54
54
|
range = offense_range(node)
|
55
55
|
preferred_method = "except(#{except_key.source})"
|
@@ -81,10 +81,11 @@ module RuboCop
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def except_key(node)
|
84
|
-
key_argument = node.argument_list.first
|
84
|
+
key_argument = node.argument_list.first.source
|
85
85
|
lhs, _method_name, rhs = *node.body
|
86
|
+
return if [lhs, rhs].map(&:source).none?(key_argument)
|
86
87
|
|
87
|
-
[lhs, rhs].find { |operand| operand.source != key_argument
|
88
|
+
[lhs, rhs].find { |operand| operand.source != key_argument }
|
88
89
|
end
|
89
90
|
|
90
91
|
def offense_range(node)
|
@@ -8,12 +8,10 @@ module RuboCop
|
|
8
8
|
# transforming the keys of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_keys` instead.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# This cop should only be enabled on Ruby version 2.5 or newer
|
16
|
-
# (`transform_keys` was added in Ruby 2.5.)
|
11
|
+
# @safety
|
12
|
+
# This cop is unsafe, as it can produce false positives if we are
|
13
|
+
# transforming an enumerable of key-value-like pairs that isn't actually
|
14
|
+
# a hash, e.g.: `[[k1, v1], [k2, v2], ...]`
|
17
15
|
#
|
18
16
|
# @example
|
19
17
|
# # bad
|
@@ -8,12 +8,10 @@ module RuboCop
|
|
8
8
|
# transforming the values of a hash, and tries to use a simpler & faster
|
9
9
|
# call to `transform_values` instead.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
# This cop should only be enabled on Ruby version 2.4 or newer
|
16
|
-
# (`transform_values` was added in Ruby 2.4.)
|
11
|
+
# @safety
|
12
|
+
# This cop is unsafe, as it can produce false positives if we are
|
13
|
+
# transforming an enumerable of key-value-like pairs that isn't actually
|
14
|
+
# a hash, e.g.: `[[k1, v1], [k2, v2], ...]`
|
17
15
|
#
|
18
16
|
# @example
|
19
17
|
# # bad
|
@@ -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
|
@@ -109,12 +122,13 @@ module RuboCop
|
|
109
122
|
end
|
110
123
|
|
111
124
|
def opposite_condition?(node)
|
112
|
-
!node.unless? && node.if_branch.false_type? ||
|
125
|
+
(!node.unless? && node.if_branch.false_type?) ||
|
126
|
+
(node.unless? && node.if_branch.true_type?)
|
113
127
|
end
|
114
128
|
|
115
129
|
def require_parentheses?(condition)
|
116
130
|
condition.and_type? || condition.or_type? ||
|
117
|
-
condition.send_type? && condition.comparison_method?
|
131
|
+
(condition.send_type? && condition.comparison_method?)
|
118
132
|
end
|
119
133
|
end
|
120
134
|
end
|
@@ -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
|
@@ -93,8 +93,8 @@ module RuboCop
|
|
93
93
|
parent = node.parent&.block_type? ? node.parent.parent : node.parent
|
94
94
|
parent &&
|
95
95
|
(logical_operator?(parent) ||
|
96
|
-
parent.send_type? &&
|
97
|
-
parent.arguments.any? { |argument| logical_operator?(argument) })
|
96
|
+
(parent.send_type? &&
|
97
|
+
parent.arguments.any? { |argument| logical_operator?(argument) }))
|
98
98
|
end
|
99
99
|
|
100
100
|
def call_in_optional_arguments?(node)
|
@@ -122,14 +122,14 @@ module RuboCop
|
|
122
122
|
|
123
123
|
def call_as_argument_or_chain?(node)
|
124
124
|
node.parent &&
|
125
|
-
(node.parent.send_type? && !assigned_before?(node.parent, node) ||
|
125
|
+
((node.parent.send_type? && !assigned_before?(node.parent, node)) ||
|
126
126
|
node.parent.csend_type? || node.parent.super_type? || node.parent.yield_type?)
|
127
127
|
end
|
128
128
|
|
129
129
|
def hash_literal_in_arguments?(node)
|
130
130
|
node.arguments.any? do |n|
|
131
131
|
hash_literal?(n) ||
|
132
|
-
n.send_type? && node.descendants.any? { |descendant| hash_literal?(descendant) }
|
132
|
+
(n.send_type? && node.descendants.any? { |descendant| hash_literal?(descendant) })
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
@@ -171,8 +171,8 @@ module RuboCop
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def unary_literal?(node)
|
174
|
-
node.numeric_type? && node.sign? ||
|
175
|
-
node.parent&.send_type? && node.parent&.unary_operation?
|
174
|
+
(node.numeric_type? && node.sign?) ||
|
175
|
+
(node.parent&.send_type? && node.parent&.unary_operation?)
|
176
176
|
end
|
177
177
|
|
178
178
|
def assigned_before?(node, target)
|
@@ -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
|
@@ -14,8 +14,25 @@ module RuboCop
|
|
14
14
|
# positives. Luckily, there is no harm in freezing an already
|
15
15
|
# frozen object.
|
16
16
|
#
|
17
|
+
# From Ruby 3.0, this cop honours the magic comment
|
18
|
+
# 'shareable_constant_value'. When this magic comment is set to any
|
19
|
+
# acceptable value other than none, it will suppress the offenses
|
20
|
+
# raised by this cop. It enforces frozen state.
|
21
|
+
#
|
17
22
|
# NOTE: Regexp and Range literals are frozen objects since Ruby 3.0.
|
18
23
|
#
|
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.
|
35
|
+
#
|
19
36
|
# @example EnforcedStyle: literals (default)
|
20
37
|
# # bad
|
21
38
|
# CONST = [1, 2, 3]
|
@@ -52,7 +69,55 @@ module RuboCop
|
|
52
69
|
# puts 1
|
53
70
|
# end
|
54
71
|
# end.freeze
|
72
|
+
#
|
73
|
+
# @example
|
74
|
+
# # Magic comment - shareable_constant_value: literal
|
75
|
+
#
|
76
|
+
# # bad
|
77
|
+
# CONST = [1, 2, 3]
|
78
|
+
#
|
79
|
+
# # good
|
80
|
+
# # shareable_constant_value: literal
|
81
|
+
# CONST = [1, 2, 3]
|
82
|
+
#
|
55
83
|
class MutableConstant < Base
|
84
|
+
# Handles magic comment shareable_constant_value with O(n ^ 2) complexity
|
85
|
+
# n - number of lines in the source
|
86
|
+
# Iterates over all lines before a CONSTANT
|
87
|
+
# until it reaches shareable_constant_value
|
88
|
+
module ShareableConstantValue
|
89
|
+
module_function
|
90
|
+
|
91
|
+
def recent_shareable_value?(node)
|
92
|
+
shareable_constant_comment = magic_comment_in_scope node
|
93
|
+
return false if shareable_constant_comment.nil?
|
94
|
+
|
95
|
+
shareable_constant_value = MagicComment.parse(shareable_constant_comment)
|
96
|
+
.shareable_constant_value
|
97
|
+
shareable_constant_value_enabled? shareable_constant_value
|
98
|
+
end
|
99
|
+
|
100
|
+
# Identifies the most recent magic comment with valid shareable constant values
|
101
|
+
# that's in scope for this node
|
102
|
+
def magic_comment_in_scope(node)
|
103
|
+
processed_source_till_node(node).reverse_each.find do |line|
|
104
|
+
MagicComment.parse(line).valid_shareable_constant_value?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def processed_source_till_node(node)
|
111
|
+
processed_source.lines[0..(node.last_line - 1)]
|
112
|
+
end
|
113
|
+
|
114
|
+
def shareable_constant_value_enabled?(value)
|
115
|
+
%w[literal experimental_everything experimental_copy].include? value
|
116
|
+
end
|
117
|
+
end
|
118
|
+
private_constant :ShareableConstantValue
|
119
|
+
|
120
|
+
include ShareableConstantValue
|
56
121
|
include FrozenStringLiteral
|
57
122
|
include ConfigurableEnforcedStyle
|
58
123
|
extend AutoCorrector
|
@@ -85,18 +150,18 @@ module RuboCop
|
|
85
150
|
return if immutable_literal?(value)
|
86
151
|
return if operation_produces_immutable_object?(value)
|
87
152
|
return if frozen_string_literal?(value)
|
153
|
+
return if shareable_constant_value?(value)
|
88
154
|
|
89
155
|
add_offense(value) { |corrector| autocorrect(corrector, value) }
|
90
156
|
end
|
91
157
|
|
92
158
|
def check(value)
|
93
159
|
range_enclosed_in_parentheses = range_enclosed_in_parentheses?(value)
|
94
|
-
|
95
160
|
return unless mutable_literal?(value) ||
|
96
|
-
target_ruby_version <= 2.7 && range_enclosed_in_parentheses
|
161
|
+
(target_ruby_version <= 2.7 && range_enclosed_in_parentheses)
|
97
162
|
|
98
|
-
return if
|
99
|
-
|
163
|
+
return if frozen_string_literal?(value)
|
164
|
+
return if shareable_constant_value?(value)
|
100
165
|
|
101
166
|
add_offense(value) { |corrector| autocorrect(corrector, value) }
|
102
167
|
end
|
@@ -126,8 +191,10 @@ module RuboCop
|
|
126
191
|
frozen_regexp_or_range_literals?(node) || node.immutable_literal?
|
127
192
|
end
|
128
193
|
|
129
|
-
def
|
130
|
-
|
194
|
+
def shareable_constant_value?(node)
|
195
|
+
return false if target_ruby_version < 3.0
|
196
|
+
|
197
|
+
recent_shareable_value? node
|
131
198
|
end
|
132
199
|
|
133
200
|
def frozen_regexp_or_range_literals?(node)
|
@@ -63,7 +63,7 @@ module RuboCop
|
|
63
63
|
|
64
64
|
def on_send(node)
|
65
65
|
return if ignored_node?(node) ||
|
66
|
-
!include_semantic_changes? && nil_comparison_style == 'comparison'
|
66
|
+
(!include_semantic_changes? && nil_comparison_style == 'comparison')
|
67
67
|
return unless register_offense?(node)
|
68
68
|
|
69
69
|
message = message(node)
|
@@ -87,7 +87,7 @@ module RuboCop
|
|
87
87
|
|
88
88
|
def register_offense?(node)
|
89
89
|
not_equal_to_nil?(node) ||
|
90
|
-
include_semantic_changes? && (not_and_nil_check?(node) || unless_and_nil_check?(node))
|
90
|
+
(include_semantic_changes? && (not_and_nil_check?(node) || unless_and_nil_check?(node)))
|
91
91
|
end
|
92
92
|
|
93
93
|
def autocorrect(corrector, node)
|
@@ -53,8 +53,8 @@ module RuboCop
|
|
53
53
|
|
54
54
|
def requires_parens?(child)
|
55
55
|
child.and_type? || child.or_type? ||
|
56
|
-
child.send_type? && child.binary_operation? ||
|
57
|
-
child.if_type? && child.ternary?
|
56
|
+
(child.send_type? && child.binary_operation?) ||
|
57
|
+
(child.if_type? && child.ternary?)
|
58
58
|
end
|
59
59
|
|
60
60
|
def correct_opposite_method(corrector, range, child)
|
@@ -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
|