rubocop 1.57.1 → 1.65.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/LICENSE.txt +1 -1
- data/README.md +4 -5
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +136 -19
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/config.rb +36 -12
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +9 -3
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +63 -16
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
- data/lib/rubocop/cop/cop.rb +20 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/documentation.rb +16 -6
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +53 -20
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +29 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
- data/lib/rubocop/cop/lint/empty_when.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +24 -17
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +14 -7
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +54 -6
- data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +7 -2
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +3 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +53 -12
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/class_length.rb +6 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +16 -12
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +34 -7
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +52 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +155 -21
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +21 -11
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +6 -15
- data/lib/rubocop/cop/style/exact_regexp_match.rb +4 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
- data/lib/rubocop/cop/style/hash_except.rb +10 -6
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +12 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +27 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -10
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +5 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +19 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +50 -19
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +7 -1
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +3 -4
- data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +8 -0
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/zero_length_predicate.rb +28 -24
- data/lib/rubocop/cop/team.rb +13 -0
- data/lib/rubocop/cop/util.rb +7 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +37 -14
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +7 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +14 -11
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/result_cache.rb +0 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +73 -16
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +14 -3
- data/lib/rubocop/server/cache.rb +11 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +4 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +8 -0
- metadata +27 -29
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -5,7 +5,8 @@ module RuboCop
|
|
|
5
5
|
module Lint
|
|
6
6
|
# Checks for redundant safe navigation calls.
|
|
7
7
|
# Use cases where a constant, named in camel case for classes and modules is `nil` are rare,
|
|
8
|
-
# and an offense is not detected when the receiver is a
|
|
8
|
+
# and an offense is not detected when the receiver is a constant. The detection also applies
|
|
9
|
+
# to literal receivers, except for `nil`.
|
|
9
10
|
#
|
|
10
11
|
# For all receivers, the `instance_of?`, `kind_of?`, `is_a?`, `eql?`, `respond_to?`,
|
|
11
12
|
# and `equal?` methods are checked by default.
|
|
@@ -50,6 +51,22 @@ module RuboCop
|
|
|
50
51
|
# # good - without `&.` this will always return `true`
|
|
51
52
|
# foo&.respond_to?(:to_a)
|
|
52
53
|
#
|
|
54
|
+
# # bad - for `nil`s conversion methods return default values for the type
|
|
55
|
+
# foo&.to_h || {}
|
|
56
|
+
# foo&.to_h { |k, v| [k, v] } || {}
|
|
57
|
+
# foo&.to_a || []
|
|
58
|
+
# foo&.to_i || 0
|
|
59
|
+
# foo&.to_f || 0.0
|
|
60
|
+
# foo&.to_s || ''
|
|
61
|
+
#
|
|
62
|
+
# # good
|
|
63
|
+
# foo.to_h
|
|
64
|
+
# foo.to_h { |k, v| [k, v] }
|
|
65
|
+
# foo.to_a
|
|
66
|
+
# foo.to_i
|
|
67
|
+
# foo.to_f
|
|
68
|
+
# foo.to_s
|
|
69
|
+
#
|
|
53
70
|
# @example AllowedMethods: [nil_safe_method]
|
|
54
71
|
# # bad
|
|
55
72
|
# do_something if attrs&.nil_safe_method(:[])
|
|
@@ -60,10 +77,10 @@ module RuboCop
|
|
|
60
77
|
#
|
|
61
78
|
class RedundantSafeNavigation < Base
|
|
62
79
|
include AllowedMethods
|
|
63
|
-
include RangeHelp
|
|
64
80
|
extend AutoCorrector
|
|
65
81
|
|
|
66
|
-
MSG = 'Redundant safe navigation detected.'
|
|
82
|
+
MSG = 'Redundant safe navigation detected, use `.` instead.'
|
|
83
|
+
MSG_LITERAL = 'Redundant safe navigation with default literal detected.'
|
|
67
84
|
|
|
68
85
|
NIL_SPECIFIC_METHODS = (nil.methods - Object.new.methods).to_set.freeze
|
|
69
86
|
|
|
@@ -74,20 +91,51 @@ module RuboCop
|
|
|
74
91
|
(csend _ :respond_to? (sym %NIL_SPECIFIC_METHODS))
|
|
75
92
|
PATTERN
|
|
76
93
|
|
|
94
|
+
# @!method conversion_with_default?(node)
|
|
95
|
+
def_node_matcher :conversion_with_default?, <<~PATTERN
|
|
96
|
+
{
|
|
97
|
+
(or $(csend _ :to_h) (hash))
|
|
98
|
+
(or (block $(csend _ :to_h) ...) (hash))
|
|
99
|
+
(or $(csend _ :to_a) (array))
|
|
100
|
+
(or $(csend _ :to_i) (int 0))
|
|
101
|
+
(or $(csend _ :to_f) (float 0.0))
|
|
102
|
+
(or $(csend _ :to_s) (str empty?))
|
|
103
|
+
}
|
|
104
|
+
PATTERN
|
|
105
|
+
|
|
77
106
|
# rubocop:disable Metrics/AbcSize
|
|
78
107
|
def on_csend(node)
|
|
79
|
-
unless
|
|
108
|
+
unless assume_receiver_instance_exists?(node.receiver)
|
|
80
109
|
return unless check?(node) && allowed_method?(node.method_name)
|
|
81
110
|
return if respond_to_nil_specific_method?(node)
|
|
82
111
|
end
|
|
83
112
|
|
|
84
|
-
range =
|
|
85
|
-
add_offense(range) { |corrector| corrector.replace(
|
|
113
|
+
range = node.loc.dot
|
|
114
|
+
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def on_or(node)
|
|
118
|
+
conversion_with_default?(node) do |send_node|
|
|
119
|
+
range = send_node.loc.dot.begin.join(node.source_range.end)
|
|
120
|
+
|
|
121
|
+
add_offense(range, message: MSG_LITERAL) do |corrector|
|
|
122
|
+
corrector.replace(send_node.loc.dot, '.')
|
|
123
|
+
|
|
124
|
+
range_with_default = node.lhs.source_range.end.begin.join(node.source_range.end)
|
|
125
|
+
corrector.remove(range_with_default)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
86
128
|
end
|
|
87
129
|
# rubocop:enable Metrics/AbcSize
|
|
88
130
|
|
|
89
131
|
private
|
|
90
132
|
|
|
133
|
+
def assume_receiver_instance_exists?(receiver)
|
|
134
|
+
return true if receiver.const_type? && !receiver.source.match?(SNAKE_CASE)
|
|
135
|
+
|
|
136
|
+
receiver.literal? && !receiver.nil_type?
|
|
137
|
+
end
|
|
138
|
+
|
|
91
139
|
def check?(node)
|
|
92
140
|
parent = node.parent
|
|
93
141
|
return false unless parent
|
|
@@ -33,7 +33,10 @@ module RuboCop
|
|
|
33
33
|
MSG_EACH_WITH_INDEX = 'Use `each` instead of `each_with_index`.'
|
|
34
34
|
MSG_WITH_INDEX = 'Remove redundant `with_index`.'
|
|
35
35
|
|
|
36
|
+
# rubocop:disable Metrics/AbcSize
|
|
36
37
|
def on_block(node)
|
|
38
|
+
return unless node.receiver
|
|
39
|
+
return if node.method?(:with_index) && !node.receiver.receiver
|
|
37
40
|
return unless (send = redundant_with_index?(node))
|
|
38
41
|
|
|
39
42
|
range = with_index_range(send)
|
|
@@ -47,6 +50,7 @@ module RuboCop
|
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
end
|
|
53
|
+
# rubocop:enable Metrics/AbcSize
|
|
50
54
|
|
|
51
55
|
alias on_numblock on_block
|
|
52
56
|
|
|
@@ -56,10 +60,10 @@ module RuboCop
|
|
|
56
60
|
def_node_matcher :redundant_with_index?, <<~PATTERN
|
|
57
61
|
{
|
|
58
62
|
(block
|
|
59
|
-
$(
|
|
63
|
+
$(call _ {:each_with_index :with_index} ...)
|
|
60
64
|
(args (arg _)) ...)
|
|
61
65
|
(numblock
|
|
62
|
-
$(
|
|
66
|
+
$(call _ {:each_with_index :with_index} ...) 1 ...)
|
|
63
67
|
}
|
|
64
68
|
PATTERN
|
|
65
69
|
|
|
@@ -56,9 +56,9 @@ module RuboCop
|
|
|
56
56
|
def_node_matcher :redundant_with_object?, <<~PATTERN
|
|
57
57
|
{
|
|
58
58
|
(block
|
|
59
|
-
$(
|
|
59
|
+
$(call _ {:each_with_object :with_object} _) (args (arg _)) ...)
|
|
60
60
|
(numblock
|
|
61
|
-
$(
|
|
61
|
+
$(call _ {:each_with_object :with_object} _) 1 ...)
|
|
62
62
|
}
|
|
63
63
|
PATTERN
|
|
64
64
|
|
|
@@ -59,9 +59,7 @@ module RuboCop
|
|
|
59
59
|
|
|
60
60
|
def autocorrect(corrector, node)
|
|
61
61
|
rescued, _, _body = *node
|
|
62
|
-
range =
|
|
63
|
-
node.loc.keyword.end_pos,
|
|
64
|
-
rescued.source_range.end_pos)
|
|
62
|
+
range = node.loc.keyword.end.join(rescued.source_range.end)
|
|
65
63
|
|
|
66
64
|
corrector.replace(range, correction(*rescued))
|
|
67
65
|
end
|
|
@@ -45,10 +45,9 @@ module RuboCop
|
|
|
45
45
|
bad_method?(node) do |safe_nav, method|
|
|
46
46
|
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
node.source_range.end_pos)
|
|
48
|
+
begin_range = node.loc.dot || safe_nav.source_range.end
|
|
49
|
+
location = begin_range.join(node.source_range.end)
|
|
50
|
+
|
|
52
51
|
add_offense(location) do |corrector|
|
|
53
52
|
autocorrect(corrector, offense_range: location, send_node: node)
|
|
54
53
|
end
|
|
@@ -46,14 +46,14 @@ module RuboCop
|
|
|
46
46
|
message = format_message_from(processed_source)
|
|
47
47
|
|
|
48
48
|
add_offense(comment, message: message) do
|
|
49
|
-
autocorrect
|
|
49
|
+
autocorrect if autocorrect_requested?
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
|
-
def autocorrect
|
|
56
|
-
FileUtils.chmod('+x',
|
|
55
|
+
def autocorrect
|
|
56
|
+
FileUtils.chmod('+x', processed_source.file_path)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def executable?(processed_source)
|
|
@@ -10,11 +10,18 @@ module RuboCop
|
|
|
10
10
|
# foo = foo
|
|
11
11
|
# foo, bar = foo, bar
|
|
12
12
|
# Foo = Foo
|
|
13
|
+
# hash['foo'] = hash['foo']
|
|
14
|
+
# obj.attr = obj.attr
|
|
13
15
|
#
|
|
14
16
|
# # good
|
|
15
17
|
# foo = bar
|
|
16
18
|
# foo, bar = bar, foo
|
|
17
19
|
# Foo = Bar
|
|
20
|
+
# hash['foo'] = hash['bar']
|
|
21
|
+
# obj.attr = obj.attr2
|
|
22
|
+
#
|
|
23
|
+
# # good (method calls possibly can return different results)
|
|
24
|
+
# hash[foo] = hash[foo]
|
|
18
25
|
#
|
|
19
26
|
class SelfAssignment < Base
|
|
20
27
|
MSG = 'Self-assignment detected.'
|
|
@@ -26,6 +33,15 @@ module RuboCop
|
|
|
26
33
|
gvasgn: :gvar
|
|
27
34
|
}.freeze
|
|
28
35
|
|
|
36
|
+
def on_send(node)
|
|
37
|
+
if node.method?(:[]=)
|
|
38
|
+
handle_key_assignment(node) if node.arguments.size == 2
|
|
39
|
+
elsif node.assignment_method?
|
|
40
|
+
handle_attribute_assignment(node) if node.arguments.size == 1
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
alias on_csend on_send
|
|
44
|
+
|
|
29
45
|
def on_lvasgn(node)
|
|
30
46
|
lhs, rhs = *node
|
|
31
47
|
return unless rhs
|
|
@@ -72,6 +88,28 @@ module RuboCop
|
|
|
72
88
|
rhs.type == ASSIGNMENT_TYPE_TO_RHS_TYPE[lhs.type] &&
|
|
73
89
|
rhs.children.first == lhs.children.first
|
|
74
90
|
end
|
|
91
|
+
|
|
92
|
+
def handle_key_assignment(node)
|
|
93
|
+
value_node = node.arguments[1]
|
|
94
|
+
|
|
95
|
+
if value_node.send_type? && value_node.method?(:[]) &&
|
|
96
|
+
node.receiver == value_node.receiver &&
|
|
97
|
+
!node.first_argument.call_type? &&
|
|
98
|
+
node.first_argument == value_node.first_argument
|
|
99
|
+
add_offense(node)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def handle_attribute_assignment(node)
|
|
104
|
+
first_argument = node.first_argument
|
|
105
|
+
return unless first_argument.respond_to?(:arguments) && first_argument.arguments.empty?
|
|
106
|
+
|
|
107
|
+
if first_argument.call_type? &&
|
|
108
|
+
node.receiver == first_argument.receiver &&
|
|
109
|
+
first_argument.method_name.to_s == node.method_name.to_s.delete_suffix('=')
|
|
110
|
+
add_offense(node)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
75
113
|
end
|
|
76
114
|
end
|
|
77
115
|
end
|
|
@@ -123,6 +123,7 @@ module RuboCop
|
|
|
123
123
|
|
|
124
124
|
# Shorthand assignments always use their arguments
|
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
|
126
|
+
next false unless assignment_node.parent
|
|
126
127
|
|
|
127
128
|
node_within_block_or_conditional =
|
|
128
129
|
node_within_block_or_conditional?(assignment_node.parent, argument.scope.node)
|
|
@@ -19,6 +19,7 @@ module RuboCop
|
|
|
19
19
|
# 'underscored_string'.to_sym
|
|
20
20
|
# :'underscored_symbol'
|
|
21
21
|
# 'hyphenated-string'.to_sym
|
|
22
|
+
# "string_#{interpolation}".to_sym
|
|
22
23
|
#
|
|
23
24
|
# # good
|
|
24
25
|
# :string
|
|
@@ -26,6 +27,7 @@ module RuboCop
|
|
|
26
27
|
# :underscored_string
|
|
27
28
|
# :underscored_symbol
|
|
28
29
|
# :'hyphenated-string'
|
|
30
|
+
# :"string_#{interpolation}"
|
|
29
31
|
#
|
|
30
32
|
# @example EnforcedStyle: strict (default)
|
|
31
33
|
#
|
|
@@ -75,9 +77,12 @@ module RuboCop
|
|
|
75
77
|
|
|
76
78
|
def on_send(node)
|
|
77
79
|
return unless node.receiver
|
|
78
|
-
return unless node.receiver.str_type? || node.receiver.sym_type?
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
if node.receiver.str_type? || node.receiver.sym_type?
|
|
82
|
+
register_offense(node, correction: node.receiver.value.to_sym.inspect)
|
|
83
|
+
elsif node.receiver.dstr_type?
|
|
84
|
+
register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"")
|
|
85
|
+
end
|
|
81
86
|
end
|
|
82
87
|
|
|
83
88
|
def on_sym(node)
|
|
@@ -17,9 +17,12 @@ module RuboCop
|
|
|
17
17
|
private
|
|
18
18
|
|
|
19
19
|
def add_offense_from_diagnostic(diagnostic, ruby_version)
|
|
20
|
-
message =
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
message = if LSP.enabled?
|
|
21
|
+
diagnostic.message
|
|
22
|
+
else
|
|
23
|
+
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
|
24
|
+
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
|
25
|
+
end
|
|
23
26
|
add_offense(diagnostic.location, message: message, severity: diagnostic.level)
|
|
24
27
|
end
|
|
25
28
|
|
|
@@ -49,9 +49,7 @@ module RuboCop
|
|
|
49
49
|
return unless def_node
|
|
50
50
|
|
|
51
51
|
enum_conversion_call?(node) do |method_node, arguments|
|
|
52
|
-
next if method_node.
|
|
53
|
-
!method_node.method?(:__method__) && !method_node.method?(:__callee__)
|
|
54
|
-
next if method_name?(method_node, def_node.method_name) &&
|
|
52
|
+
next if !method_name?(method_node, def_node.method_name) ||
|
|
55
53
|
arguments_match?(arguments, def_node)
|
|
56
54
|
|
|
57
55
|
add_offense(node)
|
|
@@ -34,7 +34,7 @@ module RuboCop
|
|
|
34
34
|
MSG = 'Avoid leaving a trailing comma in attribute declarations.'
|
|
35
35
|
|
|
36
36
|
def on_send(node)
|
|
37
|
-
return unless node.attribute_accessor? && node.
|
|
37
|
+
return unless node.attribute_accessor? && node.last_argument.def_type?
|
|
38
38
|
|
|
39
39
|
trailing_comma = trailing_comma_range(node)
|
|
40
40
|
|
|
@@ -69,8 +69,8 @@ module RuboCop
|
|
|
69
69
|
# @!method reduce_with_block?(node)
|
|
70
70
|
def_node_matcher :reduce_with_block?, <<~PATTERN
|
|
71
71
|
{
|
|
72
|
-
(block (
|
|
73
|
-
(numblock (
|
|
72
|
+
(block (call _recv {:reduce :inject} ...) args ...)
|
|
73
|
+
(numblock (call _recv {:reduce :inject} ...) ...)
|
|
74
74
|
}
|
|
75
75
|
PATTERN
|
|
76
76
|
|
|
@@ -113,6 +113,7 @@ module RuboCop
|
|
|
113
113
|
PATTERN
|
|
114
114
|
|
|
115
115
|
def on_block(node)
|
|
116
|
+
return unless node.body
|
|
116
117
|
return unless reduce_with_block?(node)
|
|
117
118
|
return unless node.argument_list.length >= 2
|
|
118
119
|
|
|
@@ -71,7 +71,7 @@ module RuboCop
|
|
|
71
71
|
expressions.any? { |expr| flow_expression?(expr) }
|
|
72
72
|
when :if
|
|
73
73
|
check_if(node)
|
|
74
|
-
when :case
|
|
74
|
+
when :case, :case_match
|
|
75
75
|
check_case(node)
|
|
76
76
|
else
|
|
77
77
|
false
|
|
@@ -89,7 +89,9 @@ module RuboCop
|
|
|
89
89
|
return false unless else_branch
|
|
90
90
|
return false unless flow_expression?(else_branch)
|
|
91
91
|
|
|
92
|
-
node.
|
|
92
|
+
branches = node.case_type? ? node.when_branches : node.in_pattern_branches
|
|
93
|
+
|
|
94
|
+
branches.all? { |branch| branch.body && flow_expression?(branch.body) }
|
|
93
95
|
end
|
|
94
96
|
end
|
|
95
97
|
end
|
|
@@ -160,7 +160,7 @@ module RuboCop
|
|
|
160
160
|
break_statement && !preceded_by_continue_statement?(break_statement)
|
|
161
161
|
when :if
|
|
162
162
|
check_if(node)
|
|
163
|
-
when :case
|
|
163
|
+
when :case, :case_match
|
|
164
164
|
check_case(node)
|
|
165
165
|
else
|
|
166
166
|
false
|
|
@@ -178,7 +178,13 @@ module RuboCop
|
|
|
178
178
|
return false unless else_branch
|
|
179
179
|
return false unless break_statement?(else_branch)
|
|
180
180
|
|
|
181
|
-
|
|
181
|
+
branches = if node.case_type?
|
|
182
|
+
node.when_branches
|
|
183
|
+
else
|
|
184
|
+
node.in_pattern_branches
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
branches.all? { |branch| branch.body && break_statement?(branch.body) }
|
|
182
188
|
end
|
|
183
189
|
|
|
184
190
|
def preceded_by_continue_statement?(break_statement)
|
|
@@ -256,7 +256,7 @@ module RuboCop
|
|
|
256
256
|
|
|
257
257
|
def any_method_definition?(child)
|
|
258
258
|
cop_config.fetch('MethodCreatingMethods', []).any? do |m|
|
|
259
|
-
matcher_name = "#{m}_method?"
|
|
259
|
+
matcher_name = :"#{m}_method?"
|
|
260
260
|
unless respond_to?(matcher_name)
|
|
261
261
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
|
262
262
|
{def (send nil? :#{m} ...)}
|
|
@@ -279,7 +279,7 @@ module RuboCop
|
|
|
279
279
|
|
|
280
280
|
def any_context_creating_methods?(child)
|
|
281
281
|
cop_config.fetch('ContextCreatingMethods', []).any? do |m|
|
|
282
|
-
matcher_name = "#{m}_block?"
|
|
282
|
+
matcher_name = :"#{m}_block?"
|
|
283
283
|
unless respond_to?(matcher_name)
|
|
284
284
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
|
285
285
|
({block numblock} (send {nil? const} {:#{m}} ...) ...)
|
|
@@ -4,7 +4,7 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
6
|
# Checks for uses of `Integer#times` that will never yield
|
|
7
|
-
# (when the integer
|
|
7
|
+
# (when the integer ``<= 0``) or that will only ever yield once
|
|
8
8
|
# (`1.times`).
|
|
9
9
|
#
|
|
10
10
|
# @safety
|
|
@@ -64,7 +64,7 @@ module RuboCop
|
|
|
64
64
|
remove_node(corrector, node)
|
|
65
65
|
elsif !proc_name.empty?
|
|
66
66
|
autocorrect_block_pass(corrector, node, proc_name)
|
|
67
|
-
|
|
67
|
+
elsif node.block_type?
|
|
68
68
|
autocorrect_block(corrector, node)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
@@ -6,6 +6,16 @@ module RuboCop
|
|
|
6
6
|
# Checks for operators, variables, literals, lambda, proc and nonmutating
|
|
7
7
|
# methods used in void context.
|
|
8
8
|
#
|
|
9
|
+
# `each` blocks are allowed to prevent false positives.
|
|
10
|
+
# For example, the expression inside the `each` block below.
|
|
11
|
+
# It's not void, especially when the receiver is an `Enumerator`:
|
|
12
|
+
#
|
|
13
|
+
# [source,ruby]
|
|
14
|
+
# ----
|
|
15
|
+
# enumerator = [1, 2, 3].filter
|
|
16
|
+
# enumerator.each { |item| item >= 2 } #=> [2, 3]
|
|
17
|
+
# ----
|
|
18
|
+
#
|
|
9
19
|
# @example CheckForMethodsWithNoSideEffects: false (default)
|
|
10
20
|
# # bad
|
|
11
21
|
# def some_method
|
|
@@ -47,6 +57,7 @@ module RuboCop
|
|
|
47
57
|
|
|
48
58
|
OP_MSG = 'Operator `%<op>s` used in void context.'
|
|
49
59
|
VAR_MSG = 'Variable `%<var>s` used in void context.'
|
|
60
|
+
CONST_MSG = 'Constant `%<var>s` used in void context.'
|
|
50
61
|
LIT_MSG = 'Literal `%<lit>s` used in void context.'
|
|
51
62
|
SELF_MSG = '`self` used in void context.'
|
|
52
63
|
EXPRESSION_MSG = '`%<expression>s` used in void context.'
|
|
@@ -72,6 +83,7 @@ module RuboCop
|
|
|
72
83
|
return unless node.body && !node.body.begin_type?
|
|
73
84
|
return unless in_void_context?(node.body)
|
|
74
85
|
|
|
86
|
+
check_void_op(node.body) { node.method?(:each) }
|
|
75
87
|
check_expression(node.body)
|
|
76
88
|
end
|
|
77
89
|
|
|
@@ -87,11 +99,20 @@ module RuboCop
|
|
|
87
99
|
def check_begin(node)
|
|
88
100
|
expressions = *node
|
|
89
101
|
expressions.pop unless in_void_context?(node)
|
|
90
|
-
expressions.each
|
|
102
|
+
expressions.each do |expr|
|
|
103
|
+
check_void_op(expr) do
|
|
104
|
+
block_node = node.each_ancestor(:block).first
|
|
105
|
+
|
|
106
|
+
block_node&.method?(:each)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
check_expression(expr)
|
|
110
|
+
end
|
|
91
111
|
end
|
|
92
112
|
|
|
93
113
|
def check_expression(expr)
|
|
94
|
-
|
|
114
|
+
expr = expr.body if expr.if_type? && expr.modifier_form?
|
|
115
|
+
|
|
95
116
|
check_literal(expr)
|
|
96
117
|
check_var(expr)
|
|
97
118
|
check_self(expr)
|
|
@@ -101,8 +122,10 @@ module RuboCop
|
|
|
101
122
|
check_nonmutating(expr)
|
|
102
123
|
end
|
|
103
124
|
|
|
104
|
-
def check_void_op(node)
|
|
125
|
+
def check_void_op(node, &block)
|
|
126
|
+
node = node.children.first while node.begin_type?
|
|
105
127
|
return unless node.send_type? && OPERATORS.include?(node.method_name)
|
|
128
|
+
return if block && yield(node)
|
|
106
129
|
|
|
107
130
|
add_offense(node.loc.selector,
|
|
108
131
|
message: format(OP_MSG, op: node.method_name)) do |corrector|
|
|
@@ -113,20 +136,23 @@ module RuboCop
|
|
|
113
136
|
def check_var(node)
|
|
114
137
|
return unless node.variable? || node.const_type?
|
|
115
138
|
|
|
116
|
-
if node.const_type?
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
139
|
+
if node.const_type?
|
|
140
|
+
template = node.special_keyword? ? VAR_MSG : CONST_MSG
|
|
141
|
+
|
|
142
|
+
offense_range = node
|
|
143
|
+
message = format(template, var: node.source)
|
|
120
144
|
else
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
145
|
+
offense_range = node.loc.name
|
|
146
|
+
message = format(VAR_MSG, var: node.loc.name.source)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
add_offense(offense_range, message: message) do |corrector|
|
|
150
|
+
autocorrect_void_expression(corrector, node)
|
|
125
151
|
end
|
|
126
152
|
end
|
|
127
153
|
|
|
128
154
|
def check_literal(node)
|
|
129
|
-
return if !node
|
|
155
|
+
return if !entirely_literal?(node) || node.xstr_type? || node.range_type?
|
|
130
156
|
|
|
131
157
|
add_offense(node, message: format(LIT_MSG, lit: node.source)) do |corrector|
|
|
132
158
|
autocorrect_void_expression(corrector, node)
|
|
@@ -188,6 +214,8 @@ module RuboCop
|
|
|
188
214
|
end
|
|
189
215
|
|
|
190
216
|
def autocorrect_void_expression(corrector, node)
|
|
217
|
+
return if node.parent.if_type? && node.parent.modifier_form?
|
|
218
|
+
|
|
191
219
|
corrector.remove(range_with_surrounding_space(range: node.source_range, side: :left))
|
|
192
220
|
end
|
|
193
221
|
|
|
@@ -199,6 +227,19 @@ module RuboCop
|
|
|
199
227
|
end
|
|
200
228
|
corrector.replace(send_node.loc.selector, suggestion)
|
|
201
229
|
end
|
|
230
|
+
|
|
231
|
+
def entirely_literal?(node)
|
|
232
|
+
case node.type
|
|
233
|
+
when :array
|
|
234
|
+
node.each_value.all? { |value| entirely_literal?(value) }
|
|
235
|
+
when :hash
|
|
236
|
+
return false unless node.each_key.all? { |key| entirely_literal?(key) }
|
|
237
|
+
|
|
238
|
+
node.each_value.all? { |value| entirely_literal?(value) }
|
|
239
|
+
else
|
|
240
|
+
node.literal?
|
|
241
|
+
end
|
|
242
|
+
end
|
|
202
243
|
end
|
|
203
244
|
end
|
|
204
245
|
end
|
|
@@ -10,9 +10,9 @@ module RuboCop
|
|
|
10
10
|
#
|
|
11
11
|
# Interpreting ABC size:
|
|
12
12
|
#
|
|
13
|
-
# *
|
|
14
|
-
# * 18..30 unsatisfactory
|
|
15
|
-
# *
|
|
13
|
+
# * ``<= 17`` satisfactory
|
|
14
|
+
# * `18..30` unsatisfactory
|
|
15
|
+
# * `>` 30 dangerous
|
|
16
16
|
#
|
|
17
17
|
# You can have repeated "attributes" calls count as a single "branch".
|
|
18
18
|
# For this purpose, attributes are any method with no argument; no attempt
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Metrics
|
|
6
|
-
# Checks for excessive nesting of conditional and looping
|
|
7
|
-
# constructs.
|
|
6
|
+
# Checks for excessive nesting of conditional and looping constructs.
|
|
8
7
|
#
|
|
9
|
-
# You can configure if blocks are considered using the `CountBlocks`
|
|
10
|
-
#
|
|
11
|
-
# towards the nesting level. Set to `true` to
|
|
8
|
+
# You can configure if blocks are considered using the `CountBlocks` and `CountModifierForms`
|
|
9
|
+
# options. When both are set to `false` (the default) blocks and modifier forms are not
|
|
10
|
+
# counted towards the nesting level. Set them to `true` to include these in the nesting level
|
|
11
|
+
# calculation as well.
|
|
12
12
|
#
|
|
13
13
|
# The maximum level of nesting allowed is configurable.
|
|
14
14
|
class BlockNesting < Base
|
|
@@ -27,7 +27,7 @@ module RuboCop
|
|
|
27
27
|
|
|
28
28
|
def check_nesting_level(node, max, current_level)
|
|
29
29
|
if consider_node?(node)
|
|
30
|
-
current_level += 1
|
|
30
|
+
current_level += 1 if count_if_block?(node)
|
|
31
31
|
if current_level > max
|
|
32
32
|
self.max = current_level
|
|
33
33
|
unless part_of_ignored_node?(node)
|
|
@@ -41,6 +41,14 @@ module RuboCop
|
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def count_if_block?(node)
|
|
45
|
+
return true unless node.if_type?
|
|
46
|
+
return false if node.elsif?
|
|
47
|
+
return count_modifier_forms? if node.modifier_form?
|
|
48
|
+
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
44
52
|
def consider_node?(node)
|
|
45
53
|
return true if NESTING_BLOCKS.include?(node.type)
|
|
46
54
|
|
|
@@ -52,7 +60,11 @@ module RuboCop
|
|
|
52
60
|
end
|
|
53
61
|
|
|
54
62
|
def count_blocks?
|
|
55
|
-
cop_config
|
|
63
|
+
cop_config.fetch('CountBlocks', false)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def count_modifier_forms?
|
|
67
|
+
cop_config.fetch('CountModifierForms', false)
|
|
56
68
|
end
|
|
57
69
|
end
|
|
58
70
|
end
|
|
@@ -43,16 +43,16 @@ module RuboCop
|
|
|
43
43
|
types.map do |type|
|
|
44
44
|
case type
|
|
45
45
|
when :array
|
|
46
|
-
|
|
46
|
+
lambda(&:array_type?)
|
|
47
47
|
when :hash
|
|
48
|
-
|
|
48
|
+
lambda(&:hash_type?)
|
|
49
49
|
when :heredoc
|
|
50
50
|
->(node) { heredoc_node?(node) }
|
|
51
51
|
when :method_call
|
|
52
|
-
|
|
52
|
+
lambda(&:call_type?)
|
|
53
53
|
else
|
|
54
|
-
raise
|
|
55
|
-
|
|
54
|
+
raise Warning, "Unknown foldable type: #{type.inspect}. " \
|
|
55
|
+
"Valid foldable types are: #{FOLDABLE_TYPES.join(', ')}."
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|