rubocop 1.69.2 → 1.74.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 -4
- data/config/default.yml +122 -17
- data/config/internal_affairs.yml +20 -0
- 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/comment_config.rb +2 -2
- data/lib/rubocop/config.rb +17 -4
- data/lib/rubocop/config_loader.rb +48 -9
- data/lib/rubocop/config_loader_resolver.rb +36 -10
- data/lib/rubocop/config_obsoletion/extracted_cop.rb +4 -3
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +19 -9
- data/lib/rubocop/cop/autocorrect_logic.rb +1 -1
- data/lib/rubocop/cop/base.rb +6 -0
- data/lib/rubocop/cop/bundler/duplicated_gem.rb +1 -1
- data/lib/rubocop/cop/bundler/gem_comment.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/cop_enabled.rb +85 -0
- data/lib/rubocop/cop/internal_affairs/example_description.rb +7 -3
- 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/node_first_or_last_argument.rb +3 -2
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +1 -1
- 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 +229 -0
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +91 -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/plugin.rb +33 -0
- 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 +7 -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/class_structure.rb +9 -9
- data/lib/rubocop/cop/layout/closing_parenthesis_indentation.rb +4 -4
- 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 +1 -1
- data/lib/rubocop/cop/layout/empty_line_between_defs.rb +7 -11
- data/lib/rubocop/cop/layout/empty_lines_around_access_modifier.rb +27 -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 +3 -8
- 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 +6 -4
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -1
- 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 +4 -3
- 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/redundant_line_break.rb +7 -6
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +1 -1
- 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 +1 -1
- data/lib/rubocop/cop/layout/space_around_keyword.rb +1 -0
- data/lib/rubocop/cop/layout/space_around_method_call_operator.rb +1 -1
- data/lib/rubocop/cop/layout/space_around_operators.rb +3 -3
- 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/trailing_whitespace.rb +5 -3
- data/lib/rubocop/cop/lint/ambiguous_block_association.rb +1 -1
- data/lib/rubocop/cop/lint/array_literal_in_regexp.rb +119 -0
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +1 -3
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +1 -1
- 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 +1 -1
- data/lib/rubocop/cop/lint/duplicate_match_pattern.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +0 -14
- 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/erb_new_arguments.rb +0 -6
- data/lib/rubocop/cop/lint/float_comparison.rb +6 -8
- 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/implicit_string_concatenation.rb +1 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +103 -9
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +24 -6
- 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 +8 -4
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/non_atomic_file_operation.rb +4 -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 +18 -31
- 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/redundant_regexp_quantifiers.rb +1 -1
- data/lib/rubocop/cop/lint/redundant_require_statement.rb +0 -21
- data/lib/rubocop/cop/lint/redundant_string_coercion.rb +2 -2
- data/lib/rubocop/cop/lint/redundant_type_conversion.rb +258 -0
- data/lib/rubocop/cop/lint/rescue_exception.rb +1 -1
- data/lib/rubocop/cop/lint/return_in_void_context.rb +4 -11
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +8 -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/unescaped_bracket_in_regexp.rb +1 -4
- data/lib/rubocop/cop/lint/unexpected_block_arity.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_code.rb +1 -1
- data/lib/rubocop/cop/lint/unreachable_loop.rb +1 -1
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +4 -4
- data/lib/rubocop/cop/lint/useless_assignment.rb +1 -1
- data/lib/rubocop/cop/lint/useless_constant_scoping.rb +71 -0
- data/lib/rubocop/cop/lint/useless_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/useless_numeric_operation.rb +2 -1
- data/lib/rubocop/cop/lint/useless_ruby2_keywords.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +11 -9
- data/lib/rubocop/cop/metrics/block_nesting.rb +1 -1
- 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 +8 -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/repeated_attribute_discount.rb +7 -7
- data/lib/rubocop/cop/mixin/alignment.rb +2 -2
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +4 -4
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +11 -11
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +1 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +4 -2
- data/lib/rubocop/cop/mixin/dig_help.rb +1 -1
- data/lib/rubocop/cop/mixin/frozen_string_literal.rb +1 -1
- 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/method_complexity.rb +1 -1
- data/lib/rubocop/cop/mixin/percent_literal.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +48 -24
- 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 +15 -3
- data/lib/rubocop/cop/naming/block_forwarding.rb +19 -15
- data/lib/rubocop/cop/naming/predicate_name.rb +44 -0
- data/lib/rubocop/cop/naming/rescued_exceptions_variable_name.rb +3 -3
- data/lib/rubocop/cop/naming/variable_name.rb +64 -6
- data/lib/rubocop/cop/security/compound_hash.rb +1 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +34 -5
- data/lib/rubocop/cop/style/accessor_grouping.rb +19 -5
- data/lib/rubocop/cop/style/and_or.rb +1 -1
- data/lib/rubocop/cop/style/arguments_forwarding.rb +39 -23
- data/lib/rubocop/cop/style/array_first_last.rb +18 -2
- data/lib/rubocop/cop/style/block_delimiters.rb +7 -20
- data/lib/rubocop/cop/style/class_and_module_children.rb +35 -10
- data/lib/rubocop/cop/style/collection_methods.rb +1 -1
- data/lib/rubocop/cop/style/combinable_defined.rb +1 -1
- data/lib/rubocop/cop/style/combinable_loops.rb +2 -2
- data/lib/rubocop/cop/style/commented_keyword.rb +10 -3
- data/lib/rubocop/cop/style/comparable_between.rb +75 -0
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -1
- data/lib/rubocop/cop/style/conditional_assignment.rb +6 -4
- 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 +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +1 -1
- data/lib/rubocop/cop/style/endless_method.rb +163 -18
- data/lib/rubocop/cop/style/eval_with_location.rb +1 -1
- data/lib/rubocop/cop/style/exact_regexp_match.rb +3 -10
- data/lib/rubocop/cop/style/expand_path_arguments.rb +2 -7
- data/lib/rubocop/cop/style/explicit_block_argument.rb +15 -2
- data/lib/rubocop/cop/style/exponential_notation.rb +3 -3
- data/lib/rubocop/cop/style/fetch_env_var.rb +1 -1
- data/lib/rubocop/cop/style/float_division.rb +8 -4
- data/lib/rubocop/cop/style/format_string_token.rb +38 -11
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +1 -1
- data/lib/rubocop/cop/style/hash_each_methods.rb +3 -6
- data/lib/rubocop/cop/style/hash_except.rb +24 -148
- data/lib/rubocop/cop/style/hash_slice.rb +80 -0
- data/lib/rubocop/cop/style/hash_syntax.rb +6 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_unless_modifier.rb +5 -5
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +1 -1
- data/lib/rubocop/cop/style/if_with_semicolon.rb +2 -2
- data/lib/rubocop/cop/style/infinite_loop.rb +1 -1
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -11
- data/lib/rubocop/cop/style/it_assignment.rb +36 -0
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +14 -8
- data/lib/rubocop/cop/style/line_end_concatenation.rb +10 -4
- data/lib/rubocop/cop/style/map_into_array.rb +1 -1
- data/lib/rubocop/cop/style/map_to_hash.rb +1 -1
- data/lib/rubocop/cop/style/map_to_set.rb +3 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +22 -15
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -0
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +2 -1
- data/lib/rubocop/cop/style/method_called_on_do_end_block.rb +2 -4
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_else.rb +2 -0
- data/lib/rubocop/cop/style/multiline_block_chain.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +1 -9
- data/lib/rubocop/cop/style/multiple_comparison.rb +26 -20
- 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/object_then.rb +13 -15
- data/lib/rubocop/cop/style/open_struct_use.rb +5 -5
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -5
- 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/proc.rb +1 -2
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +6 -4
- data/lib/rubocop/cop/style/random_with_offset.rb +3 -3
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_condition.rb +47 -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_format.rb +250 -0
- data/lib/rubocop/cop/style/redundant_freeze.rb +3 -3
- data/lib/rubocop/cop/style/redundant_initialize.rb +12 -3
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +34 -13
- data/lib/rubocop/cop/style/redundant_parentheses.rb +28 -14
- 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_assignment.rb +14 -28
- data/lib/rubocop/cop/style/redundant_sort.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +2 -2
- data/lib/rubocop/cop/style/rescue_modifier.rb +3 -0
- data/lib/rubocop/cop/style/return_nil.rb +1 -1
- data/lib/rubocop/cop/style/safe_navigation.rb +2 -2
- 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 +1 -2
- data/lib/rubocop/cop/style/single_line_methods.rb +6 -7
- data/lib/rubocop/cop/style/slicing_with_range.rb +40 -11
- data/lib/rubocop/cop/style/sole_nested_conditional.rb +2 -8
- data/lib/rubocop/cop/style/string_concatenation.rb +2 -2
- 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/super_arguments.rb +65 -17
- data/lib/rubocop/cop/style/ternary_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/trailing_comma_in_arguments.rb +4 -1
- data/lib/rubocop/cop/style/trailing_comma_in_array_literal.rb +47 -6
- 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/util.rb +12 -5
- data/lib/rubocop/cop/utils/format_string.rb +10 -5
- data/lib/rubocop/cop/variable_force/variable.rb +14 -2
- data/lib/rubocop/cop/variable_force/variable_table.rb +3 -3
- data/lib/rubocop/cops_documentation_generator.rb +25 -14
- data/lib/rubocop/directive_comment.rb +45 -11
- data/lib/rubocop/ext/regexp_node.rb +0 -1
- data/lib/rubocop/formatter/formatter_set.rb +1 -1
- data/lib/rubocop/lsp/diagnostic.rb +189 -0
- data/lib/rubocop/lsp/logger.rb +2 -2
- data/lib/rubocop/lsp/routes.rb +7 -23
- data/lib/rubocop/lsp/runtime.rb +17 -49
- data/lib/rubocop/lsp/server.rb +0 -2
- data/lib/rubocop/lsp/stdin_runner.rb +83 -0
- data/lib/rubocop/options.rb +28 -12
- data/lib/rubocop/path_util.rb +15 -8
- 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 +13 -13
- data/lib/rubocop/rspec/cop_helper.rb +9 -0
- data/lib/rubocop/rspec/expect_offense.rb +6 -2
- data/lib/rubocop/rspec/shared_contexts.rb +19 -1
- data/lib/rubocop/rspec/support.rb +2 -2
- data/lib/rubocop/runner.rb +5 -6
- data/lib/rubocop/server/cache.rb +35 -2
- data/lib/rubocop/server/cli.rb +2 -2
- data/lib/rubocop/target_finder.rb +1 -0
- data/lib/rubocop/target_ruby.rb +15 -0
- data/lib/rubocop/version.rb +17 -2
- data/lib/rubocop.rb +12 -1
- data/lib/ruby_lsp/rubocop/addon.rb +75 -0
- data/lib/ruby_lsp/rubocop/runtime_adapter.rb +47 -0
- metadata +55 -16
- data/lib/rubocop/cop/utils/regexp_ranges.rb +0 -113
- data/lib/rubocop/rspec/host_environment_simulation_helper.rb +0 -28
@@ -0,0 +1,258 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for redundant uses of `to_s`, `to_sym`, `to_i`, `to_f`, `to_d`, `to_r`, `to_c`,
|
7
|
+
# `to_a`, `to_h`, and `to_set`.
|
8
|
+
#
|
9
|
+
# When one of these methods is called on an object of the same type, that object
|
10
|
+
# is returned, making the call unnecessary. The cop detects conversion methods called
|
11
|
+
# on object literals, class constructors, class `[]` methods, and the `Kernel` methods
|
12
|
+
# `String()`, `Integer()`, `Float()`, BigDecimal(), `Rational()`, `Complex()`, and `Array()`.
|
13
|
+
#
|
14
|
+
# Specifically, these cases are detected for each conversion method:
|
15
|
+
#
|
16
|
+
# * `to_s` when called on a string literal, interpolated string, heredoc,
|
17
|
+
# or with `String.new` or `String()`.
|
18
|
+
# * `to_sym` when called on a symbol literal or interpolated symbol.
|
19
|
+
# * `to_i` when called on an integer literal or with `Integer()`.
|
20
|
+
# * `to_f` when called on a float literal of with `Float()`.
|
21
|
+
# * `to_r` when called on a rational literal or with `Rational()`.
|
22
|
+
# * `to_c` when called on a complex literal of with `Complex()`.
|
23
|
+
# * `to_a` when called on an array literal, or with `Array.new`, `Array()` or `Array[]`.
|
24
|
+
# * `to_h` when called on a hash literal, or with `Hash.new`, `Hash()` or `Hash[]`.
|
25
|
+
# * `to_set` when called on `Set.new` or `Set[]`.
|
26
|
+
#
|
27
|
+
# In all cases, chaining one same `to_*` conversion methods listed above is redundant.
|
28
|
+
#
|
29
|
+
# The cop can also register an offense for chaining conversion methods on methods that are
|
30
|
+
# expected to return a specific type regardless of receiver (eg. `foo.inspect.to_s`).
|
31
|
+
#
|
32
|
+
# @example
|
33
|
+
# # bad
|
34
|
+
# "text".to_s
|
35
|
+
# :sym.to_sym
|
36
|
+
# 42.to_i
|
37
|
+
# 8.5.to_f
|
38
|
+
# 12r.to_r
|
39
|
+
# 1i.to_c
|
40
|
+
# [].to_a
|
41
|
+
# {}.to_h
|
42
|
+
# Set.new.to_set
|
43
|
+
#
|
44
|
+
# # good
|
45
|
+
# "text"
|
46
|
+
# :sym
|
47
|
+
# 42
|
48
|
+
# 8.5
|
49
|
+
# 12r
|
50
|
+
# 1i
|
51
|
+
# []
|
52
|
+
# {}
|
53
|
+
# Set.new
|
54
|
+
#
|
55
|
+
# # bad
|
56
|
+
# Integer(var).to_i
|
57
|
+
#
|
58
|
+
# # good
|
59
|
+
# Integer(var)
|
60
|
+
#
|
61
|
+
# # good - chaining to a type constructor with exceptions suppressed
|
62
|
+
# # in this case, `Integer()` could return `nil`
|
63
|
+
# Integer(var, exception: false).to_i
|
64
|
+
#
|
65
|
+
# # bad - chaining the same conversion
|
66
|
+
# foo.to_s.to_s
|
67
|
+
#
|
68
|
+
# # good
|
69
|
+
# foo.to_s
|
70
|
+
#
|
71
|
+
# # bad - chaining a conversion to a method that is expected to return the same type
|
72
|
+
# inspect.to_s
|
73
|
+
#
|
74
|
+
# # good
|
75
|
+
# inspect
|
76
|
+
#
|
77
|
+
class RedundantTypeConversion < Base
|
78
|
+
extend AutoCorrector
|
79
|
+
|
80
|
+
MSG = 'Redundant `%<method>s` detected.'
|
81
|
+
|
82
|
+
# Maps conversion methods to the node types for the literals of that type
|
83
|
+
LITERAL_NODE_TYPES = {
|
84
|
+
to_s: %i[str dstr],
|
85
|
+
to_sym: %i[sym dsym],
|
86
|
+
to_i: %i[int],
|
87
|
+
to_f: %i[float],
|
88
|
+
to_r: %i[rational],
|
89
|
+
to_c: %i[complex],
|
90
|
+
to_a: %i[array],
|
91
|
+
to_h: %i[hash],
|
92
|
+
to_set: [] # sets don't have a literal or node type
|
93
|
+
}.freeze
|
94
|
+
|
95
|
+
# Maps each conversion method to the pattern matcher for that type's constructors
|
96
|
+
# Not every type has a constructor, for instance Symbol.
|
97
|
+
CONSTRUCTOR_MAPPING = {
|
98
|
+
to_s: 'string_constructor?',
|
99
|
+
to_i: 'integer_constructor?',
|
100
|
+
to_f: 'float_constructor?',
|
101
|
+
to_d: 'bigdecimal_constructor?',
|
102
|
+
to_r: 'rational_constructor?',
|
103
|
+
to_c: 'complex_constructor?',
|
104
|
+
to_a: 'array_constructor?',
|
105
|
+
to_h: 'hash_constructor?',
|
106
|
+
to_set: 'set_constructor?'
|
107
|
+
}.freeze
|
108
|
+
|
109
|
+
# Methods that already are expected to return a given type, which makes a further
|
110
|
+
# conversion redundant.
|
111
|
+
TYPED_METHODS = { to_s: %i[inspect] }.freeze
|
112
|
+
|
113
|
+
CONVERSION_METHODS = Set[*LITERAL_NODE_TYPES.keys].freeze
|
114
|
+
RESTRICT_ON_SEND = CONVERSION_METHODS + [:to_d]
|
115
|
+
|
116
|
+
private_constant :LITERAL_NODE_TYPES, :CONSTRUCTOR_MAPPING
|
117
|
+
|
118
|
+
# @!method type_constructor?(node, type_symbol)
|
119
|
+
def_node_matcher :type_constructor?, <<~PATTERN
|
120
|
+
(send {nil? (const {cbase nil?} :Kernel)} %1 ...)
|
121
|
+
PATTERN
|
122
|
+
|
123
|
+
# @!method string_constructor?(node)
|
124
|
+
def_node_matcher :string_constructor?, <<~PATTERN
|
125
|
+
{
|
126
|
+
(send (const {cbase nil?} :String) :new ...)
|
127
|
+
#type_constructor?(:String)
|
128
|
+
}
|
129
|
+
PATTERN
|
130
|
+
|
131
|
+
# @!method integer_constructor?(node)
|
132
|
+
def_node_matcher :integer_constructor?, <<~PATTERN
|
133
|
+
#type_constructor?(:Integer)
|
134
|
+
PATTERN
|
135
|
+
|
136
|
+
# @!method float_constructor?(node)
|
137
|
+
def_node_matcher :float_constructor?, <<~PATTERN
|
138
|
+
#type_constructor?(:Float)
|
139
|
+
PATTERN
|
140
|
+
|
141
|
+
# @!method bigdecimal_constructor?(node)
|
142
|
+
def_node_matcher :bigdecimal_constructor?, <<~PATTERN
|
143
|
+
#type_constructor?(:BigDecimal)
|
144
|
+
PATTERN
|
145
|
+
|
146
|
+
# @!method rational_constructor?(node)
|
147
|
+
def_node_matcher :rational_constructor?, <<~PATTERN
|
148
|
+
#type_constructor?(:Rational)
|
149
|
+
PATTERN
|
150
|
+
|
151
|
+
# @!method complex_constructor?(node)
|
152
|
+
def_node_matcher :complex_constructor?, <<~PATTERN
|
153
|
+
#type_constructor?(:Complex)
|
154
|
+
PATTERN
|
155
|
+
|
156
|
+
# @!method array_constructor?(node)
|
157
|
+
def_node_matcher :array_constructor?, <<~PATTERN
|
158
|
+
{
|
159
|
+
(send (const {cbase nil?} :Array) {:new :[]} ...)
|
160
|
+
#type_constructor?(:Array)
|
161
|
+
}
|
162
|
+
PATTERN
|
163
|
+
|
164
|
+
# @!method hash_constructor?(node)
|
165
|
+
def_node_matcher :hash_constructor?, <<~PATTERN
|
166
|
+
{
|
167
|
+
(block (send (const {cbase nil?} :Hash) :new) ...)
|
168
|
+
(send (const {cbase nil?} :Hash) {:new :[]} ...)
|
169
|
+
(send {nil? (const {cbase nil?} :Kernel)} :Hash ...)
|
170
|
+
}
|
171
|
+
PATTERN
|
172
|
+
|
173
|
+
# @!method set_constructor?(node)
|
174
|
+
def_node_matcher :set_constructor?, <<~PATTERN
|
175
|
+
{
|
176
|
+
(send (const {cbase nil?} :Set) {:new :[]} ...)
|
177
|
+
}
|
178
|
+
PATTERN
|
179
|
+
|
180
|
+
# @!method exception_false_keyword_argument?(node)
|
181
|
+
def_node_matcher :exception_false_keyword_argument?, <<~PATTERN
|
182
|
+
(hash (pair (sym :exception) false))
|
183
|
+
PATTERN
|
184
|
+
|
185
|
+
# rubocop:disable Metrics/AbcSize
|
186
|
+
def on_send(node)
|
187
|
+
return if hash_or_set_with_block?(node)
|
188
|
+
|
189
|
+
receiver = find_receiver(node)
|
190
|
+
return unless literal_receiver?(node, receiver) ||
|
191
|
+
constructor?(node, receiver) ||
|
192
|
+
chained_conversion?(node, receiver) ||
|
193
|
+
chained_to_typed_method?(node, receiver)
|
194
|
+
|
195
|
+
message = format(MSG, method: node.method_name)
|
196
|
+
|
197
|
+
add_offense(node.loc.selector, message: message) do |corrector|
|
198
|
+
corrector.remove(node.loc.dot.join(node.loc.selector))
|
199
|
+
end
|
200
|
+
end
|
201
|
+
# rubocop:enable Metrics/AbcSize
|
202
|
+
alias on_csend on_send
|
203
|
+
|
204
|
+
private
|
205
|
+
|
206
|
+
def hash_or_set_with_block?(node)
|
207
|
+
return false if !node.method?(:to_h) && !node.method?(:to_set)
|
208
|
+
|
209
|
+
node.parent&.any_block_type? || node.last_argument&.block_pass_type?
|
210
|
+
end
|
211
|
+
|
212
|
+
def find_receiver(node)
|
213
|
+
receiver = node.receiver
|
214
|
+
return unless receiver
|
215
|
+
|
216
|
+
while receiver.begin_type?
|
217
|
+
break unless receiver.children.one?
|
218
|
+
|
219
|
+
receiver = receiver.children.first
|
220
|
+
end
|
221
|
+
|
222
|
+
receiver
|
223
|
+
end
|
224
|
+
|
225
|
+
def literal_receiver?(node, receiver)
|
226
|
+
return false unless receiver
|
227
|
+
|
228
|
+
receiver.type?(*LITERAL_NODE_TYPES[node.method_name])
|
229
|
+
end
|
230
|
+
|
231
|
+
def constructor?(node, receiver)
|
232
|
+
matcher = CONSTRUCTOR_MAPPING[node.method_name]
|
233
|
+
return false unless matcher
|
234
|
+
|
235
|
+
public_send(matcher, receiver) && !constructor_suppresses_exceptions?(receiver)
|
236
|
+
end
|
237
|
+
|
238
|
+
def constructor_suppresses_exceptions?(receiver)
|
239
|
+
# If the constructor suppresses exceptions with `exception: false`, it is possible
|
240
|
+
# it could return `nil`, and therefore a chained conversion is not redundant.
|
241
|
+
receiver.arguments.any? { |arg| exception_false_keyword_argument?(arg) }
|
242
|
+
end
|
243
|
+
|
244
|
+
def chained_conversion?(node, receiver)
|
245
|
+
return false unless receiver&.call_type?
|
246
|
+
|
247
|
+
receiver.method?(node.method_name)
|
248
|
+
end
|
249
|
+
|
250
|
+
def chained_to_typed_method?(node, receiver)
|
251
|
+
return false unless receiver&.call_type?
|
252
|
+
|
253
|
+
TYPED_METHODS.fetch(node.method_name, []).include?(receiver.method_name)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
@@ -35,22 +35,15 @@ module RuboCop
|
|
35
35
|
def on_return(return_node)
|
36
36
|
return unless return_node.descendants.any?
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
return
|
41
|
-
return unless context_node&.void_context?
|
38
|
+
def_node = return_node.each_ancestor(:def).first
|
39
|
+
return unless def_node&.void_context?
|
40
|
+
return if return_node.each_ancestor(:any_block).any?(&:lambda?)
|
42
41
|
|
43
42
|
add_offense(
|
44
43
|
return_node.loc.keyword,
|
45
|
-
message: format(message, method:
|
44
|
+
message: format(message, method: def_node.method_name)
|
46
45
|
)
|
47
46
|
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def non_void_context(return_node)
|
52
|
-
return_node.each_ancestor(:block, :def, :defs).first
|
53
|
-
end
|
54
47
|
end
|
55
48
|
end
|
56
49
|
end
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
33
33
|
def_node_matcher :bad_method?, <<~PATTERN
|
34
34
|
{
|
35
35
|
(send $(csend ...) $_ ...)
|
36
|
-
(send $(
|
36
|
+
(send $(any_block (csend ...) ...) $_ ...)
|
37
37
|
}
|
38
38
|
PATTERN
|
39
39
|
|
@@ -97,12 +97,19 @@ module RuboCop
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def require_parentheses?(send_node)
|
100
|
+
return true if operator_inside_hash?(send_node)
|
100
101
|
return false unless send_node.comparison_method?
|
101
102
|
return false unless (node = send_node.parent)
|
102
103
|
|
103
104
|
(node.respond_to?(:logical_operator?) && node.logical_operator?) ||
|
104
105
|
(node.respond_to?(:comparison_method?) && node.comparison_method?)
|
105
106
|
end
|
107
|
+
|
108
|
+
def operator_inside_hash?(send_node)
|
109
|
+
# If an operator call (without a dot) is inside a hash, it needs
|
110
|
+
# to be parenthesized when converted to safe navigation.
|
111
|
+
send_node.parent&.pair_type? && !send_node.loc.dot
|
112
|
+
end
|
106
113
|
end
|
107
114
|
end
|
108
115
|
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for `Hash` creation with a mutable default value.
|
7
|
+
# Creating a `Hash` in such a way will share the default value
|
8
|
+
# across all keys, causing unexpected behavior when modifying it.
|
9
|
+
#
|
10
|
+
# For example, when the `Hash` was created with an `Array` as the argument,
|
11
|
+
# calling `hash[:foo] << 'bar'` will also change the value of all
|
12
|
+
# other keys that have not been explicitly assigned to.
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# Hash.new([])
|
17
|
+
# Hash.new({})
|
18
|
+
# Hash.new(Array.new)
|
19
|
+
# Hash.new(Hash.new)
|
20
|
+
#
|
21
|
+
# # okay -- In rare cases that intentionally have this behavior,
|
22
|
+
# # without disabling the cop, you can set the default explicitly.
|
23
|
+
# h = Hash.new
|
24
|
+
# h.default = []
|
25
|
+
# h[:a] << 1
|
26
|
+
# h[:b] << 2
|
27
|
+
# h # => {:a => [1, 2], :b => [1, 2]}
|
28
|
+
#
|
29
|
+
# # okay -- beware this will discard mutations and only remember assignments
|
30
|
+
# Hash.new { Array.new }
|
31
|
+
# Hash.new { Hash.new }
|
32
|
+
# Hash.new { {} }
|
33
|
+
# Hash.new { [] }
|
34
|
+
#
|
35
|
+
# # good - frozen solution will raise an error when mutation attempted
|
36
|
+
# Hash.new([].freeze)
|
37
|
+
# Hash.new({}.freeze)
|
38
|
+
#
|
39
|
+
# # good - using a proc will create a new object for each key
|
40
|
+
# h = Hash.new
|
41
|
+
# h.default_proc = ->(h, k) { [] }
|
42
|
+
# h.default_proc = ->(h, k) { {} }
|
43
|
+
#
|
44
|
+
# # good - using a block will create a new object for each key
|
45
|
+
# Hash.new { |h, k| h[k] = [] }
|
46
|
+
# Hash.new { |h, k| h[k] = {} }
|
47
|
+
class SharedMutableDefault < Base
|
48
|
+
MSG = 'Do not create a Hash with a mutable default value ' \
|
49
|
+
'as the default value can accidentally be changed.'
|
50
|
+
RESTRICT_ON_SEND = %i[new].freeze
|
51
|
+
|
52
|
+
# @!method hash_initialized_with_mutable_shared_object?(node)
|
53
|
+
def_node_matcher :hash_initialized_with_mutable_shared_object?, <<~PATTERN
|
54
|
+
{
|
55
|
+
(send (const {nil? cbase} :Hash) :new [
|
56
|
+
{array hash (send (const {nil? cbase} {:Array :Hash}) :new)}
|
57
|
+
!#capacity_keyword_argument?
|
58
|
+
])
|
59
|
+
(send (const {nil? cbase} :Hash) :new hash #capacity_keyword_argument?)
|
60
|
+
}
|
61
|
+
PATTERN
|
62
|
+
|
63
|
+
# @!method capacity_keyword_argument?(node)
|
64
|
+
def_node_matcher :capacity_keyword_argument?, <<~PATTERN
|
65
|
+
(hash (pair (sym :capacity) _))
|
66
|
+
PATTERN
|
67
|
+
|
68
|
+
def on_send(node)
|
69
|
+
return unless hash_initialized_with_mutable_shared_object?(node)
|
70
|
+
|
71
|
+
add_offense(node)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -116,7 +116,7 @@ module RuboCop
|
|
116
116
|
private
|
117
117
|
|
118
118
|
def comment_between_rescue_and_end?(node)
|
119
|
-
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :
|
119
|
+
ancestor = node.each_ancestor(:kwbegin, :def, :defs, :any_block).first
|
120
120
|
return false unless ancestor
|
121
121
|
|
122
122
|
end_line = ancestor.loc.end&.line || ancestor.loc.last_line
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RuboCop
|
4
|
+
module Cop
|
5
|
+
module Lint
|
6
|
+
# Checks for cases where exceptions unrelated to the numeric constructors `Integer()`,
|
7
|
+
# `Float()`, `BigDecimal()`, `Complex()`, and `Rational()` may be unintentionally swallowed.
|
8
|
+
#
|
9
|
+
# @safety
|
10
|
+
# The cop is unsafe for autocorrection because unexpected errors occurring in the argument
|
11
|
+
# passed to numeric constructor (e.g., `Integer()`) can lead to incompatible behavior.
|
12
|
+
# For example, changing it to `Integer(potential_exception_method_call, exception: false)`
|
13
|
+
# ensures that exceptions raised by `potential_exception_method_call` are not ignored.
|
14
|
+
#
|
15
|
+
# [source,ruby]
|
16
|
+
# ----
|
17
|
+
# Integer(potential_exception_method_call) rescue nil
|
18
|
+
# ----
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
#
|
22
|
+
# # bad
|
23
|
+
# Integer(arg) rescue nil
|
24
|
+
#
|
25
|
+
# # bad
|
26
|
+
# begin
|
27
|
+
# Integer(arg)
|
28
|
+
# rescue
|
29
|
+
# nil
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# # bad
|
33
|
+
# begin
|
34
|
+
# Integer(arg)
|
35
|
+
# rescue
|
36
|
+
# end
|
37
|
+
#
|
38
|
+
# # good
|
39
|
+
# Integer(arg, exception: false)
|
40
|
+
#
|
41
|
+
class SuppressedExceptionInNumberConversion < Base
|
42
|
+
extend AutoCorrector
|
43
|
+
extend TargetRubyVersion
|
44
|
+
|
45
|
+
MSG = 'Use `%<prefer>s` instead.'
|
46
|
+
EXPECTED_EXCEPTION_CLASSES = %w[ArgumentError TypeError ::ArgumentError ::TypeError].freeze
|
47
|
+
|
48
|
+
# @!method numeric_constructor_rescue_nil(node)
|
49
|
+
def_node_matcher :numeric_constructor_rescue_nil, <<~PATTERN
|
50
|
+
(rescue
|
51
|
+
$#numeric_method?
|
52
|
+
(resbody nil? nil? (nil)) nil?)
|
53
|
+
PATTERN
|
54
|
+
|
55
|
+
# @!method begin_numeric_constructor_rescue_nil(node)
|
56
|
+
def_node_matcher :begin_numeric_constructor_rescue_nil, <<~PATTERN
|
57
|
+
(kwbegin
|
58
|
+
(rescue
|
59
|
+
$#numeric_method?
|
60
|
+
(resbody $_? nil?
|
61
|
+
{(nil) nil?}) nil?))
|
62
|
+
PATTERN
|
63
|
+
|
64
|
+
# @!method numeric_method?(node)
|
65
|
+
def_node_matcher :numeric_method?, <<~PATTERN
|
66
|
+
{
|
67
|
+
(call #constructor_receiver? {:Integer :BigDecimal :Complex :Rational}
|
68
|
+
_ _?)
|
69
|
+
(call #constructor_receiver? :Float
|
70
|
+
_)
|
71
|
+
}
|
72
|
+
PATTERN
|
73
|
+
|
74
|
+
# @!method constructor_receiver?(node)
|
75
|
+
def_node_matcher :constructor_receiver?, <<~PATTERN
|
76
|
+
{nil? (const {nil? cbase} :Kernel)}
|
77
|
+
PATTERN
|
78
|
+
|
79
|
+
minimum_target_ruby_version 2.6
|
80
|
+
|
81
|
+
# rubocop:disable Metrics/AbcSize
|
82
|
+
def on_rescue(node)
|
83
|
+
if (method, exception_classes = begin_numeric_constructor_rescue_nil(node.parent))
|
84
|
+
return unless expected_exception_classes_only?(exception_classes)
|
85
|
+
|
86
|
+
node = node.parent
|
87
|
+
else
|
88
|
+
return unless (method = numeric_constructor_rescue_nil(node))
|
89
|
+
end
|
90
|
+
|
91
|
+
arguments = method.arguments.map(&:source) << 'exception: false'
|
92
|
+
prefer = "#{method.method_name}(#{arguments.join(', ')})"
|
93
|
+
prefer = "#{method.receiver.source}#{method.loc.dot.source}#{prefer}" if method.receiver
|
94
|
+
|
95
|
+
add_offense(node, message: format(MSG, prefer: prefer)) do |corrector|
|
96
|
+
corrector.replace(node, prefer)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
# rubocop:enable Metrics/AbcSize
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def expected_exception_classes_only?(exception_classes)
|
104
|
+
return true unless (arguments = exception_classes.first)
|
105
|
+
|
106
|
+
(arguments.values.map(&:source) - EXPECTED_EXCEPTION_CLASSES).none?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -78,7 +78,7 @@ module RuboCop
|
|
78
78
|
def on_send(node)
|
79
79
|
return unless node.receiver
|
80
80
|
|
81
|
-
if node.receiver.
|
81
|
+
if node.receiver.type?(:str, :sym)
|
82
82
|
register_offense(node, correction: node.receiver.value.to_sym.inspect)
|
83
83
|
elsif node.receiver.dstr_type?
|
84
84
|
register_offense(node, correction: ":\"#{node.receiver.value.to_sym}\"")
|
@@ -6,9 +6,12 @@ module RuboCop
|
|
6
6
|
# Repacks Parser's diagnostics/errors
|
7
7
|
# into RuboCop's offenses.
|
8
8
|
class Syntax < Base
|
9
|
+
LEVELS = %i[error fatal].freeze
|
10
|
+
|
9
11
|
def on_other_file
|
10
12
|
add_offense_from_error(processed_source.parser_error) if processed_source.parser_error
|
11
|
-
processed_source.diagnostics.
|
13
|
+
syntax_errors = processed_source.diagnostics.select { |d| LEVELS.include?(d.level) }
|
14
|
+
syntax_errors.each do |diagnostic|
|
12
15
|
add_offense_from_diagnostic(diagnostic, processed_source.ruby_version)
|
13
16
|
end
|
14
17
|
super
|
@@ -55,12 +55,9 @@ module RuboCop
|
|
55
55
|
return if node.each_descendant(:dstr).any?
|
56
56
|
|
57
57
|
regexp_constructor(node) do |text|
|
58
|
-
|
58
|
+
parse_regexp(text.value)&.each_expression do |expr|
|
59
59
|
detect_offenses(text, expr)
|
60
60
|
end
|
61
|
-
rescue Regexp::Parser::Error
|
62
|
-
# Upon encountering an invalid regular expression,
|
63
|
-
# we aim to proceed and identify any remaining potential offenses.
|
64
61
|
end
|
65
62
|
end
|
66
63
|
|
@@ -130,7 +130,7 @@ module RuboCop
|
|
130
130
|
|
131
131
|
block_body_node.each_descendant(:next, :break) do |n|
|
132
132
|
# Ignore `next`/`break` inside an inner block
|
133
|
-
next if n.each_ancestor(:
|
133
|
+
next if n.each_ancestor(:any_block).first != block_body_node.parent
|
134
134
|
next unless n.first_argument
|
135
135
|
|
136
136
|
nodes << n.first_argument
|
@@ -108,7 +108,7 @@ module RuboCop
|
|
108
108
|
private
|
109
109
|
|
110
110
|
def loop_method?(node)
|
111
|
-
return false unless node.
|
111
|
+
return false unless node.any_block_type?
|
112
112
|
|
113
113
|
send_node = node.send_node
|
114
114
|
loopable = send_node.enumerable_method? || send_node.enumerator_method? ||
|
@@ -159,12 +159,12 @@ module RuboCop
|
|
159
159
|
|
160
160
|
# @!method dynamic_method_definition?(node)
|
161
161
|
def_node_matcher :dynamic_method_definition?, <<~PATTERN
|
162
|
-
{(send nil? :define_method ...) (
|
162
|
+
{(send nil? :define_method ...) (any_block (send nil? :define_method ...) ...)}
|
163
163
|
PATTERN
|
164
164
|
|
165
165
|
# @!method class_or_instance_eval?(node)
|
166
166
|
def_node_matcher :class_or_instance_eval?, <<~PATTERN
|
167
|
-
(
|
167
|
+
(any_block (send _ {:class_eval :instance_eval}) ...)
|
168
168
|
PATTERN
|
169
169
|
|
170
170
|
def check_node(node)
|
@@ -268,7 +268,7 @@ module RuboCop
|
|
268
268
|
end
|
269
269
|
|
270
270
|
def start_of_new_scope?(child)
|
271
|
-
child.
|
271
|
+
child.type?(:module, :class, :sclass) || eval_call?(child)
|
272
272
|
end
|
273
273
|
|
274
274
|
def eval_call?(child)
|
@@ -282,7 +282,7 @@ module RuboCop
|
|
282
282
|
matcher_name = :"#{m}_block?"
|
283
283
|
unless respond_to?(matcher_name)
|
284
284
|
self.class.def_node_matcher matcher_name, <<~PATTERN
|
285
|
-
(
|
285
|
+
(any_block (send {nil? const} {:#{m}} ...) ...)
|
286
286
|
PATTERN
|
287
287
|
end
|
288
288
|
|
@@ -17,7 +17,7 @@ module RuboCop
|
|
17
17
|
# rescue, ensure, etc.
|
18
18
|
#
|
19
19
|
# This cop's autocorrection avoids cases like `a ||= 1` because removing assignment from
|
20
|
-
# operator assignment can cause NameError if this assignment has been used to declare
|
20
|
+
# operator assignment can cause `NameError` if this assignment has been used to declare
|
21
21
|
# a local variable. For example, replacing `a ||= 1` with `a || 1` may cause
|
22
22
|
# "undefined local variable or method `a' for main:Object (NameError)".
|
23
23
|
#
|