rubocop 1.80.2 → 1.86.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/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/config/default.yml +170 -19
- data/config/obsoletion.yml +9 -0
- data/lib/rubocop/cache_config.rb +29 -0
- data/lib/rubocop/cli/command/auto_generate_config.rb +3 -3
- data/lib/rubocop/cli/command/lsp.rb +1 -1
- data/lib/rubocop/cli/command/mcp.rb +19 -0
- data/lib/rubocop/cli/command/show_cops.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +1 -1
- data/lib/rubocop/cli.rb +28 -6
- data/lib/rubocop/comment_config.rb +62 -17
- data/lib/rubocop/config.rb +14 -10
- data/lib/rubocop/config_finder.rb +1 -1
- data/lib/rubocop/config_loader.rb +20 -21
- data/lib/rubocop/config_loader_resolver.rb +9 -7
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -2
- data/lib/rubocop/config_store.rb +6 -1
- data/lib/rubocop/config_validator.rb +1 -1
- data/lib/rubocop/cop/autocorrect_logic.rb +8 -4
- data/lib/rubocop/cop/bundler/gem_version.rb +28 -28
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -2
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +22 -6
- data/lib/rubocop/cop/correctors/condition_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/percent_literal_corrector.rb +2 -2
- data/lib/rubocop/cop/documentation.rb +2 -3
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -2
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +10 -5
- data/lib/rubocop/cop/internal_affairs/example_heredoc_delimiter.rb +8 -8
- data/lib/rubocop/cop/internal_affairs/itblock_handler.rb +69 -0
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +28 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +9 -9
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/useless_message_assertion.rb +4 -4
- data/lib/rubocop/cop/internal_affairs.rb +1 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/array_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +3 -1
- data/lib/rubocop/cop/layout/class_structure.rb +13 -6
- data/lib/rubocop/cop/layout/dot_position.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +12 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +31 -13
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +12 -2
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +16 -2
- data/lib/rubocop/cop/layout/empty_lines_around_module_body.rb +16 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +8 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +34 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +26 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +7 -1
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +25 -25
- data/lib/rubocop/cop/layout/hash_alignment.rb +3 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +33 -3
- data/lib/rubocop/cop/layout/indentation_style.rb +1 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +111 -7
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +26 -9
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +57 -57
- data/lib/rubocop/cop/layout/multiline_assignment_layout.rb +9 -2
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +2 -0
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +56 -56
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +204 -39
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +6 -4
- data/lib/rubocop/cop/layout/parameter_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +13 -3
- data/lib/rubocop/cop/layout/space_after_comma.rb +2 -10
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +4 -2
- data/lib/rubocop/cop/layout/space_in_lambda_literal.rb +9 -8
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +47 -3
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +3 -2
- data/lib/rubocop/cop/lint/constant_reassignment.rb +59 -9
- data/lib/rubocop/cop/lint/constant_resolution.rb +1 -1
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +14 -8
- data/lib/rubocop/cop/lint/data_define_override.rb +63 -0
- data/lib/rubocop/cop/lint/debugger.rb +0 -2
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +4 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +4 -4
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -12
- data/lib/rubocop/cop/lint/else_layout.rb +19 -0
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +6 -1
- data/lib/rubocop/cop/lint/empty_in_pattern.rb +8 -1
- data/lib/rubocop/cop/lint/empty_interpolation.rb +11 -0
- data/lib/rubocop/cop/lint/empty_when.rb +8 -1
- data/lib/rubocop/cop/lint/float_comparison.rb +1 -1
- data/lib/rubocop/cop/lint/interpolation_check.rb +7 -2
- data/lib/rubocop/cop/lint/literal_as_condition.rb +5 -1
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +1 -1
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +16 -6
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +2 -0
- data/lib/rubocop/cop/lint/no_return_in_begin_end_blocks.rb +4 -0
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +23 -9
- data/lib/rubocop/cop/lint/redundant_cop_enable_directive.rb +0 -9
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +4 -2
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +23 -6
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +8 -2
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -4
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +17 -0
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +7 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +10 -2
- data/lib/rubocop/cop/lint/shadowed_argument.rb +7 -7
- data/lib/rubocop/cop/lint/struct_new_override.rb +17 -1
- data/lib/rubocop/cop/lint/syntax.rb +25 -1
- data/lib/rubocop/cop/lint/to_json.rb +12 -16
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -0
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -0
- data/lib/rubocop/cop/lint/unreachable_code.rb +5 -3
- data/lib/rubocop/cop/lint/unreachable_pattern_branch.rb +113 -0
- data/lib/rubocop/cop/lint/unused_method_argument.rb +10 -0
- data/lib/rubocop/cop/lint/useless_assignment.rb +45 -17
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +4 -4
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +2 -0
- data/lib/rubocop/cop/lint/useless_or.rb +15 -2
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +24 -9
- data/lib/rubocop/cop/lint/void.rb +39 -12
- data/lib/rubocop/cop/message_annotator.rb +1 -1
- data/lib/rubocop/cop/metrics/block_nesting.rb +23 -0
- data/lib/rubocop/cop/metrics/utils/abc_size_calculator.rb +4 -3
- data/lib/rubocop/cop/migration/department_name.rb +12 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +2 -2
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +4 -6
- data/lib/rubocop/cop/mixin/code_length.rb +1 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +5 -5
- data/lib/rubocop/cop/mixin/hash_transform_method/autocorrection.rb +63 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +10 -60
- data/lib/rubocop/cop/mixin/line_length_help.rb +21 -2
- data/lib/rubocop/cop/mixin/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +1 -1
- data/lib/rubocop/cop/mixin/space_after_punctuation.rb +5 -4
- data/lib/rubocop/cop/mixin/statement_modifier.rb +0 -6
- data/lib/rubocop/cop/mixin/trailing_comma.rb +8 -5
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +4 -2
- data/lib/rubocop/cop/naming/predicate_method.rb +27 -4
- data/lib/rubocop/cop/naming/predicate_prefix.rb +11 -11
- data/lib/rubocop/cop/offense.rb +9 -1
- data/lib/rubocop/cop/registry.rb +20 -13
- data/lib/rubocop/cop/security/eval.rb +15 -2
- data/lib/rubocop/cop/security/json_load.rb +33 -11
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +15 -4
- data/lib/rubocop/cop/style/accessor_grouping.rb +4 -2
- data/lib/rubocop/cop/style/alias.rb +4 -1
- data/lib/rubocop/cop/style/and_or.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +25 -7
- data/lib/rubocop/cop/style/array_intersect.rb +2 -2
- data/lib/rubocop/cop/style/array_intersect_with_single_element.rb +47 -0
- data/lib/rubocop/cop/style/array_join.rb +4 -2
- data/lib/rubocop/cop/style/ascii_comments.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +5 -2
- data/lib/rubocop/cop/style/bare_percent_literals.rb +4 -3
- data/lib/rubocop/cop/style/begin_block.rb +3 -1
- data/lib/rubocop/cop/style/block_delimiters.rb +27 -34
- data/lib/rubocop/cop/style/case_equality.rb +15 -13
- data/lib/rubocop/cop/style/class_and_module_children.rb +11 -2
- data/lib/rubocop/cop/style/collection_compact.rb +36 -16
- data/lib/rubocop/cop/style/colon_method_call.rb +3 -1
- data/lib/rubocop/cop/style/concat_array_literals.rb +2 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +8 -18
- data/lib/rubocop/cop/style/constant_visibility.rb +17 -12
- data/lib/rubocop/cop/style/copyright.rb +1 -1
- data/lib/rubocop/cop/style/documentation.rb +6 -6
- data/lib/rubocop/cop/style/documentation_method.rb +8 -8
- data/lib/rubocop/cop/style/double_negation.rb +1 -1
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/each_with_object.rb +2 -0
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_class_definition.rb +119 -0
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +0 -6
- data/lib/rubocop/cop/style/encoding.rb +7 -1
- data/lib/rubocop/cop/style/end_block.rb +3 -1
- data/lib/rubocop/cop/style/endless_method.rb +23 -5
- data/lib/rubocop/cop/style/explicit_block_argument.rb +1 -1
- data/lib/rubocop/cop/style/file_open.rb +84 -0
- data/lib/rubocop/cop/style/float_division.rb +15 -1
- data/lib/rubocop/cop/style/for.rb +3 -0
- data/lib/rubocop/cop/style/format_string_token.rb +49 -5
- data/lib/rubocop/cop/style/global_vars.rb +5 -2
- data/lib/rubocop/cop/style/guard_clause.rb +27 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +27 -9
- data/lib/rubocop/cop/style/hash_lookup_method.rb +101 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +1 -1
- data/lib/rubocop/cop/style/hash_transform_keys.rb +17 -7
- data/lib/rubocop/cop/style/hash_transform_values.rb +17 -7
- data/lib/rubocop/cop/style/if_inside_else.rb +1 -5
- data/lib/rubocop/cop/style/if_unless_modifier.rb +57 -17
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +12 -12
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +4 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/inline_comment.rb +4 -1
- data/lib/rubocop/cop/style/ip_addresses.rb +1 -2
- data/lib/rubocop/cop/style/lambda_call.rb +8 -8
- data/lib/rubocop/cop/style/magic_comment_format.rb +2 -2
- data/lib/rubocop/cop/style/map_join.rb +123 -0
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/require_parentheses.rb +15 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +17 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/module_member_existence_check.rb +107 -0
- data/lib/rubocop/cop/style/multiline_if_then.rb +4 -4
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -4
- data/lib/rubocop/cop/style/mutable_constant.rb +1 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +220 -0
- data/lib/rubocop/cop/style/nil_comparison.rb +11 -10
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +5 -11
- data/lib/rubocop/cop/style/not.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literals.rb +3 -2
- data/lib/rubocop/cop/style/one_class_per_file.rb +115 -0
- data/lib/rubocop/cop/style/one_line_conditional.rb +21 -12
- data/lib/rubocop/cop/style/operator_method_call.rb +11 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +6 -2
- data/lib/rubocop/cop/style/partition_instead_of_double_select.rb +270 -0
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +2 -0
- data/lib/rubocop/cop/style/predicate_with_kind.rb +84 -0
- data/lib/rubocop/cop/style/preferred_hash_methods.rb +12 -12
- data/lib/rubocop/cop/style/proc.rb +3 -2
- data/lib/rubocop/cop/style/raise_args.rb +1 -1
- data/lib/rubocop/cop/style/reduce_to_hash.rb +184 -0
- data/lib/rubocop/cop/style/redundant_argument.rb +2 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +3 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +5 -2
- data/lib/rubocop/cop/style/redundant_each.rb +3 -3
- data/lib/rubocop/cop/style/redundant_exception.rb +1 -1
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -1
- data/lib/rubocop/cop/style/redundant_format.rb +26 -5
- data/lib/rubocop/cop/style/redundant_interpolation.rb +11 -2
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +26 -10
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +16 -0
- data/lib/rubocop/cop/style/redundant_min_max_by.rb +93 -0
- data/lib/rubocop/cop/style/redundant_parentheses.rb +26 -22
- data/lib/rubocop/cop/style/redundant_percent_q.rb +5 -3
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +9 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +8 -0
- data/lib/rubocop/cop/style/redundant_return.rb +3 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +0 -5
- data/lib/rubocop/cop/style/redundant_sort.rb +7 -7
- data/lib/rubocop/cop/style/redundant_struct_keyword_init.rb +114 -0
- data/lib/rubocop/cop/style/reverse_find.rb +51 -0
- data/lib/rubocop/cop/style/safe_navigation.rb +7 -7
- data/lib/rubocop/cop/style/select_by_kind.rb +158 -0
- data/lib/rubocop/cop/style/select_by_range.rb +197 -0
- data/lib/rubocop/cop/style/select_by_regexp.rb +51 -21
- data/lib/rubocop/cop/style/semicolon.rb +25 -7
- data/lib/rubocop/cop/style/single_line_block_params.rb +2 -2
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +3 -1
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +8 -1
- data/lib/rubocop/cop/style/special_global_vars.rb +6 -1
- data/lib/rubocop/cop/style/super_arguments.rb +2 -2
- data/lib/rubocop/cop/style/symbol_proc.rb +4 -3
- data/lib/rubocop/cop/style/tally_method.rb +181 -0
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +45 -0
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_method_end_statement.rb +1 -0
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +11 -11
- data/lib/rubocop/cop/style/unless_else.rb +10 -9
- data/lib/rubocop/cop/style/yoda_expression.rb +1 -1
- data/lib/rubocop/cop/team.rb +4 -4
- data/lib/rubocop/cop/util.rb +2 -3
- data/lib/rubocop/cop/utils/format_string.rb +10 -0
- data/lib/rubocop/cop/variable_force/branch.rb +30 -6
- data/lib/rubocop/cops_documentation_generator.rb +4 -4
- data/lib/rubocop/directive_comment.rb +48 -4
- data/lib/rubocop/formatter/clang_style_formatter.rb +5 -2
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +2 -2
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/simple_text_formatter.rb +0 -2
- data/lib/rubocop/formatter/tap_formatter.rb +5 -2
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +1 -1
- data/lib/rubocop/formatter.rb +22 -21
- data/lib/rubocop/lsp/diagnostic.rb +18 -33
- data/lib/rubocop/lsp/disable_comment_edits.rb +135 -0
- data/lib/rubocop/lsp/routes.rb +12 -5
- data/lib/rubocop/lsp/runtime.rb +13 -3
- data/lib/rubocop/lsp/stdin_runner.rb +8 -17
- data/lib/rubocop/magic_comment.rb +20 -0
- data/lib/rubocop/mcp/server.rb +200 -0
- data/lib/rubocop/options.rb +10 -1
- data/lib/rubocop/path_util.rb +14 -2
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +10 -8
- data/lib/rubocop/result_cache.rb +60 -37
- data/lib/rubocop/rspec/cop_helper.rb +8 -0
- data/lib/rubocop/rspec/shared_contexts.rb +18 -5
- data/lib/rubocop/rspec/support.rb +2 -1
- data/lib/rubocop/runner.rb +12 -3
- data/lib/rubocop/server/cache.rb +6 -29
- data/lib/rubocop/server/core.rb +2 -0
- data/lib/rubocop/target_finder.rb +1 -1
- data/lib/rubocop/target_ruby.rb +31 -14
- data/lib/rubocop/version.rb +2 -2
- data/lib/rubocop.rb +20 -0
- data/lib/ruby_lsp/rubocop/addon.rb +23 -8
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +49 -15
- metadata +33 -9
|
@@ -9,9 +9,21 @@ module RuboCop
|
|
|
9
9
|
# cop disables on wide ranges of code, that latter contributors to
|
|
10
10
|
# a file wouldn't be aware of.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
12
|
+
# You can set `MaximumRangeSize` to define the maximum number of
|
|
13
|
+
# consecutive lines a cop can be disabled for.
|
|
14
|
+
#
|
|
15
|
+
# - `.inf` any size (default)
|
|
16
|
+
# - `0` allows only single-line disables
|
|
17
|
+
# - `1` means the maximum allowed is as follows:
|
|
18
|
+
#
|
|
19
|
+
# [source,ruby]
|
|
20
|
+
# ----
|
|
21
|
+
# # rubocop:disable SomeCop
|
|
22
|
+
# a = 1
|
|
23
|
+
# # rubocop:enable SomeCop
|
|
24
|
+
# ----
|
|
25
|
+
#
|
|
26
|
+
# @example MaximumRangeSize: .inf (default)
|
|
15
27
|
#
|
|
16
28
|
# # good
|
|
17
29
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -25,9 +37,7 @@ module RuboCop
|
|
|
25
37
|
# x= 0
|
|
26
38
|
# # EOF
|
|
27
39
|
#
|
|
28
|
-
# @example
|
|
29
|
-
# # Lint/MissingCopEnableDirective:
|
|
30
|
-
# # MaximumRangeSize: 2
|
|
40
|
+
# @example MaximumRangeSize: 2
|
|
31
41
|
#
|
|
32
42
|
# # good
|
|
33
43
|
# # rubocop:disable Layout/SpaceAroundOperators
|
|
@@ -31,6 +31,7 @@ module RuboCop
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
alias on_numblock on_block
|
|
34
|
+
alias on_itblock on_block
|
|
34
35
|
|
|
35
36
|
private
|
|
36
37
|
|
|
@@ -39,6 +40,7 @@ module RuboCop
|
|
|
39
40
|
{
|
|
40
41
|
(block (call _recv {:reduce :inject} !sym) _blockargs $(begin ...))
|
|
41
42
|
(numblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
43
|
+
(itblock (call _recv {:reduce :inject} !sym) _argscount $(begin ...))
|
|
42
44
|
}
|
|
43
45
|
PATTERN
|
|
44
46
|
|
|
@@ -65,7 +65,9 @@ module RuboCop
|
|
|
65
65
|
|
|
66
66
|
maximum_target_ruby_version 2.7
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
# NOTE: itblock is not handled because this cop is limited to Ruby <= 2.7
|
|
69
|
+
# via `maximum_target_ruby_version`, so itblock nodes (Ruby 3.4+) are never encountered.
|
|
70
|
+
def on_block(node) # rubocop:disable InternalAffairs/ItblockHandler
|
|
69
71
|
return unless node.body
|
|
70
72
|
return unless unsorted_dir_loop?(node.send_node)
|
|
71
73
|
|
|
@@ -162,7 +162,7 @@ module RuboCop
|
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
def allow_receiver?(receiver)
|
|
165
|
-
if receiver.numeric_type? || (receiver.
|
|
165
|
+
if receiver.numeric_type? || (receiver.call_type? &&
|
|
166
166
|
(conversion_method?(receiver.method_name) ||
|
|
167
167
|
allowed_method_name?(receiver.method_name)))
|
|
168
168
|
true
|
|
@@ -112,22 +112,36 @@ module RuboCop
|
|
|
112
112
|
|
|
113
113
|
def each_line_range(cop, line_ranges)
|
|
114
114
|
line_ranges.each_with_index do |line_range, line_range_index|
|
|
115
|
-
next if
|
|
116
|
-
next if expected_final_disable?(cop, line_range)
|
|
115
|
+
next if should_skip_line_range?(cop, line_range)
|
|
117
116
|
|
|
118
117
|
comment = processed_source.comment_at_line(line_range.begin)
|
|
119
|
-
|
|
120
|
-
find_redundant_all(line_range, line_ranges[line_range_index + 1])
|
|
121
|
-
elsif department_disabled?(cop, comment)
|
|
122
|
-
find_redundant_department(cop, line_range)
|
|
123
|
-
else
|
|
124
|
-
find_redundant_cop(cop, line_range)
|
|
125
|
-
end
|
|
118
|
+
next if skip_directive?(comment)
|
|
126
119
|
|
|
120
|
+
next_range = line_ranges[line_range_index + 1]
|
|
121
|
+
redundant = find_redundant_directive(cop, comment, line_range, next_range)
|
|
127
122
|
yield comment, redundant if redundant
|
|
128
123
|
end
|
|
129
124
|
end
|
|
130
125
|
|
|
126
|
+
def should_skip_line_range?(cop, line_range)
|
|
127
|
+
ignore_offense?(line_range) || expected_final_disable?(cop, line_range)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def skip_directive?(comment)
|
|
131
|
+
directive = DirectiveComment.new(comment)
|
|
132
|
+
directive.push? || directive.pop?
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def find_redundant_directive(cop, comment, line_range, next_range)
|
|
136
|
+
if all_disabled?(comment)
|
|
137
|
+
find_redundant_all(line_range, next_range)
|
|
138
|
+
elsif department_disabled?(cop, comment)
|
|
139
|
+
find_redundant_department(cop, line_range)
|
|
140
|
+
else
|
|
141
|
+
find_redundant_cop(cop, line_range)
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
131
145
|
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
132
146
|
def each_already_disabled(cop, line_ranges)
|
|
133
147
|
line_ranges.each_cons(2) do |previous_range, range|
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# The Lint/RedundantCopEnableDirective and Lint/RedundantCopDisableDirective
|
|
4
|
-
# cops need to be disabled so as to be able to provide a (bad) example of an
|
|
5
|
-
# unneeded enable.
|
|
6
|
-
|
|
7
|
-
# rubocop:disable Lint/RedundantCopEnableDirective
|
|
8
|
-
# rubocop:disable Lint/RedundantCopDisableDirective
|
|
9
3
|
module RuboCop
|
|
10
4
|
module Cop
|
|
11
5
|
module Lint
|
|
@@ -130,6 +124,3 @@ module RuboCop
|
|
|
130
124
|
end
|
|
131
125
|
end
|
|
132
126
|
end
|
|
133
|
-
|
|
134
|
-
# rubocop:enable Lint/RedundantCopDisableDirective
|
|
135
|
-
# rubocop:enable Lint/RedundantCopEnableDirective
|
|
@@ -19,7 +19,8 @@ module RuboCop
|
|
|
19
19
|
# * 2.2+ ... Add `rational` and `complex` above
|
|
20
20
|
# * 2.7+ ... Add `ruby2_keywords` above
|
|
21
21
|
# * 3.1+ ... Add `fiber` above
|
|
22
|
-
# * 3.2+ ... `set`
|
|
22
|
+
# * 3.2+ ... Add `set` above
|
|
23
|
+
# * 4.0+ ... Add `pathname` above
|
|
23
24
|
#
|
|
24
25
|
# This cop target those features.
|
|
25
26
|
#
|
|
@@ -69,7 +70,8 @@ module RuboCop
|
|
|
69
70
|
(target_ruby_version >= 2.2 && RUBY_22_LOADED_FEATURES.include?(feature_name)) ||
|
|
70
71
|
(target_ruby_version >= 2.7 && feature_name == 'ruby2_keywords') ||
|
|
71
72
|
(target_ruby_version >= 3.1 && feature_name == 'fiber') ||
|
|
72
|
-
(target_ruby_version >= 3.2 && feature_name == 'set')
|
|
73
|
+
(target_ruby_version >= 3.2 && feature_name == 'set') ||
|
|
74
|
+
(target_ruby_version >= 4.0 && feature_name == 'pathname')
|
|
73
75
|
end
|
|
74
76
|
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
75
77
|
end
|
|
@@ -62,6 +62,22 @@ module RuboCop
|
|
|
62
62
|
# do_something if attrs.respond_to?(:[])
|
|
63
63
|
#
|
|
64
64
|
# # bad
|
|
65
|
+
# foo&.bar ? foo&.bar.baz : qux
|
|
66
|
+
#
|
|
67
|
+
# # good
|
|
68
|
+
# foo&.bar ? foo.bar.baz : qux
|
|
69
|
+
#
|
|
70
|
+
# # bad
|
|
71
|
+
# if foo&.bar
|
|
72
|
+
# foo&.bar.baz
|
|
73
|
+
# end
|
|
74
|
+
#
|
|
75
|
+
# # good
|
|
76
|
+
# if foo&.bar
|
|
77
|
+
# foo.bar.baz
|
|
78
|
+
# end
|
|
79
|
+
#
|
|
80
|
+
# # bad
|
|
65
81
|
# while node&.is_a?(BeginNode)
|
|
66
82
|
# node = node.parent
|
|
67
83
|
# end
|
|
@@ -71,8 +87,9 @@ module RuboCop
|
|
|
71
87
|
# node = node.parent
|
|
72
88
|
# end
|
|
73
89
|
#
|
|
74
|
-
# # good - without `&.` this
|
|
90
|
+
# # good - without `&.` this changes the return value for `nil`
|
|
75
91
|
# foo&.respond_to?(:to_a)
|
|
92
|
+
# foo&.respond_to?(:class)
|
|
76
93
|
#
|
|
77
94
|
# # bad - for `nil`s conversion methods return default values for the type
|
|
78
95
|
# foo&.to_h || {}
|
|
@@ -151,15 +168,15 @@ module RuboCop
|
|
|
151
168
|
MSG_NON_NIL = 'Redundant safe navigation on non-nil receiver (detected by analyzing ' \
|
|
152
169
|
'previous code/method invocations).'
|
|
153
170
|
|
|
154
|
-
|
|
171
|
+
NIL_METHODS = nil.methods.to_set.freeze
|
|
155
172
|
|
|
156
173
|
SNAKE_CASE = /\A[[:digit:][:upper:]_]+\z/.freeze
|
|
157
174
|
|
|
158
175
|
GUARANTEED_INSTANCE_METHODS = %i[to_s to_i to_f to_a to_h].freeze
|
|
159
176
|
|
|
160
|
-
# @!method
|
|
161
|
-
def_node_matcher :
|
|
162
|
-
(csend _ :respond_to? (sym %
|
|
177
|
+
# @!method respond_to_nil_method?(node)
|
|
178
|
+
def_node_matcher :respond_to_nil_method?, <<~PATTERN
|
|
179
|
+
(csend _ :respond_to? (sym %NIL_METHODS))
|
|
163
180
|
PATTERN
|
|
164
181
|
|
|
165
182
|
# @!method conversion_with_default?(node)
|
|
@@ -189,7 +206,7 @@ module RuboCop
|
|
|
189
206
|
|
|
190
207
|
unless assume_receiver_instance_exists?(node.receiver)
|
|
191
208
|
return if !guaranteed_instance?(node.receiver) && !check?(node)
|
|
192
|
-
return if
|
|
209
|
+
return if respond_to_nil_method?(node)
|
|
193
210
|
end
|
|
194
211
|
|
|
195
212
|
add_offense(range) { |corrector| corrector.replace(range, '.') }
|
|
@@ -77,7 +77,7 @@ module RuboCop
|
|
|
77
77
|
PERCENT_CAPITAL_W = '%W'
|
|
78
78
|
PERCENT_I = '%i'
|
|
79
79
|
PERCENT_CAPITAL_I = '%I'
|
|
80
|
-
ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn].freeze
|
|
80
|
+
ASSIGNMENT_TYPES = %i[lvasgn ivasgn cvasgn gvasgn casgn].freeze
|
|
81
81
|
|
|
82
82
|
# @!method array_new?(node)
|
|
83
83
|
def_node_matcher :array_new?, <<~PATTERN
|
|
@@ -144,7 +144,9 @@ module RuboCop
|
|
|
144
144
|
expression = node.parent.source_range if node.parent.array_type?
|
|
145
145
|
[expression, variable.source]
|
|
146
146
|
elsif !variable.array_type?
|
|
147
|
-
|
|
147
|
+
replacement = variable.source
|
|
148
|
+
replacement = "[#{replacement}]" if wrap_in_brackets?(node)
|
|
149
|
+
[expression, replacement]
|
|
148
150
|
elsif redundant_brackets?(node)
|
|
149
151
|
[expression, remove_brackets(variable)]
|
|
150
152
|
else
|
|
@@ -176,6 +178,10 @@ module RuboCop
|
|
|
176
178
|
grandparent&.resbody_type?
|
|
177
179
|
end
|
|
178
180
|
|
|
181
|
+
def wrap_in_brackets?(node)
|
|
182
|
+
node.parent.array_type? && !node.parent.bracketed?
|
|
183
|
+
end
|
|
184
|
+
|
|
179
185
|
def remove_brackets(array)
|
|
180
186
|
array_start = array.loc.begin.source
|
|
181
187
|
elements = *array
|
|
@@ -24,10 +24,7 @@ module RuboCop
|
|
|
24
24
|
MSG = 'Avoid rescuing the `Exception` class. Perhaps you meant to rescue `StandardError`?'
|
|
25
25
|
|
|
26
26
|
def on_resbody(node)
|
|
27
|
-
return unless node.
|
|
28
|
-
|
|
29
|
-
rescue_args = node.children.first.children
|
|
30
|
-
return unless rescue_args.any? { |a| targets_exception?(a) }
|
|
27
|
+
return unless node.exceptions.any? { |exception| targets_exception?(exception) }
|
|
31
28
|
|
|
32
29
|
add_offense(node)
|
|
33
30
|
end
|
|
@@ -37,20 +37,25 @@ module RuboCop
|
|
|
37
37
|
}
|
|
38
38
|
PATTERN
|
|
39
39
|
|
|
40
|
+
# rubocop:disable Metrics/AbcSize
|
|
40
41
|
def on_send(node)
|
|
41
42
|
return unless require_safe_navigation?(node)
|
|
42
43
|
|
|
43
44
|
bad_method?(node) do |safe_nav, method|
|
|
44
45
|
return if nil_methods.include?(method) || PLUS_MINUS_METHODS.include?(node.method_name)
|
|
46
|
+
return if ternary_safe_navigation?(node, safe_nav)
|
|
45
47
|
|
|
46
48
|
begin_range = node.loc.dot || safe_nav.source_range.end
|
|
47
49
|
location = begin_range.join(node.source_range.end)
|
|
48
50
|
|
|
49
51
|
add_offense(location) do |corrector|
|
|
52
|
+
next if ternary_else_branch?(node, safe_nav)
|
|
53
|
+
|
|
50
54
|
autocorrect(corrector, offense_range: location, send_node: node)
|
|
51
55
|
end
|
|
52
56
|
end
|
|
53
57
|
end
|
|
58
|
+
# rubocop:enable Metrics/AbcSize
|
|
54
59
|
|
|
55
60
|
private
|
|
56
61
|
|
|
@@ -61,6 +66,18 @@ module RuboCop
|
|
|
61
66
|
parent.rhs != node || parent.lhs.receiver != parent.rhs.receiver
|
|
62
67
|
end
|
|
63
68
|
|
|
69
|
+
def ternary_safe_navigation?(node, safe_nav)
|
|
70
|
+
return false unless (parent = node.parent)
|
|
71
|
+
|
|
72
|
+
parent.if_type? && node.equal?(parent.if_branch) && parent.condition == safe_nav
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def ternary_else_branch?(node, safe_nav)
|
|
76
|
+
return false unless (parent = node.parent)
|
|
77
|
+
|
|
78
|
+
parent.if_type? && node.equal?(parent.else_branch) && parent.condition == safe_nav
|
|
79
|
+
end
|
|
80
|
+
|
|
64
81
|
# @param [Parser::Source::Range] offense_range
|
|
65
82
|
# @param [RuboCop::AST::SendNode] send_node
|
|
66
83
|
# @return [String]
|
|
@@ -3,10 +3,16 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Lint
|
|
6
|
-
#
|
|
6
|
+
# Checks that if safe navigation is used in an `&&` or `||` condition,
|
|
7
7
|
# consistent and appropriate safe navigation, without excess or deficiency,
|
|
8
8
|
# is used for all method calls on the same object.
|
|
9
9
|
#
|
|
10
|
+
# @safety
|
|
11
|
+
# Autocorrection is unsafe because if the receiver is not a local variable
|
|
12
|
+
# but a method call, it may not be idempotent. For example, replacing
|
|
13
|
+
# `foo&.bar` with `foo.bar` could raise `NoMethodError` if `foo` returns
|
|
14
|
+
# `nil` on a subsequent call.
|
|
15
|
+
#
|
|
10
16
|
# @example
|
|
11
17
|
# # bad
|
|
12
18
|
# foo&.bar && foo&.baz
|
|
@@ -23,7 +23,15 @@ module RuboCop
|
|
|
23
23
|
# # good (method calls possibly can return different results)
|
|
24
24
|
# hash[foo] = hash[foo]
|
|
25
25
|
#
|
|
26
|
-
# @example AllowRBSInlineAnnotation:
|
|
26
|
+
# @example AllowRBSInlineAnnotation: false (default)
|
|
27
|
+
# # bad
|
|
28
|
+
# foo = foo #: Integer
|
|
29
|
+
# foo, bar = foo, bar #: Integer
|
|
30
|
+
# Foo = Foo #: Integer
|
|
31
|
+
# hash['foo'] = hash['foo'] #: Integer
|
|
32
|
+
# obj.attr = obj.attr #: Integer
|
|
33
|
+
#
|
|
34
|
+
# @example AllowRBSInlineAnnotation: true
|
|
27
35
|
# # good
|
|
28
36
|
# foo = foo #: Integer
|
|
29
37
|
# foo, bar = foo, bar #: Integer
|
|
@@ -108,7 +116,7 @@ module RuboCop
|
|
|
108
116
|
value_node = node.last_argument
|
|
109
117
|
node_arguments = node.arguments[0...-1]
|
|
110
118
|
|
|
111
|
-
if value_node.
|
|
119
|
+
if value_node.respond_to?(:method?) && value_node.method?(:[]) &&
|
|
112
120
|
node.receiver == value_node.receiver &&
|
|
113
121
|
node_arguments.none?(&:call_type?) &&
|
|
114
122
|
node_arguments == value_node.arguments
|
|
@@ -125,13 +125,13 @@ module RuboCop
|
|
|
125
125
|
next false if assignment_node.shorthand_asgn?
|
|
126
126
|
next false unless assignment_node.parent
|
|
127
127
|
|
|
128
|
-
|
|
129
|
-
|
|
128
|
+
conditional_assignment =
|
|
129
|
+
conditional_assignment?(assignment_node.parent, argument.scope.node)
|
|
130
130
|
|
|
131
131
|
unless uses_var?(assignment_node, argument.name)
|
|
132
132
|
# It's impossible to decide whether a branch or block is executed,
|
|
133
133
|
# so the precise reassignment location is undecidable.
|
|
134
|
-
next false if
|
|
134
|
+
next false if conditional_assignment
|
|
135
135
|
|
|
136
136
|
yield(assignment.node, location_known)
|
|
137
137
|
break
|
|
@@ -147,13 +147,13 @@ module RuboCop
|
|
|
147
147
|
node.source_range.begin_pos
|
|
148
148
|
end
|
|
149
149
|
|
|
150
|
-
# Check whether the given node is
|
|
150
|
+
# Check whether the given node is always executed or not
|
|
151
151
|
#
|
|
152
|
-
def
|
|
152
|
+
def conditional_assignment?(node, stop_search_node)
|
|
153
153
|
return false if node == stop_search_node
|
|
154
154
|
|
|
155
|
-
node.conditional? || node.
|
|
156
|
-
|
|
155
|
+
node.conditional? || node.type?(:block, :rescue) ||
|
|
156
|
+
conditional_assignment?(node.parent, stop_search_node)
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
# Get argument references without assignments' references
|
|
@@ -26,7 +26,23 @@ module RuboCop
|
|
|
26
26
|
'and it may be unexpected.'
|
|
27
27
|
RESTRICT_ON_SEND = %i[new].freeze
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
# This is based on `Struct.instance_methods.sort` in Ruby 4.0.0.
|
|
30
|
+
STRUCT_METHOD_NAMES = %i[
|
|
31
|
+
! != !~ <=> == === [] []= __id__ __send__ all? any? chain chunk chunk_while class clone
|
|
32
|
+
collect collect_concat compact count cycle deconstruct deconstruct_keys
|
|
33
|
+
define_singleton_method detect dig display drop drop_while dup each each_cons each_entry
|
|
34
|
+
each_pair each_slice each_with_index each_with_object entries enum_for eql? equal? extend
|
|
35
|
+
filter filter_map find find_all find_index first flat_map freeze frozen? grep grep_v
|
|
36
|
+
group_by hash include? inject inspect instance_eval instance_exec instance_of?
|
|
37
|
+
instance_variable_defined? instance_variable_get instance_variable_set instance_variables
|
|
38
|
+
is_a? itself kind_of? lazy length map max max_by member? members method methods
|
|
39
|
+
min min_by minmax minmax_by nil? none? object_id one? partition private_methods
|
|
40
|
+
protected_methods public_method public_methods public_send reduce reject
|
|
41
|
+
remove_instance_variable respond_to? reverse_each select send singleton_class
|
|
42
|
+
singleton_method singleton_methods size slice_after slice_before slice_when sort sort_by
|
|
43
|
+
sum take take_while tally tap then to_a to_enum to_h to_s to_set uniq values values_at
|
|
44
|
+
yield_self zip
|
|
45
|
+
].freeze
|
|
30
46
|
STRUCT_MEMBER_NAME_TYPES = %i[sym str].freeze
|
|
31
47
|
|
|
32
48
|
# @!method struct_new(node)
|
|
@@ -26,7 +26,31 @@ module RuboCop
|
|
|
26
26
|
"#{diagnostic.message}\n(Using Ruby #{ruby_version} parser; " \
|
|
27
27
|
'configure using `TargetRubyVersion` parameter, under `AllCops`)'
|
|
28
28
|
end
|
|
29
|
-
|
|
29
|
+
location = diagnostic_location(diagnostic.location)
|
|
30
|
+
add_offense(location, message: message, severity: diagnostic.level)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Expand zero-length diagnostic ranges so that editors and formatters
|
|
34
|
+
# can display them. This typically occurs when the parser reports
|
|
35
|
+
# `unexpected token $end` at EOF.
|
|
36
|
+
def diagnostic_location(location)
|
|
37
|
+
return location if location.size.positive?
|
|
38
|
+
|
|
39
|
+
source_buffer = location.source_buffer
|
|
40
|
+
if location.end_pos < source_buffer.source.size
|
|
41
|
+
location.resize(1)
|
|
42
|
+
elsif location.begin_pos.positive?
|
|
43
|
+
location.adjust(begin_pos: -1)
|
|
44
|
+
else
|
|
45
|
+
location
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Override to skip multiline_ranges check which requires AST.
|
|
50
|
+
# Syntax errors mean the AST is nil, so we go directly to
|
|
51
|
+
# the EOL comment insertion path.
|
|
52
|
+
def disable_offense(offense_range)
|
|
53
|
+
disable_offense_with_eol_or_surround_comment(offense_range)
|
|
30
54
|
end
|
|
31
55
|
|
|
32
56
|
def add_offense_from_error(error)
|
|
@@ -5,27 +5,23 @@ module RuboCop
|
|
|
5
5
|
module Lint
|
|
6
6
|
# Checks to make sure `#to_json` includes an optional argument.
|
|
7
7
|
# When overriding `#to_json`, callers may invoke JSON
|
|
8
|
-
# generation via `JSON.generate(your_obj)`.
|
|
8
|
+
# generation via `JSON.generate(your_obj)`. Since `JSON#generate` allows
|
|
9
9
|
# for an optional argument, your method should too.
|
|
10
10
|
#
|
|
11
11
|
# @example
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
# def to_json
|
|
17
|
-
# JSON.generate([x, y])
|
|
18
|
-
# end
|
|
12
|
+
# # bad - incorrect arity
|
|
13
|
+
# def to_json
|
|
14
|
+
# JSON.generate([x, y])
|
|
15
|
+
# end
|
|
19
16
|
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
17
|
+
# # good - preserving args
|
|
18
|
+
# def to_json(*args)
|
|
19
|
+
# JSON.generate([x, y], *args)
|
|
20
|
+
# end
|
|
24
21
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
# end
|
|
22
|
+
# # good - discarding args
|
|
23
|
+
# def to_json(*_args)
|
|
24
|
+
# JSON.generate([x, y])
|
|
29
25
|
# end
|
|
30
26
|
#
|
|
31
27
|
class ToJSON < Base
|
|
@@ -32,6 +32,7 @@ module RuboCop
|
|
|
32
32
|
include RangeHelp
|
|
33
33
|
|
|
34
34
|
MSG = 'Avoid leaving a trailing comma in attribute declarations.'
|
|
35
|
+
RESTRICT_ON_SEND = %i[attr_reader attr_writer attr_accessor attr].freeze
|
|
35
36
|
|
|
36
37
|
def on_send(node)
|
|
37
38
|
return unless node.attribute_accessor? && node.last_argument.def_type?
|
|
@@ -78,6 +78,7 @@ module RuboCop
|
|
|
78
78
|
}
|
|
79
79
|
PATTERN
|
|
80
80
|
|
|
81
|
+
# rubocop:disable Metrics/MethodLength
|
|
81
82
|
def flow_expression?(node)
|
|
82
83
|
return report_on_flow_command?(node) if flow_command?(node)
|
|
83
84
|
|
|
@@ -89,12 +90,14 @@ module RuboCop
|
|
|
89
90
|
check_if(node)
|
|
90
91
|
when :case, :case_match
|
|
91
92
|
check_case(node)
|
|
92
|
-
when :def
|
|
93
|
+
when :def, :defs
|
|
93
94
|
register_redefinition(node)
|
|
95
|
+
false
|
|
94
96
|
else
|
|
95
97
|
false
|
|
96
98
|
end
|
|
97
99
|
end
|
|
100
|
+
# rubocop:enable Metrics/MethodLength
|
|
98
101
|
|
|
99
102
|
def check_if(node)
|
|
100
103
|
if_branch = node.if_branch
|
|
@@ -113,8 +116,7 @@ module RuboCop
|
|
|
113
116
|
end
|
|
114
117
|
|
|
115
118
|
def register_redefinition(node)
|
|
116
|
-
@redefined << node.method_name if redefinable_flow_method?
|
|
117
|
-
false
|
|
119
|
+
@redefined << node.method_name if redefinable_flow_method?(node.method_name)
|
|
118
120
|
end
|
|
119
121
|
|
|
120
122
|
def instance_eval_block?(node)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Lint
|
|
6
|
+
# Checks for unreachable `in` pattern branches in `case...in` statements.
|
|
7
|
+
#
|
|
8
|
+
# An `in` branch is unreachable when a previous branch uses an unguarded
|
|
9
|
+
# catch-all pattern that matches any value unconditionally. Any `in` branches
|
|
10
|
+
# (and `else`) that follow such a catch-all are dead code.
|
|
11
|
+
#
|
|
12
|
+
# A catch-all pattern is one of:
|
|
13
|
+
#
|
|
14
|
+
# * A bare variable capture (`in x`)
|
|
15
|
+
# * An underscore (`in _`)
|
|
16
|
+
# * A pattern alias where the left side is a catch-all (`in _ => y`)
|
|
17
|
+
# * An alternation pattern where at least one alternative is a catch-all
|
|
18
|
+
# (`in _ | Integer`)
|
|
19
|
+
#
|
|
20
|
+
# NOTE: A catch-all pattern with a guard clause (e.g., `in _ if condition`)
|
|
21
|
+
# does NOT make subsequent branches unreachable because the guard might
|
|
22
|
+
# not be satisfied.
|
|
23
|
+
#
|
|
24
|
+
# @example
|
|
25
|
+
#
|
|
26
|
+
# # bad
|
|
27
|
+
# case value
|
|
28
|
+
# in Integer
|
|
29
|
+
# handle_integer
|
|
30
|
+
# in x
|
|
31
|
+
# handle_other
|
|
32
|
+
# in String
|
|
33
|
+
# handle_string
|
|
34
|
+
# else
|
|
35
|
+
# handle_else
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# # good
|
|
39
|
+
# case value
|
|
40
|
+
# in Integer
|
|
41
|
+
# handle_integer
|
|
42
|
+
# in String
|
|
43
|
+
# handle_string
|
|
44
|
+
# in x
|
|
45
|
+
# handle_other
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# # bad - else is unreachable after catch-all
|
|
49
|
+
# case value
|
|
50
|
+
# in Integer
|
|
51
|
+
# handle_integer
|
|
52
|
+
# in _
|
|
53
|
+
# handle_other
|
|
54
|
+
# else
|
|
55
|
+
# handle_else
|
|
56
|
+
# end
|
|
57
|
+
#
|
|
58
|
+
# # good - guard clause means catch-all might not match
|
|
59
|
+
# case value
|
|
60
|
+
# in x if x.positive?
|
|
61
|
+
# handle_positive
|
|
62
|
+
# in Integer
|
|
63
|
+
# handle_integer
|
|
64
|
+
# else
|
|
65
|
+
# handle_other
|
|
66
|
+
# end
|
|
67
|
+
#
|
|
68
|
+
class UnreachablePatternBranch < Base
|
|
69
|
+
extend TargetRubyVersion
|
|
70
|
+
|
|
71
|
+
MSG = 'Unreachable `in` pattern branch detected.'
|
|
72
|
+
MSG_ELSE = 'Unreachable `else` branch detected.'
|
|
73
|
+
|
|
74
|
+
minimum_target_ruby_version 2.7
|
|
75
|
+
|
|
76
|
+
def on_case_match(case_node)
|
|
77
|
+
catch_all_found = false
|
|
78
|
+
|
|
79
|
+
case_node.in_pattern_branches.each do |in_pattern_node|
|
|
80
|
+
if catch_all_found
|
|
81
|
+
add_offense(in_pattern_node)
|
|
82
|
+
next
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
pattern = in_pattern_node.pattern
|
|
86
|
+
guard = in_pattern_node.children[1]
|
|
87
|
+
|
|
88
|
+
catch_all_found = true if catch_all_pattern?(pattern) && guard.nil?
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
return unless catch_all_found && case_node.else?
|
|
92
|
+
|
|
93
|
+
add_offense(case_node.loc.else, message: MSG_ELSE)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
def catch_all_pattern?(pattern)
|
|
99
|
+
case pattern.type
|
|
100
|
+
when :match_var
|
|
101
|
+
true
|
|
102
|
+
when :match_as, :begin
|
|
103
|
+
catch_all_pattern?(pattern.children[0])
|
|
104
|
+
when :match_alt
|
|
105
|
+
pattern.children.any? { |child| catch_all_pattern?(child) }
|
|
106
|
+
else
|
|
107
|
+
false
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|