rubocop 1.69.0 → 1.79.2
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 +23 -19
- data/config/default.yml +290 -65
- data/config/internal_affairs.yml +20 -0
- data/config/obsoletion.yml +8 -3
- data/lib/rubocop/cli/command/execute_runner.rb +3 -3
- data/lib/rubocop/cli/command/show_cops.rb +24 -2
- data/lib/rubocop/cli/command/suggest_extensions.rb +7 -1
- data/lib/rubocop/cli.rb +13 -2
- data/lib/rubocop/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +52 -10
- data/lib/rubocop/config_loader.rb +53 -47
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion/renamed_cop.rb +18 -3
- data/lib/rubocop/config_obsoletion.rb +46 -2
- data/lib/rubocop/config_validator.rb +25 -14
- data/lib/rubocop/cop/autocorrect_logic.rb +44 -39
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +1 -1
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +5 -2
- data/lib/rubocop/cop/gemspec/attribute_assignment.rb +91 -0
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +37 -15
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +1 -1
- data/lib/rubocop/cop/gemspec/require_mfa.rb +15 -1
- data/lib/rubocop/cop/generator.rb +6 -0
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +9 -5
- data/lib/rubocop/cop/internal_affairs/location_exists.rb +116 -0
- data/lib/rubocop/cop/internal_affairs/location_expression.rb +2 -1
- data/lib/rubocop/cop/internal_affairs/location_line_equality_comparison.rb +1 -0
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +5 -5
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_processor.rb +63 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups/ast_walker.rb +131 -0
- data/lib/rubocop/cop/internal_affairs/node_pattern_groups.rb +231 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +92 -0
- data/lib/rubocop/cop/internal_affairs/node_type_multiple_predicates.rb +126 -0
- data/lib/rubocop/cop/internal_affairs/node_type_predicate.rb +4 -3
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +90 -0
- data/lib/rubocop/cop/internal_affairs/operator_keyword.rb +4 -2
- data/lib/rubocop/cop/internal_affairs/plugin.rb +33 -0
- data/lib/rubocop/cop/internal_affairs/redundant_described_class_as_subject.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/redundant_source_range.rb +3 -1
- data/lib/rubocop/cop/internal_affairs/single_line_comparison.rb +5 -4
- data/lib/rubocop/cop/internal_affairs/undefined_config.rb +13 -2
- data/lib/rubocop/cop/internal_affairs/useless_restrict_on_send.rb +1 -1
- data/lib/rubocop/cop/internal_affairs.rb +6 -16
- data/lib/rubocop/cop/layout/access_modifier_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -8
- data/lib/rubocop/cop/layout/block_alignment.rb +3 -1
- data/lib/rubocop/cop/layout/block_end_newline.rb +1 -0
- data/lib/rubocop/cop/layout/class_structure.rb +44 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +5 -5
- data/lib/rubocop/cop/layout/def_end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/dot_position.rb +1 -1
- data/lib/rubocop/cop/layout/else_alignment.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_after_guard_clause.rb +2 -2
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +101 -0
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +35 -4
- data/lib/rubocop/cop/layout/empty_lines_around_arguments.rb +8 -29
- data/lib/rubocop/cop/layout/empty_lines_around_begin_body.rb +5 -6
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_class_body.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_method_body.rb +22 -2
- data/lib/rubocop/cop/layout/end_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/extra_spacing.rb +1 -1
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +4 -9
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +2 -7
- data/lib/rubocop/cop/layout/first_hash_element_line_break.rb +1 -1
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/hash_alignment.rb +8 -6
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -0
- data/lib/rubocop/cop/layout/leading_comment_space.rb +13 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +11 -2
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +7 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/line_length.rb +35 -9
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_hash_key_line_breaks.rb +1 -1
- data/lib/rubocop/cop/layout/multiline_method_argument_line_breaks.rb +25 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +4 -4
- data/lib/rubocop/cop/layout/multiline_method_parameter_line_breaks.rb +1 -0
- data/lib/rubocop/cop/layout/multiline_operation_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -11
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +3 -5
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_colon.rb +2 -2
- data/lib/rubocop/cop/layout/space_after_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_method_name.rb +1 -1
- data/lib/rubocop/cop/layout/space_after_semicolon.rb +11 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +7 -1
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +15 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_before_brackets.rb +5 -38
- data/lib/rubocop/cop/layout/space_before_comma.rb +1 -1
- data/lib/rubocop/cop/layout/space_before_semicolon.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +12 -3
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +1 -0
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +3 -0
- data/lib/rubocop/cop/layout/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_range.rb +5 -0
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +118 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -3
- data/lib/rubocop/cop/lint/boolean_symbol.rb +1 -1
- data/lib/rubocop/cop/lint/circular_argument_reference.rb +4 -3
- data/lib/rubocop/cop/lint/constant_definition_in_block.rb +3 -3
- data/lib/rubocop/cop/lint/constant_reassignment.rb +148 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +84 -0
- data/lib/rubocop/cop/lint/debugger.rb +3 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/deprecated_open_ssl_constant.rb +2 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +111 -23
- data/lib/rubocop/cop/lint/duplicate_regexp_character_class_element.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_set_element.rb +20 -7
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +14 -64
- data/lib/rubocop/cop/lint/empty_expression.rb +0 -2
- data/lib/rubocop/cop/lint/empty_interpolation.rb +3 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +37 -12
- data/lib/rubocop/cop/lint/float_out_of_range.rb +1 -1
- data/lib/rubocop/cop/lint/format_parameter_mismatch.rb +2 -2
- data/lib/rubocop/cop/lint/identity_comparison.rb +19 -15
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +125 -10
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +1 -1
- data/lib/rubocop/cop/lint/missing_super.rb +2 -2
- data/lib/rubocop/cop/lint/mixed_case_range.rb +3 -3
- data/lib/rubocop/cop/lint/mixed_regexp_capture_types.rb +1 -1
- data/lib/rubocop/cop/lint/nested_method_definition.rb +9 -5
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -2
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -3
- data/lib/rubocop/cop/lint/non_local_exit_from_iterator.rb +3 -3
- data/lib/rubocop/cop/lint/numeric_operation_with_constant_result.rb +19 -31
- data/lib/rubocop/cop/lint/or_assignment_to_constant.rb +1 -1
- data/lib/rubocop/cop/lint/out_of_range_regexp_ref.rb +2 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +1 -5
- data/lib/rubocop/cop/lint/raise_exception.rb +29 -10
- data/lib/rubocop/cop/lint/redundant_regexp_quantifiers.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +101 -2
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +261 -0
- data/lib/rubocop/cop/lint/redundant_with_index.rb +3 -0
- data/lib/rubocop/cop/lint/redundant_with_object.rb +3 -0
- data/lib/rubocop/cop/lint/refinement_import_methods.rb +1 -1
- data/lib/rubocop/cop/lint/require_range_parentheses.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +9 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -1
- data/lib/rubocop/cop/lint/self_assignment.rb +25 -0
- data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +13 -1
- data/lib/rubocop/cop/lint/shared_mutable_default.rb +76 -0
- data/lib/rubocop/cop/lint/suppressed_exception.rb +1 -1
- data/lib/rubocop/cop/lint/suppressed_exception_in_number_conversion.rb +111 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/syntax.rb +4 -1
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -1
- data/lib/rubocop/cop/lint/top_level_return_with_argument.rb +1 -1
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +1 -1
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +3 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +52 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +6 -6
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +34 -8
- data/lib/rubocop/cop/lint/useless_assignment.rb +3 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_default_value_argument.rb +90 -0
- data/lib/rubocop/cop/lint/useless_else_without_rescue.rb +4 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +3 -1
- data/lib/rubocop/cop/lint/useless_or.rb +98 -0
- data/lib/rubocop/cop/lint/useless_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +5 -5
- data/lib/rubocop/cop/lint/utils/nil_receiver_checker.rb +121 -0
- data/lib/rubocop/cop/lint/void.rb +14 -11
- data/lib/rubocop/cop/message_annotator.rb +7 -3
- data/lib/rubocop/cop/metrics/abc_size.rb +1 -1
- data/lib/rubocop/cop/metrics/block_length.rb +1 -0
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- data/lib/rubocop/cop/metrics/class_length.rb +9 -9
- data/lib/rubocop/cop/metrics/collection_literal_length.rb +7 -0
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/method_length.rb +9 -1
- data/lib/rubocop/cop/metrics/module_length.rb +1 -1
- data/lib/rubocop/cop/metrics/perceived_complexity.rb +1 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +2 -2
- data/lib/rubocop/cop/metrics/utils/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +3 -3
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +13 -13
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +2 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +8 -3
- data/lib/rubocop/cop/mixin/def_node.rb +1 -1
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +1 -1
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +20 -0
- data/lib/rubocop/cop/mixin/forbidden_pattern.rb +16 -0
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -2
- data/lib/rubocop/cop/mixin/gemspec_help.rb +22 -0
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +15 -14
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +22 -22
- data/lib/rubocop/cop/mixin/hash_subset.rb +203 -0
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +74 -74
- data/lib/rubocop/cop/mixin/line_length_help.rb +27 -10
- data/lib/rubocop/cop/mixin/method_complexity.rb +2 -1
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +2 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +68 -30
- data/lib/rubocop/cop/mixin/range_help.rb +15 -3
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/mixin/statement_modifier.rb +8 -3
- data/lib/rubocop/cop/mixin/string_help.rb +2 -2
- data/lib/rubocop/cop/mixin/string_literals_help.rb +1 -1
- data/lib/rubocop/cop/mixin/target_ruby_version.rb +1 -1
- data/lib/rubocop/cop/mixin/trailing_comma.rb +21 -5
- data/lib/rubocop/cop/naming/accessor_method_name.rb +6 -6
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/method_name.rb +185 -15
- data/lib/rubocop/cop/naming/predicate_method.rb +306 -0
- data/lib/rubocop/cop/naming/{predicate_name.rb → predicate_prefix.rb} +48 -4
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +4 -4
- data/lib/rubocop/cop/naming/variable_name.rb +51 -6
- data/lib/rubocop/cop/registry.rb +9 -6
- data/lib/rubocop/cop/security/compound_hash.rb +2 -0
- data/lib/rubocop/cop/security/eval.rb +2 -1
- data/lib/rubocop/cop/security/open.rb +1 -0
- data/lib/rubocop/cop/security/yaml_load.rb +3 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +66 -15
- data/lib/rubocop/cop/style/accessor_grouping.rb +32 -6
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +57 -44
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/array_intersect.rb +81 -40
- data/lib/rubocop/cop/style/block_delimiters.rb +27 -24
- data/lib/rubocop/cop/style/case_like_if.rb +1 -1
- data/lib/rubocop/cop/style/class_and_module_children.rb +52 -11
- data/lib/rubocop/cop/style/class_equality_comparison.rb +1 -1
- data/lib/rubocop/cop/style/collection_methods.rb +2 -1
- data/lib/rubocop/cop/style/collection_querying.rb +167 -0
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +3 -2
- data/lib/rubocop/cop/style/command_literal.rb +1 -1
- data/lib/rubocop/cop/style/commented_keyword.rb +12 -5
- data/lib/rubocop/cop/style/comparable_between.rb +78 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +23 -7
- data/lib/rubocop/cop/style/data_inheritance.rb +7 -0
- data/lib/rubocop/cop/style/def_with_parentheses.rb +18 -5
- data/lib/rubocop/cop/style/dig_chain.rb +6 -7
- data/lib/rubocop/cop/style/documentation.rb +1 -1
- data/lib/rubocop/cop/style/double_negation.rb +4 -4
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +4 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -3
- data/lib/rubocop/cop/style/empty_else.rb +4 -2
- data/lib/rubocop/cop/style/empty_literal.rb +5 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +100 -0
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +4 -4
- data/lib/rubocop/cop/style/exact_regexp_match.rb +2 -3
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +16 -3
- data/lib/rubocop/cop/style/exponential_notation.rb +6 -5
- data/lib/rubocop/cop/style/fetch_env_var.rb +34 -7
- data/lib/rubocop/cop/style/file_null.rb +20 -4
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/for.rb +1 -0
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +3 -2
- data/lib/rubocop/cop/style/global_std_stream.rb +3 -0
- data/lib/rubocop/cop/style/guard_clause.rb +2 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +16 -8
- data/lib/rubocop/cop/style/hash_each_methods.rb +6 -8
- data/lib/rubocop/cop/style/hash_except.rb +35 -147
- data/lib/rubocop/cop/style/hash_fetch_chain.rb +104 -0
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +9 -3
- data/lib/rubocop/cop/style/hash_transform_keys.rb +2 -2
- data/lib/rubocop/cop/style/hash_transform_values.rb +2 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +25 -6
- data/lib/rubocop/cop/style/if_inside_else.rb +10 -13
- data/lib/rubocop/cop/style/if_unless_modifier.rb +36 -9
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -7
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +2 -2
- data/lib/rubocop/cop/style/if_with_semicolon.rb +7 -5
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +16 -12
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +2 -2
- data/lib/rubocop/cop/style/ip_addresses.rb +2 -2
- data/lib/rubocop/cop/style/it_assignment.rb +93 -0
- data/lib/rubocop/cop/style/it_block_parameter.rb +121 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/lambda.rb +1 -0
- data/lib/rubocop/cop/style/lambda_call.rb +10 -3
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +5 -2
- data/lib/rubocop/cop/style/map_to_hash.rb +13 -4
- data/lib/rubocop/cop/style/map_to_set.rb +4 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +27 -19
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +18 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +3 -2
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +3 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/min_max_comparison.rb +13 -5
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +3 -2
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +2 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +34 -22
- data/lib/rubocop/cop/style/mutable_constant.rb +3 -3
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +1 -1
- data/lib/rubocop/cop/style/nested_parenthesized_calls.rb +1 -1
- data/lib/rubocop/cop/style/next.rb +44 -0
- data/lib/rubocop/cop/style/object_then.rb +15 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +33 -25
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +2 -2
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +1 -1
- data/lib/rubocop/cop/style/percent_q_literals.rb +1 -1
- data/lib/rubocop/cop/style/proc.rb +2 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +14 -12
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_argument.rb +3 -1
- data/lib/rubocop/cop/style/redundant_array_flatten.rb +50 -0
- data/lib/rubocop/cop/style/redundant_begin.rb +2 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +59 -2
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +16 -5
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -10
- data/lib/rubocop/cop/style/redundant_each.rb +1 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +2 -2
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +1 -9
- data/lib/rubocop/cop/style/redundant_format.rb +262 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +4 -4
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_interpolation.rb +1 -1
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +39 -22
- data/lib/rubocop/cop/style/redundant_parentheses.rb +85 -17
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +3 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +1 -1
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +1 -1
- data/lib/rubocop/cop/style/redundant_self.rb +10 -6
- data/lib/rubocop/cop/style/redundant_self_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_sort_by.rb +17 -1
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/regexp_literal.rb +1 -1
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +2 -2
- data/lib/rubocop/cop/style/safe_navigation.rb +46 -16
- data/lib/rubocop/cop/style/select_by_regexp.rb +4 -1
- data/lib/rubocop/cop/style/semicolon.rb +1 -1
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +2 -1
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +4 -3
- data/lib/rubocop/cop/style/single_line_methods.rb +13 -11
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +68 -101
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/string_concatenation.rb +15 -14
- data/lib/rubocop/cop/style/string_literals.rb +1 -1
- data/lib/rubocop/cop/style/string_methods.rb +1 -1
- data/lib/rubocop/cop/style/struct_inheritance.rb +8 -1
- data/lib/rubocop/cop/style/super_arguments.rb +66 -19
- data/lib/rubocop/cop/style/symbol_proc.rb +3 -1
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +2 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +11 -2
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_hash_literal.rb +48 -6
- data/lib/rubocop/cop/style/trivial_accessors.rb +1 -1
- data/lib/rubocop/cop/style/while_until_modifier.rb +0 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +8 -4
- data/lib/rubocop/cop/style/yoda_expression.rb +2 -1
- data/lib/rubocop/cop/team.rb +1 -1
- data/lib/rubocop/cop/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +7 -3
- data/lib/rubocop/cop/variable_force/scope.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +10 -3
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cop/variable_force.rb +23 -8
- data/lib/rubocop/cops_documentation_generator.rb +32 -16
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/disabled_config_formatter.rb +2 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/formatter/fuubar_style_formatter.rb +1 -1
- data/lib/rubocop/formatter/html_formatter.rb +1 -1
- data/lib/rubocop/formatter/markdown_formatter.rb +1 -0
- data/lib/rubocop/formatter/offense_count_formatter.rb +1 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +2 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +10 -26
- data/lib/rubocop/lsp/runtime.rb +18 -50
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +85 -0
- data/lib/rubocop/magic_comment.rb +11 -3
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- data/lib/rubocop/pending_cops_reporter.rb +56 -0
- data/lib/rubocop/plugin/configuration_integrator.rb +143 -0
- data/lib/rubocop/plugin/load_error.rb +26 -0
- data/lib/rubocop/plugin/loader.rb +100 -0
- data/lib/rubocop/plugin/not_supported_error.rb +29 -0
- data/lib/rubocop/plugin.rb +46 -0
- data/lib/rubocop/rake_task.rb +4 -1
- data/lib/rubocop/result_cache.rb +26 -24
- data/lib/rubocop/rspec/cop_helper.rb +13 -1
- data/lib/rubocop/rspec/expect_offense.rb +15 -5
- data/lib/rubocop/rspec/shared_contexts.rb +38 -1
- data/lib/rubocop/rspec/support.rb +4 -2
- data/lib/rubocop/runner.rb +10 -7
- data/lib/rubocop/server/cache.rb +51 -13
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/server/client_command/base.rb +10 -0
- data/lib/rubocop/server/client_command/exec.rb +2 -1
- data/lib/rubocop/server/client_command/start.rb +11 -1
- data/lib/rubocop/target_finder.rb +7 -2
- data/lib/rubocop/target_ruby.rb +16 -1
- data/lib/rubocop/version.rb +30 -8
- data/lib/rubocop.rb +27 -2
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +65 -0
- metadata +72 -19
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -7,11 +7,6 @@ module RuboCop
|
|
7
7
|
#
|
8
8
|
# NOTE: empty `else` branches are handled by `Style/EmptyElse`.
|
9
9
|
#
|
10
|
-
# @safety
|
11
|
-
# Autocorrection for this cop is not safe. The conditions for empty branches that
|
12
|
-
# the autocorrection removes may have side effects, or the logic in subsequent
|
13
|
-
# branches may change due to the removal of a previous condition.
|
14
|
-
#
|
15
10
|
# @example
|
16
11
|
# # bad
|
17
12
|
# if condition
|
@@ -41,6 +36,13 @@ module RuboCop
|
|
41
36
|
# if condition
|
42
37
|
# do_something
|
43
38
|
# elsif other_condition
|
39
|
+
# nil
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # good
|
43
|
+
# if condition
|
44
|
+
# do_something
|
45
|
+
# elsif other_condition
|
44
46
|
# do_something_else
|
45
47
|
# end
|
46
48
|
#
|
@@ -63,11 +65,9 @@ module RuboCop
|
|
63
65
|
class EmptyConditionalBody < Base
|
64
66
|
extend AutoCorrector
|
65
67
|
include CommentsHelp
|
66
|
-
include RangeHelp
|
67
68
|
|
68
69
|
MSG = 'Avoid `%<keyword>s` branches without a body.'
|
69
70
|
|
70
|
-
# rubocop:disable Metrics/AbcSize
|
71
71
|
def on_if(node)
|
72
72
|
return if node.body || same_line?(node.loc.begin, node.loc.end)
|
73
73
|
return if cop_config['AllowComments'] && contains_comments?(node)
|
@@ -75,12 +75,11 @@ module RuboCop
|
|
75
75
|
range = offense_range(node)
|
76
76
|
|
77
77
|
add_offense(range, message: format(MSG, keyword: node.keyword)) do |corrector|
|
78
|
-
next
|
78
|
+
next unless can_simplify_conditional?(node)
|
79
79
|
|
80
|
-
|
80
|
+
flip_orphaned_else(corrector, node)
|
81
81
|
end
|
82
82
|
end
|
83
|
-
# rubocop:enable Metrics/AbcSize
|
84
83
|
|
85
84
|
private
|
86
85
|
|
@@ -92,53 +91,23 @@ module RuboCop
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
95
|
-
def
|
96
|
-
|
97
|
-
remove_empty_branch(corrector, node)
|
98
|
-
correct_other_branches(corrector, node)
|
99
|
-
end
|
100
|
-
|
101
|
-
def remove_comments(corrector, node)
|
102
|
-
comments_in_range(node).each do |comment|
|
103
|
-
range = range_by_whole_lines(comment.source_range, include_final_newline: true)
|
104
|
-
corrector.remove(range)
|
105
|
-
end
|
94
|
+
def can_simplify_conditional?(node)
|
95
|
+
node.else_branch && node.loc.else.source == 'else'
|
106
96
|
end
|
107
97
|
|
108
|
-
# rubocop:disable Metrics/AbcSize
|
109
98
|
def remove_empty_branch(corrector, node)
|
110
99
|
range = if empty_if_branch?(node) && else_branch?(node)
|
111
100
|
branch_range(node)
|
112
|
-
elsif same_line?(node, else_kw_loc = node.loc.else)
|
113
|
-
node.source_range.begin.join(else_kw_loc.begin)
|
114
|
-
elsif node.parent&.loc.respond_to?(:end) &&
|
115
|
-
same_line?(node, end_loc = node.parent.loc.end)
|
116
|
-
node.source_range.begin.join(end_loc.begin)
|
117
101
|
else
|
118
102
|
deletion_range(branch_range(node))
|
119
103
|
end
|
120
104
|
|
121
105
|
corrector.remove(range)
|
122
106
|
end
|
123
|
-
# rubocop:enable Metrics/AbcSize
|
124
|
-
|
125
|
-
def correct_other_branches(corrector, node)
|
126
|
-
return unless require_other_branches_correction?(node)
|
127
|
-
|
128
|
-
if node.else_branch&.if_type? && !node.else_branch.modifier_form?
|
129
|
-
# Replace an orphaned `elsif` with `if`
|
130
|
-
corrector.replace(node.else_branch.loc.keyword, 'if')
|
131
|
-
else
|
132
|
-
# Flip orphaned `else`
|
133
|
-
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
def require_other_branches_correction?(node)
|
138
|
-
return false unless node.if_type? && node.else?
|
139
|
-
return false if !empty_if_branch?(node) && node.elsif?
|
140
107
|
|
141
|
-
|
108
|
+
def flip_orphaned_else(corrector, node)
|
109
|
+
corrector.replace(node.loc.else, "#{node.inverse_keyword} #{node.condition.source}")
|
110
|
+
remove_empty_branch(corrector, node)
|
142
111
|
end
|
143
112
|
|
144
113
|
def empty_if_branch?(node)
|
@@ -149,36 +118,17 @@ module RuboCop
|
|
149
118
|
if_branch.if_type? && !if_branch.body
|
150
119
|
end
|
151
120
|
|
152
|
-
def empty_elsif_branch?(node)
|
153
|
-
return false unless (else_branch = node.else_branch)
|
154
|
-
|
155
|
-
else_branch.if_type? && !else_branch.body
|
156
|
-
end
|
157
|
-
|
158
121
|
def else_branch?(node)
|
159
122
|
node.else_branch && !node.else_branch.if_type?
|
160
123
|
end
|
161
124
|
|
162
|
-
# rubocop:disable Metrics/AbcSize
|
163
125
|
def branch_range(node)
|
164
126
|
if empty_if_branch?(node) && else_branch?(node)
|
165
127
|
node.source_range.with(end_pos: node.loc.else.begin_pos)
|
166
128
|
elsif node.loc.else
|
167
129
|
node.source_range.with(end_pos: node.condition.source_range.end_pos)
|
168
|
-
elsif all_branches_body_missing?(node)
|
169
|
-
if_node = node.ancestors.detect(&:if?)
|
170
|
-
node.source_range.join(if_node.loc.end.end)
|
171
|
-
else
|
172
|
-
node.source_range
|
173
130
|
end
|
174
131
|
end
|
175
|
-
# rubocop:enable Metrics/AbcSize
|
176
|
-
|
177
|
-
def all_branches_body_missing?(node)
|
178
|
-
return false unless node.parent&.if_type?
|
179
|
-
|
180
|
-
node.parent.branches.compact.empty?
|
181
|
-
end
|
182
132
|
|
183
133
|
def deletion_range(range)
|
184
134
|
# Collect a range between the start of the `if` node and the next relevant node,
|
@@ -19,7 +19,9 @@ module RuboCop
|
|
19
19
|
MSG = 'Empty interpolation detected.'
|
20
20
|
|
21
21
|
def on_interpolation(begin_node)
|
22
|
-
|
22
|
+
node_children = begin_node.children.dup
|
23
|
+
node_children.delete_if { |e| e.nil_type? || (e.basic_literal? && e.str_content&.empty?) }
|
24
|
+
return unless node_children.empty?
|
23
25
|
|
24
26
|
add_offense(begin_node) { |corrector| corrector.remove(begin_node) }
|
25
27
|
end
|
@@ -156,12 +156,6 @@ module RuboCop
|
|
156
156
|
|
157
157
|
overridden_kwargs
|
158
158
|
end
|
159
|
-
|
160
|
-
def arguments_range(node)
|
161
|
-
arguments = node.arguments
|
162
|
-
|
163
|
-
range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
|
164
|
-
end
|
165
159
|
end
|
166
160
|
end
|
167
161
|
end
|
@@ -15,6 +15,14 @@ module RuboCop
|
|
15
15
|
# x == 0.1
|
16
16
|
# x != 0.1
|
17
17
|
#
|
18
|
+
# # bad
|
19
|
+
# case value
|
20
|
+
# when 1.0
|
21
|
+
# foo
|
22
|
+
# when 2.0
|
23
|
+
# bar
|
24
|
+
# end
|
25
|
+
#
|
18
26
|
# # good - using BigDecimal
|
19
27
|
# x.to_d == 0.1.to_d
|
20
28
|
#
|
@@ -32,11 +40,21 @@ module RuboCop
|
|
32
40
|
# # good - comparing against nil
|
33
41
|
# Float(x, exception: false) == nil
|
34
42
|
#
|
43
|
+
# # good - using epsilon comparison in case expression
|
44
|
+
# case
|
45
|
+
# when (value - 1.0).abs < Float::EPSILON
|
46
|
+
# foo
|
47
|
+
# when (value - 2.0).abs < Float::EPSILON
|
48
|
+
# bar
|
49
|
+
# end
|
50
|
+
#
|
35
51
|
# # Or some other epsilon based type of comparison:
|
36
52
|
# # https://www.embeddeduse.com/2019/08/26/qt-compare-two-floats/
|
37
53
|
#
|
38
54
|
class FloatComparison < Base
|
39
|
-
|
55
|
+
MSG_EQUALITY = 'Avoid equality comparisons of floats as they are unreliable.'
|
56
|
+
MSG_INEQUALITY = 'Avoid inequality comparisons of floats as they are unreliable.'
|
57
|
+
MSG_CASE = 'Avoid float literal comparisons in case statements as they are unreliable.'
|
40
58
|
|
41
59
|
EQUALITY_METHODS = %i[== != eql? equal?].freeze
|
42
60
|
FLOAT_RETURNING_METHODS = %i[to_f Float fdiv].freeze
|
@@ -52,7 +70,19 @@ module RuboCop
|
|
52
70
|
|
53
71
|
return if literal_safe?(lhs) || literal_safe?(rhs)
|
54
72
|
|
55
|
-
|
73
|
+
message = node.method?(:!=) ? MSG_INEQUALITY : MSG_EQUALITY
|
74
|
+
add_offense(node, message: message) if float?(lhs) || float?(rhs)
|
75
|
+
end
|
76
|
+
alias on_csend on_send
|
77
|
+
|
78
|
+
def on_case(node)
|
79
|
+
node.when_branches.each do |when_branch|
|
80
|
+
when_branch.each_condition do |condition|
|
81
|
+
next if !float?(condition) || literal_safe?(condition)
|
82
|
+
|
83
|
+
add_offense(condition, message: MSG_CASE)
|
84
|
+
end
|
85
|
+
end
|
56
86
|
end
|
57
87
|
|
58
88
|
private
|
@@ -64,7 +94,7 @@ module RuboCop
|
|
64
94
|
when :float
|
65
95
|
true
|
66
96
|
when :send
|
67
|
-
|
97
|
+
float_send?(node)
|
68
98
|
when :begin
|
69
99
|
float?(node.children.first)
|
70
100
|
else
|
@@ -78,23 +108,18 @@ module RuboCop
|
|
78
108
|
(node.numeric_type? && node.value.zero?) || node.nil_type?
|
79
109
|
end
|
80
110
|
|
81
|
-
|
82
|
-
def check_send(node)
|
111
|
+
def float_send?(node)
|
83
112
|
if node.arithmetic_operation?
|
84
113
|
float?(node.receiver) || float?(node.first_argument)
|
85
114
|
elsif FLOAT_RETURNING_METHODS.include?(node.method_name)
|
86
115
|
true
|
87
116
|
elsif node.receiver&.float_type?
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
check_numeric_returning_method(node)
|
92
|
-
end
|
117
|
+
FLOAT_INSTANCE_METHODS.include?(node.method_name) ||
|
118
|
+
numeric_returning_method?(node)
|
93
119
|
end
|
94
120
|
end
|
95
|
-
# rubocop:enable Metrics/PerceivedComplexity
|
96
121
|
|
97
|
-
def
|
122
|
+
def numeric_returning_method?(node)
|
98
123
|
return false unless node.receiver
|
99
124
|
|
100
125
|
case node.method_name
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module RuboCop
|
4
4
|
module Cop
|
5
5
|
module Lint
|
6
|
-
# Identifies Float literals which are, like, really really really
|
6
|
+
# Identifies `Float` literals which are, like, really really really
|
7
7
|
# really really really really really big. Too big. No-one needs Floats
|
8
8
|
# that big. If you need a float that big, something is wrong with you.
|
9
9
|
#
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
7
7
|
# expected fields for format/sprintf/#% and what is actually
|
8
8
|
# passed as arguments.
|
9
9
|
#
|
10
|
-
# In addition it checks whether different formats are used in the same
|
10
|
+
# In addition, it checks whether different formats are used in the same
|
11
11
|
# format string. Do not mix numbered, unnumbered, and named formats in
|
12
12
|
# the same format string.
|
13
13
|
#
|
@@ -73,7 +73,7 @@ module RuboCop
|
|
73
73
|
|
74
74
|
first_arg = node.first_argument
|
75
75
|
return false if num_of_expected_fields.zero? &&
|
76
|
-
|
76
|
+
first_arg.type?(:dstr, :array)
|
77
77
|
|
78
78
|
matched_arguments_count?(num_of_expected_fields, num_of_format_args)
|
79
79
|
end
|
@@ -11,39 +11,43 @@ module RuboCop
|
|
11
11
|
# @example
|
12
12
|
# # bad
|
13
13
|
# foo.object_id == bar.object_id
|
14
|
+
# foo.object_id != baz.object_id
|
14
15
|
#
|
15
16
|
# # good
|
16
17
|
# foo.equal?(bar)
|
18
|
+
# !foo.equal?(baz)
|
17
19
|
#
|
18
20
|
class IdentityComparison < Base
|
19
21
|
extend AutoCorrector
|
20
22
|
|
21
|
-
MSG = 'Use
|
22
|
-
RESTRICT_ON_SEND = %i[==].freeze
|
23
|
+
MSG = 'Use `%<bang>sequal?` instead of `%<comparison_method>s` when comparing `object_id`.'
|
24
|
+
RESTRICT_ON_SEND = %i[== !=].freeze
|
25
|
+
|
26
|
+
# @!method object_id_comparison(node)
|
27
|
+
def_node_matcher :object_id_comparison, <<~PATTERN
|
28
|
+
(send
|
29
|
+
(send
|
30
|
+
_lhs_receiver :object_id) ${:== :!=}
|
31
|
+
(send
|
32
|
+
_rhs_receiver :object_id))
|
33
|
+
PATTERN
|
23
34
|
|
24
35
|
def on_send(node)
|
25
|
-
return unless
|
36
|
+
return unless (comparison_method = object_id_comparison(node))
|
26
37
|
|
27
|
-
|
38
|
+
bang = comparison_method == :== ? '' : '!'
|
39
|
+
add_offense(node,
|
40
|
+
message: format(MSG, comparison_method: comparison_method,
|
41
|
+
bang: bang)) do |corrector|
|
28
42
|
receiver = node.receiver.receiver
|
29
43
|
argument = node.first_argument.receiver
|
30
44
|
return unless receiver && argument
|
31
45
|
|
32
|
-
replacement = "#{receiver.source}.equal?(#{argument.source})"
|
46
|
+
replacement = "#{bang}#{receiver.source}.equal?(#{argument.source})"
|
33
47
|
|
34
48
|
corrector.replace(node, replacement)
|
35
49
|
end
|
36
50
|
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def compare_between_object_id_by_double_equal?(node)
|
41
|
-
object_id_method?(node.receiver) && object_id_method?(node.first_argument)
|
42
|
-
end
|
43
|
-
|
44
|
-
def object_id_method?(node)
|
45
|
-
node.send_type? && node.method?(:object_id)
|
46
|
-
end
|
47
51
|
end
|
48
52
|
end
|
49
53
|
end
|
@@ -18,12 +18,15 @@ module RuboCop
|
|
18
18
|
# end
|
19
19
|
#
|
20
20
|
# # bad
|
21
|
-
#
|
21
|
+
# # We're only interested in the left hand side being a truthy literal,
|
22
|
+
# # because it affects the evaluation of the &&, whereas the right hand
|
23
|
+
# # side will be conditionally executed/called and can be a literal.
|
24
|
+
# if true && some_var
|
22
25
|
# do_something
|
23
26
|
# end
|
24
27
|
#
|
25
28
|
# # good
|
26
|
-
# if some_var
|
29
|
+
# if some_var
|
27
30
|
# do_something
|
28
31
|
# end
|
29
32
|
#
|
@@ -34,29 +37,107 @@ module RuboCop
|
|
34
37
|
# end
|
35
38
|
class LiteralAsCondition < Base
|
36
39
|
include RangeHelp
|
40
|
+
extend AutoCorrector
|
37
41
|
|
38
42
|
MSG = 'Literal `%<literal>s` appeared as a condition.'
|
43
|
+
RESTRICT_ON_SEND = [:!].freeze
|
44
|
+
|
45
|
+
def on_and(node)
|
46
|
+
return unless node.lhs.truthy_literal?
|
47
|
+
|
48
|
+
add_offense(node.lhs) do |corrector|
|
49
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
50
|
+
# the leftmost node can lead to a void value expression syntax error.
|
51
|
+
next if node.rhs.type?(:return, :break, :next)
|
52
|
+
|
53
|
+
corrector.replace(node, node.rhs.source)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def on_or(node)
|
58
|
+
return unless node.lhs.falsey_literal?
|
59
|
+
|
60
|
+
add_offense(node.lhs) do |corrector|
|
61
|
+
# Don't autocorrect `'foo' && return` because having `return` as
|
62
|
+
# the leftmost node can lead to a void value expression syntax error.
|
63
|
+
next if node.rhs.type?(:return, :break, :next)
|
64
|
+
|
65
|
+
corrector.replace(node, node.rhs.source)
|
66
|
+
end
|
67
|
+
end
|
39
68
|
|
40
69
|
def on_if(node)
|
41
|
-
|
70
|
+
cond = condition(node)
|
71
|
+
|
72
|
+
return unless cond.falsey_literal? || cond.truthy_literal?
|
73
|
+
|
74
|
+
correct_if_node(node, cond)
|
42
75
|
end
|
43
76
|
|
44
77
|
def on_while(node)
|
45
|
-
return if
|
78
|
+
return if node.condition.source == 'true'
|
46
79
|
|
47
|
-
|
80
|
+
if node.condition.truthy_literal?
|
81
|
+
add_offense(node.condition) do |corrector|
|
82
|
+
corrector.replace(node.condition, 'true')
|
83
|
+
end
|
84
|
+
elsif node.condition.falsey_literal?
|
85
|
+
add_offense(node.condition) do |corrector|
|
86
|
+
corrector.remove(node)
|
87
|
+
end
|
88
|
+
end
|
48
89
|
end
|
49
|
-
|
90
|
+
|
91
|
+
# rubocop:disable Metrics/AbcSize
|
92
|
+
def on_while_post(node)
|
93
|
+
return if node.condition.source == 'true'
|
94
|
+
|
95
|
+
if node.condition.truthy_literal?
|
96
|
+
add_offense(node.condition) do |corrector|
|
97
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'true'))
|
98
|
+
end
|
99
|
+
elsif node.condition.falsey_literal?
|
100
|
+
add_offense(node.condition) do |corrector|
|
101
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
# rubocop:enable Metrics/AbcSize
|
50
106
|
|
51
107
|
def on_until(node)
|
52
|
-
return if
|
108
|
+
return if node.condition.source == 'false'
|
53
109
|
|
54
|
-
|
110
|
+
if node.condition.falsey_literal?
|
111
|
+
add_offense(node.condition) do |corrector|
|
112
|
+
corrector.replace(node.condition, 'false')
|
113
|
+
end
|
114
|
+
elsif node.condition.truthy_literal?
|
115
|
+
add_offense(node.condition) do |corrector|
|
116
|
+
corrector.remove(node)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# rubocop:disable Metrics/AbcSize
|
122
|
+
def on_until_post(node)
|
123
|
+
return if node.condition.source == 'false'
|
124
|
+
|
125
|
+
if node.condition.falsey_literal?
|
126
|
+
add_offense(node.condition) do |corrector|
|
127
|
+
corrector.replace(node, node.source.sub(node.condition.source, 'false'))
|
128
|
+
end
|
129
|
+
elsif node.condition.truthy_literal?
|
130
|
+
add_offense(node.condition) do |corrector|
|
131
|
+
corrector.replace(node, node.body.child_nodes.map(&:source).join("\n"))
|
132
|
+
end
|
133
|
+
end
|
55
134
|
end
|
56
|
-
|
135
|
+
# rubocop:enable Metrics/AbcSize
|
57
136
|
|
58
137
|
def on_case(case_node)
|
59
|
-
if case_node.condition
|
138
|
+
if (cond = case_node.condition)
|
139
|
+
return if !cond.falsey_literal? && !cond.truthy_literal?
|
140
|
+
|
60
141
|
check_case(case_node)
|
61
142
|
else
|
62
143
|
case_node.when_branches.each do |when_node|
|
@@ -129,6 +210,8 @@ module RuboCop
|
|
129
210
|
|
130
211
|
def handle_node(node)
|
131
212
|
if node.literal?
|
213
|
+
return if node.parent.and_type?
|
214
|
+
|
132
215
|
add_offense(node)
|
133
216
|
elsif %i[send and or begin].include?(node.type)
|
134
217
|
check_node(node)
|
@@ -158,6 +241,38 @@ module RuboCop
|
|
158
241
|
when_node.conditions.last.source_range.end_pos
|
159
242
|
)
|
160
243
|
end
|
244
|
+
|
245
|
+
def condition_evaluation?(node, cond)
|
246
|
+
if node.unless?
|
247
|
+
cond.falsey_literal?
|
248
|
+
else
|
249
|
+
cond.truthy_literal?
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
254
|
+
def correct_if_node(node, cond)
|
255
|
+
result = condition_evaluation?(node, cond)
|
256
|
+
|
257
|
+
new_node = if node.elsif? && result
|
258
|
+
"else\n #{range_with_comments(node.if_branch).source}"
|
259
|
+
elsif node.elsif? && !result
|
260
|
+
"else\n #{node.else_branch.source}"
|
261
|
+
elsif node.if_branch && result
|
262
|
+
node.if_branch.source
|
263
|
+
elsif node.elsif_conditional?
|
264
|
+
"#{node.else_branch.source.sub('elsif', 'if')}\nend"
|
265
|
+
elsif node.else? || node.ternary?
|
266
|
+
node.else_branch.source
|
267
|
+
else
|
268
|
+
'' # Equivalent to removing the node
|
269
|
+
end
|
270
|
+
|
271
|
+
add_offense(cond) do |corrector|
|
272
|
+
corrector.replace(node, new_node)
|
273
|
+
end
|
274
|
+
end
|
275
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
161
276
|
end
|
162
277
|
end
|
163
278
|
end
|
@@ -5,6 +5,9 @@ module RuboCop
|
|
5
5
|
module Lint
|
6
6
|
# Checks for interpolated literals.
|
7
7
|
#
|
8
|
+
# NOTE: Array literals interpolated in regexps are not handled by this cop, but
|
9
|
+
# by `Lint/ArrayLiteralInRegexp` instead.
|
10
|
+
#
|
8
11
|
# @example
|
9
12
|
#
|
10
13
|
# # bad
|
@@ -21,6 +24,7 @@ module RuboCop
|
|
21
24
|
MSG = 'Literal interpolation detected.'
|
22
25
|
COMPOSITE = %i[array hash pair irange erange].freeze
|
23
26
|
|
27
|
+
# rubocop:disable Metrics/AbcSize
|
24
28
|
def on_interpolation(begin_node)
|
25
29
|
final_node = begin_node.children.last
|
26
30
|
return unless offending?(final_node)
|
@@ -35,11 +39,18 @@ module RuboCop
|
|
35
39
|
return if in_array_percent_literal?(begin_node) && /\s|\A\z/.match?(expanded_value)
|
36
40
|
|
37
41
|
add_offense(final_node) do |corrector|
|
38
|
-
|
42
|
+
next if final_node.dstr_type? # nested, fixed in next iteration
|
43
|
+
|
44
|
+
replacement = if final_node.str_type? && !final_node.value.valid_encoding?
|
45
|
+
final_node.source.delete_prefix('"').delete_suffix('"')
|
46
|
+
else
|
47
|
+
expanded_value
|
48
|
+
end
|
39
49
|
|
40
|
-
corrector.replace(final_node.parent,
|
50
|
+
corrector.replace(final_node.parent, replacement)
|
41
51
|
end
|
42
52
|
end
|
53
|
+
# rubocop:enable Metrics/AbcSize
|
43
54
|
|
44
55
|
private
|
45
56
|
|
@@ -47,8 +58,10 @@ module RuboCop
|
|
47
58
|
node &&
|
48
59
|
!special_keyword?(node) &&
|
49
60
|
prints_as_self?(node) &&
|
50
|
-
# Special case for Layout/TrailingWhitespace
|
51
|
-
!(space_literal?(node) && ends_heredoc_line?(node))
|
61
|
+
# Special case for `Layout/TrailingWhitespace`
|
62
|
+
!(space_literal?(node) && ends_heredoc_line?(node)) &&
|
63
|
+
# Handled by `Lint/ArrayLiteralInRegexp`
|
64
|
+
!array_in_regexp?(node)
|
52
65
|
end
|
53
66
|
|
54
67
|
def special_keyword?(node)
|
@@ -56,6 +69,11 @@ module RuboCop
|
|
56
69
|
(node.str_type? && !node.loc.respond_to?(:begin)) || node.source_range.is?('__LINE__')
|
57
70
|
end
|
58
71
|
|
72
|
+
def array_in_regexp?(node)
|
73
|
+
grandparent = node.parent.parent
|
74
|
+
node.array_type? && grandparent.regexp_type?
|
75
|
+
end
|
76
|
+
|
59
77
|
# rubocop:disable Metrics/MethodLength, Metrics/CyclomaticComplexity
|
60
78
|
def autocorrected_value(node)
|
61
79
|
case node.type
|
@@ -168,7 +186,7 @@ module RuboCop
|
|
168
186
|
end
|
169
187
|
|
170
188
|
def space_literal?(node)
|
171
|
-
node.str_type? && node.value.blank?
|
189
|
+
node.str_type? && node.value.valid_encoding? && node.value.blank?
|
172
190
|
end
|
173
191
|
|
174
192
|
def ends_heredoc_line?(node)
|
@@ -181,7 +199,7 @@ module RuboCop
|
|
181
199
|
|
182
200
|
def in_array_percent_literal?(node)
|
183
201
|
parent = node.parent
|
184
|
-
return false unless parent.
|
202
|
+
return false unless parent.type?(:dstr, :dsym)
|
185
203
|
|
186
204
|
grandparent = parent.parent
|
187
205
|
grandparent&.array_type? && grandparent.percent_literal?
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
52
52
|
each_missing_enable do |cop, line_range|
|
53
53
|
next if acceptable_range?(cop, line_range)
|
54
54
|
|
55
|
-
range = source_range(processed_source.buffer, line_range.min,
|
55
|
+
range = source_range(processed_source.buffer, line_range.min, 0..0)
|
56
56
|
comment = processed_source.comment_at_line(line_range.begin)
|
57
57
|
|
58
58
|
add_offense(range, message: message(cop, comment))
|
@@ -97,7 +97,7 @@ module RuboCop
|
|
97
97
|
|
98
98
|
# @!method class_new_block(node)
|
99
99
|
def_node_matcher :class_new_block, <<~RUBY
|
100
|
-
(
|
100
|
+
(any_block
|
101
101
|
(send
|
102
102
|
(const {nil? cbase} :Class) :new $_) ...)
|
103
103
|
RUBY
|
@@ -135,7 +135,7 @@ module RuboCop
|
|
135
135
|
end
|
136
136
|
|
137
137
|
def inside_class_with_stateful_parent?(node)
|
138
|
-
if (block_node = node.each_ancestor(:
|
138
|
+
if (block_node = node.each_ancestor(:any_block).first)
|
139
139
|
return false unless (super_class = class_new_block(block_node))
|
140
140
|
|
141
141
|
!allowed_class?(super_class)
|