rubocop 1.19.0 → 1.23.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 +129 -21
- data/lib/rubocop/config.rb +5 -0
- data/lib/rubocop/config_loader.rb +5 -3
- data/lib/rubocop/config_validator.rb +9 -1
- data/lib/rubocop/cop/base.rb +3 -3
- data/lib/rubocop/cop/bundler/gem_comment.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/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/date_assignment.rb +2 -10
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +1 -10
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +3 -12
- data/lib/rubocop/cop/gemspec/require_mfa.rb +146 -0
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +31 -24
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -10
- data/lib/rubocop/cop/generator.rb +14 -8
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +60 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/assignment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -3
- data/lib/rubocop/cop/layout/class_structure.rb +2 -1
- data/lib/rubocop/cop/layout/dot_position.rb +34 -5
- data/lib/rubocop/cop/layout/empty_comment.rb +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +22 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +7 -4
- data/lib/rubocop/cop/layout/end_alignment.rb +2 -3
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/hash_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/leading_comment_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +9 -7
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +3 -3
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +3 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -0
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +6 -5
- 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_before_comment.rb +1 -1
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +11 -5
- data/lib/rubocop/cop/layout/space_inside_parens.rb +74 -28
- 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 +11 -11
- 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/deprecated_constants.rb +3 -2
- data/lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb +24 -1
- data/lib/rubocop/cop/lint/else_layout.rb +10 -6
- 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 +16 -2
- 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_ruby2_keywords.rb +117 -0
- 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/parameter_lists.rb +5 -2
- 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/end_keyword_alignment.rb +1 -2
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +23 -1
- data/lib/rubocop/cop/mixin/gemspec_help.rb +30 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +3 -3
- data/lib/rubocop/cop/mixin/heredoc.rb +1 -3
- data/lib/rubocop/cop/mixin/multiline_element_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -2
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +9 -1
- data/lib/rubocop/cop/mixin/percent_array.rb +11 -3
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +9 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_body.rb +1 -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/file_name.rb +37 -4
- 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 +9 -4
- 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 +27 -6
- data/lib/rubocop/cop/style/empty_method.rb +2 -2
- data/lib/rubocop/cop/style/encoding.rb +26 -15
- 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/format_string_token.rb +2 -1
- 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_as_last_array_item.rb +11 -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 +14 -1
- 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/multiline_in_pattern_then.rb +1 -1
- data/lib/rubocop/cop/style/multiline_when_then.rb +1 -1
- 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/open_struct_use.rb +69 -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/parentheses_around_condition.rb +12 -2
- 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 +21 -7
- 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_begin.rb +25 -0
- 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 +23 -28
- 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 +139 -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/sole_nested_conditional.rb +4 -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_array.rb +3 -3
- 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/word_array.rb +3 -3
- 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 +15 -4
- data/lib/rubocop/cops_documentation_generator.rb +17 -5
- data/lib/rubocop/formatter/html_formatter.rb +5 -2
- data/lib/rubocop/formatter/json_formatter.rb +4 -1
- data/lib/rubocop/magic_comment.rb +44 -15
- data/lib/rubocop/options.rb +126 -112
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.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/rspec/parallel_formatter.rb +90 -0
- data/lib/rubocop/rspec/support.rb +1 -0
- data/lib/rubocop/runner.rb +2 -3
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop/yaml_duplication_checker.rb +1 -1
- data/lib/rubocop.rb +14 -2
- metadata +20 -5
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
#
|
7
|
+
# This cop checks for `IO.select` that is incompatible with Fiber Scheduler since Ruby 3.0.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
#
|
11
|
+
# # bad
|
12
|
+
# IO.select([io], [], [], timeout)
|
13
|
+
#
|
14
|
+
# # good
|
15
|
+
# io.wait_readable(timeout)
|
16
|
+
#
|
17
|
+
# # bad
|
18
|
+
# IO.select([], [io], [], timeout)
|
19
|
+
#
|
20
|
+
# # good
|
21
|
+
# io.wait_writable(timeout)
|
22
|
+
#
|
23
|
+
class IncompatibleIoSelectWithFiberScheduler < Base
|
24
|
+
extend AutoCorrector
|
25
|
+
|
26
|
+
MSG = 'Use `%<preferred>s` instead of `%<current>s`.'
|
27
|
+
RESTRICT_ON_SEND = %i[select].freeze
|
28
|
+
|
29
|
+
# @!method io_select(node)
|
30
|
+
def_node_matcher :io_select, <<~PATTERN
|
31
|
+
(send
|
32
|
+
(const {nil? cbase} :IO) :select $_ $_ {(array) nil} $...)
|
33
|
+
PATTERN
|
34
|
+
|
35
|
+
def on_send(node)
|
36
|
+
return unless (read, write, timeout = io_select(node))
|
37
|
+
return unless scheduler_compatible?(read, write) || scheduler_compatible?(write, read)
|
38
|
+
|
39
|
+
preferred = preferred_method(read, write, timeout)
|
40
|
+
message = format(MSG, preferred: preferred, current: node.source)
|
41
|
+
|
42
|
+
add_offense(node, message: message) do |corrector|
|
43
|
+
corrector.replace(node, preferred)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def scheduler_compatible?(io1, io2)
|
50
|
+
return false unless io1.array_type? && io1.values.size == 1
|
51
|
+
|
52
|
+
io2.array_type? ? io2.values.empty? : io2.nil_type?
|
53
|
+
end
|
54
|
+
|
55
|
+
def preferred_method(read, write, timeout)
|
56
|
+
timeout_argument = timeout.empty? ? '' : "(#{timeout[0].source})"
|
57
|
+
|
58
|
+
if read.array_type? && read.values[0]
|
59
|
+
"#{read.values[0].source}.wait_readable#{timeout_argument}"
|
60
|
+
else
|
61
|
+
"#{write.values[0].source}.wait_writable#{timeout_argument}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -5,6 +5,11 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for interpolation in a single quoted string.
|
7
7
|
#
|
8
|
+
# @safety
|
9
|
+
# This cop is generally safe, but is marked as unsafe because
|
10
|
+
# it is possible to actually intentionally have text inside
|
11
|
+
# `#{...}` in a single quoted string.
|
12
|
+
#
|
8
13
|
# @example
|
9
14
|
#
|
10
15
|
# # bad
|
@@ -5,9 +5,10 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for uses of `begin...end while/until something`.
|
7
7
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# loop body
|
8
|
+
# @safety
|
9
|
+
# The cop is unsafe because behaviour can change in some cases, including
|
10
|
+
# if a local variable inside the loop body is accessed outside of it, or if the
|
11
|
+
# loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).
|
11
12
|
#
|
12
13
|
# @example
|
13
14
|
#
|
@@ -14,7 +14,11 @@ module RuboCop
|
|
14
14
|
# `Dir.glob` and `Dir[]` sort globbed results by default in Ruby 3.0.
|
15
15
|
# So all bad cases are acceptable when Ruby 3.0 or higher are used.
|
16
16
|
#
|
17
|
-
# This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
17
|
+
# NOTE: This cop will be deprecated and removed when supporting only Ruby 3.0 and higher.
|
18
|
+
#
|
19
|
+
# @safety
|
20
|
+
# This cop is unsafe in the case where sorting files changes existing
|
21
|
+
# expected behaviour.
|
18
22
|
#
|
19
23
|
# @example
|
20
24
|
#
|
@@ -18,6 +18,11 @@ module RuboCop
|
|
18
18
|
# cop by default). Similarly, Rails' duration methods do not work well
|
19
19
|
# with `Integer()` and can be ignored with `IgnoredMethods`.
|
20
20
|
#
|
21
|
+
# @safety
|
22
|
+
# Autocorrection is unsafe because it is not guaranteed that the
|
23
|
+
# replacement `Kernel` methods are able to properly handle the
|
24
|
+
# input if it is not a standard class.
|
25
|
+
#
|
21
26
|
# @example
|
22
27
|
#
|
23
28
|
# # bad
|
@@ -25,6 +30,7 @@ module RuboCop
|
|
25
30
|
# '10'.to_i
|
26
31
|
# '10.2'.to_f
|
27
32
|
# '10'.to_c
|
33
|
+
# '1/3'.to_r
|
28
34
|
# ['1', '2', '3'].map(&:to_i)
|
29
35
|
# foo.try(:to_f)
|
30
36
|
# bar.send(:to_c)
|
@@ -34,6 +40,7 @@ module RuboCop
|
|
34
40
|
# Integer('10', 10)
|
35
41
|
# Float('10.2')
|
36
42
|
# Complex('10')
|
43
|
+
# Rational('1/3')
|
37
44
|
# ['1', '2', '3'].map { |i| Integer(i, 10) }
|
38
45
|
# foo.try { |i| Float(i) }
|
39
46
|
# bar.send { |i| Complex(i) }
|
@@ -54,12 +61,14 @@ module RuboCop
|
|
54
61
|
CONVERSION_METHOD_CLASS_MAPPING = {
|
55
62
|
to_i: "#{Integer.name}(%<number_object>s, 10)",
|
56
63
|
to_f: "#{Float.name}(%<number_object>s)",
|
57
|
-
to_c: "#{Complex.name}(%<number_object>s)"
|
64
|
+
to_c: "#{Complex.name}(%<number_object>s)",
|
65
|
+
to_r: "#{Rational.name}(%<number_object>s)"
|
58
66
|
}.freeze
|
59
67
|
MSG = 'Replace unsafe number conversion with number '\
|
60
68
|
'class parsing, instead of using '\
|
61
69
|
'`%<current>s`, use stricter '\
|
62
70
|
'`%<corrected_method>s`.'
|
71
|
+
CONVERSION_METHODS = %i[Integer Float Complex Rational to_i to_f to_c to_r].freeze
|
63
72
|
METHODS = CONVERSION_METHOD_CLASS_MAPPING.keys.map(&:inspect).join(' ')
|
64
73
|
|
65
74
|
# @!method to_method(node)
|
@@ -127,7 +136,8 @@ module RuboCop
|
|
127
136
|
end
|
128
137
|
|
129
138
|
def ignore_receiver?(receiver)
|
130
|
-
if receiver.
|
139
|
+
if receiver.numeric_type? || (receiver.send_type? &&
|
140
|
+
(conversion_method?(receiver.method_name) || ignored_method?(receiver.method_name)))
|
131
141
|
true
|
132
142
|
elsif (receiver = top_receiver(receiver))
|
133
143
|
receiver.const_type? && ignored_class?(receiver.const_name)
|
@@ -142,6 +152,10 @@ module RuboCop
|
|
142
152
|
receiver
|
143
153
|
end
|
144
154
|
|
155
|
+
def conversion_method?(method_name)
|
156
|
+
CONVERSION_METHODS.include?(method_name)
|
157
|
+
end
|
158
|
+
|
145
159
|
def ignored_classes
|
146
160
|
cop_config.fetch('IgnoredClasses', [])
|
147
161
|
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
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]
|
@@ -9,8 +9,10 @@ module RuboCop
|
|
9
9
|
# should always be the same. If constants are assigned in multiple
|
10
10
|
# locations, the result may vary depending on the order of `require`.
|
11
11
|
#
|
12
|
-
#
|
13
|
-
#
|
12
|
+
# @safety
|
13
|
+
# This cop is unsafe because code that is already conditionally
|
14
|
+
# assigning a constant may have its behaviour changed by
|
15
|
+
# auto-correction.
|
14
16
|
#
|
15
17
|
# @example
|
16
18
|
#
|
@@ -6,6 +6,23 @@ module RuboCop
|
|
6
6
|
# This cops looks for references of Regexp captures that are out of range
|
7
7
|
# and thus always returns nil.
|
8
8
|
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe because it is naive in how it determines what
|
11
|
+
# references are available based on the last encountered regexp, but
|
12
|
+
# it cannot handle some cases, such as conditional regexp matches, which
|
13
|
+
# leads to false positives, such as:
|
14
|
+
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# foo ? /(c)(b)/ =~ str : /(b)/ =~ str
|
18
|
+
# do_something if $2
|
19
|
+
# # $2 is defined for the first condition but not the second, however
|
20
|
+
# # the cop will mark this as an offense.
|
21
|
+
# ----
|
22
|
+
#
|
23
|
+
# This might be a good indication of code that should be refactored,
|
24
|
+
# however.
|
25
|
+
#
|
9
26
|
# @example
|
10
27
|
#
|
11
28
|
# /(foo)bar/ =~ 'foobar'
|
@@ -9,6 +9,16 @@ module RuboCop
|
|
9
9
|
# example, mistranslating an array of literals to percent string notation)
|
10
10
|
# rather than meant to be part of the resulting strings.
|
11
11
|
#
|
12
|
+
# @safety
|
13
|
+
# The cop is unsafe because the correction changes the values in the array
|
14
|
+
# and that might have been done purposely.
|
15
|
+
#
|
16
|
+
# [source,ruby]
|
17
|
+
# ----
|
18
|
+
# %w('foo', "bar") #=> ["'foo',", '"bar"']
|
19
|
+
# %w(foo bar) #=> ['foo', 'bar']
|
20
|
+
# ----
|
21
|
+
#
|
12
22
|
# @example
|
13
23
|
#
|
14
24
|
# # bad
|
@@ -13,6 +13,10 @@ module RuboCop
|
|
13
13
|
# `Exception`. Alternatively, make `Exception` a fully qualified class
|
14
14
|
# name with an explicit namespace.
|
15
15
|
#
|
16
|
+
# @safety
|
17
|
+
# This cop is unsafe because it will change the exception class being
|
18
|
+
# raised, which is a change in behaviour.
|
19
|
+
#
|
16
20
|
# @example
|
17
21
|
# # bad
|
18
22
|
# raise Exception, 'Error message here'
|
@@ -7,13 +7,14 @@ module RuboCop
|
|
7
7
|
# `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`, and `equal?` methods
|
8
8
|
# are checked by default. These are customizable with `AllowedMethods` option.
|
9
9
|
#
|
10
|
-
# This cop is marked as unsafe, because auto-correction can change the
|
11
|
-
# return type of the expression. An offending expression that previously
|
12
|
-
# could return `nil` will be auto-corrected to never return `nil`.
|
13
|
-
#
|
14
10
|
# In the example below, the safe navigation operator (`&.`) is unnecessary
|
15
11
|
# because `NilClass` has methods like `respond_to?` and `is_a?`.
|
16
12
|
#
|
13
|
+
# @safety
|
14
|
+
# This cop is unsafe, because auto-correction can change the return type of
|
15
|
+
# the expression. An offending expression that previously could return `nil`
|
16
|
+
# will be auto-corrected to never return `nil`.
|
17
|
+
#
|
17
18
|
# @example
|
18
19
|
# # bad
|
19
20
|
# do_something if attrs&.respond_to?(:[])
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for uses a file requiring itself with `require_relative`.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
#
|
10
|
+
# # bad
|
11
|
+
#
|
12
|
+
# # foo.rb
|
13
|
+
# require_relative 'foo'
|
14
|
+
# require_relative 'bar'
|
15
|
+
#
|
16
|
+
# # good
|
17
|
+
#
|
18
|
+
# # foo.rb
|
19
|
+
# require_relative 'bar'
|
20
|
+
#
|
21
|
+
class RequireRelativeSelfPath < Base
|
22
|
+
include RangeHelp
|
23
|
+
extend AutoCorrector
|
24
|
+
|
25
|
+
MSG = 'Remove the `require_relative` that requires itself.'
|
26
|
+
RESTRICT_ON_SEND = %i[require_relative].freeze
|
27
|
+
|
28
|
+
def on_send(node)
|
29
|
+
return unless (required_feature = node.first_argument)
|
30
|
+
return unless required_feature.respond_to?(:value)
|
31
|
+
return unless same_file?(processed_source.file_path, required_feature.value)
|
32
|
+
|
33
|
+
add_offense(node) do |corrector|
|
34
|
+
corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def same_file?(file_path, required_feature)
|
41
|
+
file_path == required_feature || remove_ext(file_path) == required_feature
|
42
|
+
end
|
43
|
+
|
44
|
+
def remove_ext(file_path)
|
45
|
+
File.basename(file_path, File.extname(file_path))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -10,7 +10,7 @@ module RuboCop
|
|
10
10
|
#
|
11
11
|
# NOTE: Shadowing of variables in block passed to `Ractor.new` is allowed
|
12
12
|
# because `Ractor` should not access outer variables.
|
13
|
-
# eg. following
|
13
|
+
# eg. following style is encouraged:
|
14
14
|
#
|
15
15
|
# worker_id, pipe = env
|
16
16
|
# Ractor.new(worker_id, pipe) do |worker_id, pipe|
|
@@ -143,7 +143,7 @@ module RuboCop
|
|
143
143
|
# Although some operators can be converted to symbols normally
|
144
144
|
# (ie. `:==`), these are not accepted as hash keys and will
|
145
145
|
# raise a syntax error (eg. `{ ==: ... }`). Therefore, if the
|
146
|
-
# symbol does not start with an
|
146
|
+
# symbol does not start with an alphanumeric or underscore, it
|
147
147
|
# will be ignored.
|
148
148
|
return unless node.value.to_s.match?(/\A[a-z0-9_]/i)
|
149
149
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# This cop checks for "triple quotes" (strings
|
6
|
+
# This cop checks for "triple quotes" (strings delimited by any odd number
|
7
7
|
# of quotes greater than 1).
|
8
8
|
#
|
9
9
|
# Ruby allows multiple strings to be implicitly concatenated by just
|
@@ -13,14 +13,19 @@ module RuboCop
|
|
13
13
|
# Keyword arguments (including `**kwargs`) do not get counted towards
|
14
14
|
# this, as they are not used by the methods in question.
|
15
15
|
#
|
16
|
-
# NOTE: This cop matches for method names only and hence cannot tell apart
|
17
|
-
# methods with same name in different classes.
|
18
|
-
#
|
19
16
|
# Method names and their expected arity can be configured like this:
|
20
17
|
#
|
18
|
+
# [source,yaml]
|
19
|
+
# ----
|
21
20
|
# Methods:
|
22
21
|
# inject: 2
|
23
22
|
# reduce: 2
|
23
|
+
# ----
|
24
|
+
#
|
25
|
+
# @safety
|
26
|
+
# This cop matches for method names only and hence cannot tell apart
|
27
|
+
# methods with same name in different classes, which may lead to a
|
28
|
+
# false positive.
|
24
29
|
#
|
25
30
|
# @example
|
26
31
|
# # bad
|
@@ -87,9 +87,8 @@ module RuboCop
|
|
87
87
|
end
|
88
88
|
|
89
89
|
def ignored_method?(body)
|
90
|
-
cop_config['IgnoreEmptyMethods'] && body.nil? ||
|
91
|
-
cop_config['IgnoreNotImplementedMethods'] &&
|
92
|
-
not_implemented?(body)
|
90
|
+
(cop_config['IgnoreEmptyMethods'] && body.nil?) ||
|
91
|
+
(cop_config['IgnoreNotImplementedMethods'] && not_implemented?(body))
|
93
92
|
end
|
94
93
|
|
95
94
|
def message(variable)
|
@@ -6,8 +6,9 @@ module RuboCop
|
|
6
6
|
# This cop checks for useless method definitions, specifically: empty constructors
|
7
7
|
# and methods just delegating to `super`.
|
8
8
|
#
|
9
|
-
#
|
10
|
-
#
|
9
|
+
# @safety
|
10
|
+
# This cop is unsafe as it can register false positives for cases when an empty
|
11
|
+
# constructor just overrides the parent constructor, which is bad anyway.
|
11
12
|
#
|
12
13
|
# @example
|
13
14
|
# # bad
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# This cop looks for `ruby2_keywords` calls for methods that do not need it.
|
7
|
+
#
|
8
|
+
# `ruby2_keywords` should only be called on methods that accept an argument splat
|
9
|
+
# (`*args`) but do not explicit keyword arguments (`k:` or `k: true`) or
|
10
|
+
# a keyword splat (`**kwargs`).
|
11
|
+
#
|
12
|
+
# @example
|
13
|
+
# # good (splat argument without keyword arguments)
|
14
|
+
# ruby2_keywords def foo(*args); end
|
15
|
+
#
|
16
|
+
# # bad (no arguments)
|
17
|
+
# ruby2_keywords def foo; end
|
18
|
+
#
|
19
|
+
# # good
|
20
|
+
# def foo; end
|
21
|
+
#
|
22
|
+
# # bad (positional argument)
|
23
|
+
# ruby2_keywords def foo(arg); end
|
24
|
+
#
|
25
|
+
# # good
|
26
|
+
# def foo(arg); end
|
27
|
+
#
|
28
|
+
# # bad (double splatted argument)
|
29
|
+
# ruby2_keywords def foo(**args); end
|
30
|
+
#
|
31
|
+
# # good
|
32
|
+
# def foo(**args); end
|
33
|
+
#
|
34
|
+
# # bad (keyword arguments)
|
35
|
+
# ruby2_keywords def foo(i:, j:); end
|
36
|
+
#
|
37
|
+
# # good
|
38
|
+
# def foo(i:, j:); end
|
39
|
+
#
|
40
|
+
# # bad (splat argument with keyword arguments)
|
41
|
+
# ruby2_keywords def foo(*args, i:, j:); end
|
42
|
+
#
|
43
|
+
# # good
|
44
|
+
# def foo(*args, i:, j:); end
|
45
|
+
#
|
46
|
+
# # bad (splat argument with double splat)
|
47
|
+
# ruby2_keywords def foo(*args, **kwargs); end
|
48
|
+
#
|
49
|
+
# # good
|
50
|
+
# def foo(*args, **kwargs); end
|
51
|
+
#
|
52
|
+
# # bad (ruby2_keywords given a symbol)
|
53
|
+
# def foo; end
|
54
|
+
# ruby2_keywords :foo
|
55
|
+
#
|
56
|
+
# # good
|
57
|
+
# def foo; end
|
58
|
+
#
|
59
|
+
# # bad (ruby2_keywords with dynamic method)
|
60
|
+
# define_method(:foo) { |arg| }
|
61
|
+
# ruby2_keywords :foo
|
62
|
+
#
|
63
|
+
# # good
|
64
|
+
# define_method(:foo) { |arg| }
|
65
|
+
#
|
66
|
+
class UselessRuby2Keywords < Base
|
67
|
+
MSG = '`ruby2_keywords` is unnecessary for method `%<method_name>s`.'
|
68
|
+
RESTRICT_ON_SEND = %i[ruby2_keywords].freeze
|
69
|
+
|
70
|
+
# Looks for statically or dynamically defined methods with a given name
|
71
|
+
# @!method method_definition(node, method_name)
|
72
|
+
def_node_matcher :method_definition, <<~PATTERN
|
73
|
+
{
|
74
|
+
(def %1 ...)
|
75
|
+
({block numblock} (send _ :define_method (sym %1)) ...)
|
76
|
+
}
|
77
|
+
PATTERN
|
78
|
+
|
79
|
+
def on_send(node)
|
80
|
+
if node.first_argument.def_type?
|
81
|
+
inspect_def(node, node.first_argument)
|
82
|
+
elsif node.first_argument.sym_type?
|
83
|
+
inspect_sym(node, node.first_argument)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def inspect_def(node, def_node)
|
90
|
+
return if allowed_arguments(def_node.arguments)
|
91
|
+
|
92
|
+
add_offense(node.loc.selector, message: format(MSG, method_name: def_node.method_name))
|
93
|
+
end
|
94
|
+
|
95
|
+
def inspect_sym(node, sym_node)
|
96
|
+
return unless node.parent
|
97
|
+
|
98
|
+
method_name = sym_node.value
|
99
|
+
definition = node.parent.each_child_node.detect { |n| method_definition(n, method_name) }
|
100
|
+
|
101
|
+
return unless definition
|
102
|
+
return if allowed_arguments(definition.arguments)
|
103
|
+
|
104
|
+
add_offense(node, message: format(MSG, method_name: method_name))
|
105
|
+
end
|
106
|
+
|
107
|
+
# `ruby2_keywords` is only allowed if there's a `restarg` and no keyword arguments
|
108
|
+
def allowed_arguments(arguments)
|
109
|
+
return false if arguments.empty?
|
110
|
+
|
111
|
+
arguments.each_child_node(:restarg).any? &&
|
112
|
+
arguments.each_child_node(:kwarg, :kwoptarg, :kwrestarg).none?
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -5,11 +5,14 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# This cop checks for setter call to local variable as the final
|
7
7
|
# expression of a function definition.
|
8
|
-
# Its auto-correction is marked as unsafe because return value will be changed.
|
9
8
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
9
|
+
# @safety
|
10
|
+
# There are edge cases in which the local variable references a
|
11
|
+
# value that is also accessible outside the local scope. This is not
|
12
|
+
# detected by the cop, and it can yield a false positive.
|
13
|
+
#
|
14
|
+
# As well, auto-correction is unsafe because the method's
|
15
|
+
# return value will be changed.
|
13
16
|
#
|
14
17
|
# @example
|
15
18
|
#
|
@@ -7,8 +7,9 @@ module RuboCop
|
|
7
7
|
# (when the integer <= 0) or that will only ever yield once
|
8
8
|
# (`1.times`).
|
9
9
|
#
|
10
|
-
#
|
11
|
-
# is
|
10
|
+
# @safety
|
11
|
+
# This cop is unsafe as `times` returns its receiver, which is
|
12
|
+
# *usually* OK, but might change behavior.
|
12
13
|
#
|
13
14
|
# @example
|
14
15
|
# # bad
|
@@ -65,7 +66,7 @@ module RuboCop
|
|
65
66
|
private
|
66
67
|
|
67
68
|
def never_process?(count, node)
|
68
|
-
count < 1 || node.block_type? && node.body.nil?
|
69
|
+
count < 1 || (node.block_type? && node.body.nil?)
|
69
70
|
end
|
70
71
|
|
71
72
|
def remove_node(corrector, node)
|
@@ -8,6 +8,12 @@ module RuboCop
|
|
8
8
|
# (method calls), and conditions. See http://c2.com/cgi/wiki?AbcMetric
|
9
9
|
# and https://en.wikipedia.org/wiki/ABC_Software_Metric.
|
10
10
|
#
|
11
|
+
# Interpreting ABC size:
|
12
|
+
#
|
13
|
+
# * <= 17 satisfactory
|
14
|
+
# * 18..30 unsatisfactory
|
15
|
+
# * > 30 dangerous
|
16
|
+
#
|
11
17
|
# You can have repeated "attributes" calls count as a single "branch".
|
12
18
|
# For this purpose, attributes are any method with no argument; no attempt
|
13
19
|
# is meant to distinguish actual `attr_reader` from other methods.
|
@@ -9,6 +9,9 @@ module RuboCop
|
|
9
9
|
# Keyword arguments can optionally be excluded from the total count,
|
10
10
|
# as they add less complexity than positional or optional parameters.
|
11
11
|
#
|
12
|
+
# NOTE: Explicit block argument `&block` is not counted to prevent
|
13
|
+
# erroneous change that is avoided by making block argument implicit.
|
14
|
+
#
|
12
15
|
# @example Max: 3
|
13
16
|
# # good
|
14
17
|
# def foo(a, b, c = 1)
|
@@ -94,9 +97,9 @@ module RuboCop
|
|
94
97
|
|
95
98
|
def args_count(node)
|
96
99
|
if count_keyword_args?
|
97
|
-
node.children.
|
100
|
+
node.children.count { |a| !a.blockarg_type? }
|
98
101
|
else
|
99
|
-
node.children.count { |a| !NAMED_KEYWORD_TYPES.include?(a.type) }
|
102
|
+
node.children.count { |a| !NAMED_KEYWORD_TYPES.include?(a.type) && !a.blockarg_type? }
|
100
103
|
end
|
101
104
|
end
|
102
105
|
|
@@ -46,7 +46,7 @@ module RuboCop
|
|
46
46
|
visit_depth_last(@node) { |child| calculate_node(child) }
|
47
47
|
|
48
48
|
[
|
49
|
-
Math.sqrt(@assignment**2 + @branch**2 + @condition**2).round(2),
|
49
|
+
Math.sqrt((@assignment**2) + (@branch**2) + (@condition**2)).round(2),
|
50
50
|
"<#{@assignment}, #{@branch}, #{@condition}>"
|
51
51
|
]
|
52
52
|
end
|
@@ -147,7 +147,7 @@ module RuboCop
|
|
147
147
|
|
148
148
|
# Returns true for lines that shall not be included in the count.
|
149
149
|
def irrelevant_line?(source_line)
|
150
|
-
source_line.blank? || !count_comments? && comment_line?(source_line)
|
150
|
+
source_line.blank? || (!count_comments? && comment_line?(source_line))
|
151
151
|
end
|
152
152
|
|
153
153
|
def count_comments?
|