rubocop 1.57.1 → 1.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/README.md +4 -5
- data/assets/output.css.erb +159 -0
- data/assets/output.html.erb +1 -160
- data/config/default.yml +136 -19
- data/lib/rubocop/cached_data.rb +11 -3
- data/lib/rubocop/cli/command/auto_generate_config.rb +22 -8
- data/lib/rubocop/cli/command/lsp.rb +2 -2
- data/lib/rubocop/cli/command/show_docs_url.rb +2 -2
- data/lib/rubocop/cli.rb +10 -1
- data/lib/rubocop/config.rb +36 -12
- data/lib/rubocop/config_finder.rb +12 -2
- data/lib/rubocop/config_loader.rb +1 -2
- data/lib/rubocop/config_loader_resolver.rb +9 -3
- data/lib/rubocop/config_obsoletion.rb +11 -8
- data/lib/rubocop/config_validator.rb +14 -7
- data/lib/rubocop/cop/autocorrect_logic.rb +6 -1
- data/lib/rubocop/cop/base.rb +63 -16
- data/lib/rubocop/cop/bundler/gem_comment.rb +2 -2
- data/lib/rubocop/cop/bundler/gem_version.rb +3 -5
- data/lib/rubocop/cop/cop.rb +20 -2
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +4 -8
- data/lib/rubocop/cop/correctors/for_to_each_corrector.rb +5 -13
- data/lib/rubocop/cop/documentation.rb +16 -6
- data/lib/rubocop/cop/exclude_limit.rb +1 -1
- data/lib/rubocop/cop/force.rb +12 -0
- data/lib/rubocop/cop/gemspec/add_runtime_dependency.rb +38 -0
- data/lib/rubocop/cop/gemspec/dependency_version.rb +3 -5
- data/lib/rubocop/cop/gemspec/deprecated_attribute_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/duplicated_assignment.rb +2 -2
- data/lib/rubocop/cop/gemspec/required_ruby_version.rb +5 -1
- data/lib/rubocop/cop/gemspec/ruby_version_globals_usage.rb +3 -3
- data/lib/rubocop/cop/internal_affairs/example_description.rb +6 -5
- data/lib/rubocop/cop/internal_affairs/method_name_end_with.rb +8 -6
- data/lib/rubocop/cop/internal_affairs/method_name_equal.rb +19 -20
- data/lib/rubocop/cop/internal_affairs/node_first_or_last_argument.rb +53 -0
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +123 -29
- data/lib/rubocop/cop/internal_affairs/redundant_expect_offense_arguments.rb +34 -0
- data/lib/rubocop/cop/internal_affairs.rb +2 -0
- data/lib/rubocop/cop/layout/argument_alignment.rb +1 -1
- data/lib/rubocop/cop/layout/case_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/empty_comment.rb +3 -1
- data/lib/rubocop/cop/layout/empty_line_after_magic_comment.rb +14 -7
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +1 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +15 -3
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -10
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +24 -7
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +1 -1
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -2
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +2 -2
- data/lib/rubocop/cop/layout/indentation_width.rb +1 -1
- data/lib/rubocop/cop/layout/line_continuation_leading_space.rb +1 -1
- data/lib/rubocop/cop/layout/line_length.rb +20 -20
- data/lib/rubocop/cop/layout/redundant_line_break.rb +16 -3
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +4 -4
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +53 -20
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +19 -10
- data/lib/rubocop/cop/layout/space_inside_hash_literal_braces.rb +1 -1
- data/lib/rubocop/cop/layout/space_inside_string_interpolation.rb +3 -4
- data/lib/rubocop/cop/legacy/corrector.rb +12 -2
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +6 -6
- data/lib/rubocop/cop/lint/binary_operator_with_identical_operands.rb +2 -2
- data/lib/rubocop/cop/lint/constant_overwritten_in_rescue.rb +1 -1
- data/lib/rubocop/cop/lint/debugger.rb +29 -3
- data/lib/rubocop/cop/lint/deprecated_class_methods.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_case_condition.rb +1 -1
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +2 -2
- data/lib/rubocop/cop/lint/empty_when.rb +1 -1
- data/lib/rubocop/cop/lint/erb_new_arguments.rb +24 -17
- data/lib/rubocop/cop/lint/float_comparison.rb +10 -0
- data/lib/rubocop/cop/lint/hash_compare_by_identity.rb +2 -1
- data/lib/rubocop/cop/lint/implicit_string_concatenation.rb +14 -7
- data/lib/rubocop/cop/lint/it_without_arguments_in_block.rb +56 -0
- data/lib/rubocop/cop/lint/literal_as_condition.rb +1 -1
- data/lib/rubocop/cop/lint/literal_assignment_in_condition.rb +85 -0
- data/lib/rubocop/cop/lint/mixed_case_range.rb +9 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/next_without_accumulator.rb +6 -21
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +3 -5
- data/lib/rubocop/cop/lint/number_conversion.rb +9 -4
- data/lib/rubocop/cop/lint/redundant_safe_navigation.rb +54 -6
- data/lib/rubocop/cop/lint/redundant_with_index.rb +6 -2
- data/lib/rubocop/cop/lint/redundant_with_object.rb +2 -2
- data/lib/rubocop/cop/lint/rescue_type.rb +1 -3
- data/lib/rubocop/cop/lint/safe_navigation_chain.rb +3 -4
- data/lib/rubocop/cop/lint/script_permission.rb +3 -3
- data/lib/rubocop/cop/lint/self_assignment.rb +38 -0
- data/lib/rubocop/cop/lint/shadowed_argument.rb +1 -0
- data/lib/rubocop/cop/lint/symbol_conversion.rb +7 -2
- data/lib/rubocop/cop/lint/syntax.rb +6 -3
- data/lib/rubocop/cop/lint/to_enum_arguments.rb +1 -3
- data/lib/rubocop/cop/lint/trailing_comma_in_attribute_declaration.rb +1 -1
- data/lib/rubocop/cop/lint/unmodified_reduce_accumulator.rb +3 -2
- data/lib/rubocop/cop/lint/unreachable_code.rb +4 -2
- data/lib/rubocop/cop/lint/unreachable_loop.rb +8 -2
- data/lib/rubocop/cop/lint/useless_access_modifier.rb +2 -2
- data/lib/rubocop/cop/lint/useless_times.rb +2 -2
- data/lib/rubocop/cop/lint/void.rb +53 -12
- data/lib/rubocop/cop/metrics/abc_size.rb +3 -3
- data/lib/rubocop/cop/metrics/block_nesting.rb +19 -7
- data/lib/rubocop/cop/metrics/class_length.rb +6 -1
- data/lib/rubocop/cop/metrics/utils/code_length_calculator.rb +5 -5
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/allowed_methods.rb +7 -1
- data/lib/rubocop/cop/mixin/allowed_pattern.rb +15 -3
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +1 -1
- data/lib/rubocop/cop/mixin/code_length.rb +12 -1
- data/lib/rubocop/cop/mixin/comments_help.rb +16 -12
- data/lib/rubocop/cop/mixin/configurable_formatting.rb +1 -0
- data/lib/rubocop/cop/mixin/configurable_max.rb +5 -1
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +23 -13
- data/lib/rubocop/cop/mixin/method_complexity.rb +15 -6
- data/lib/rubocop/cop/mixin/multiline_expression_indentation.rb +1 -1
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +1 -1
- data/lib/rubocop/cop/mixin/rescue_node.rb +4 -0
- data/lib/rubocop/cop/mixin/safe_assignment.rb +1 -1
- data/lib/rubocop/cop/mixin/space_before_punctuation.rb +1 -1
- data/lib/rubocop/cop/naming/block_forwarding.rb +34 -7
- data/lib/rubocop/cop/naming/constant_name.rb +1 -2
- data/lib/rubocop/cop/naming/file_name.rb +2 -2
- data/lib/rubocop/cop/naming/inclusive_language.rb +1 -2
- data/lib/rubocop/cop/naming/memoized_instance_variable_name.rb +1 -1
- data/lib/rubocop/cop/naming/predicate_name.rb +2 -2
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/compound_hash.rb +2 -2
- data/lib/rubocop/cop/security/open.rb +2 -2
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +52 -2
- data/lib/rubocop/cop/style/accessor_grouping.rb +1 -1
- data/lib/rubocop/cop/style/alias.rb +1 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +155 -21
- data/lib/rubocop/cop/style/array_first_last.rb +64 -0
- data/lib/rubocop/cop/style/auto_resource_cleanup.rb +21 -14
- data/lib/rubocop/cop/style/bisected_attr_accessor.rb +2 -2
- data/lib/rubocop/cop/style/case_like_if.rb +5 -5
- data/lib/rubocop/cop/style/class_check.rb +1 -0
- data/lib/rubocop/cop/style/class_vars.rb +3 -3
- data/lib/rubocop/cop/style/collection_compact.rb +21 -11
- data/lib/rubocop/cop/style/combinable_loops.rb +13 -7
- data/lib/rubocop/cop/style/commented_keyword.rb +5 -2
- data/lib/rubocop/cop/style/concat_array_literals.rb +1 -0
- data/lib/rubocop/cop/style/conditional_assignment.rb +7 -8
- data/lib/rubocop/cop/style/copyright.rb +31 -21
- data/lib/rubocop/cop/style/date_time.rb +5 -4
- data/lib/rubocop/cop/style/documentation.rb +24 -24
- data/lib/rubocop/cop/style/documentation_method.rb +20 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +7 -7
- data/lib/rubocop/cop/style/each_with_object.rb +2 -2
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/eval_with_location.rb +6 -15
- data/lib/rubocop/cop/style/exact_regexp_match.rb +4 -2
- data/lib/rubocop/cop/style/explicit_block_argument.rb +2 -2
- data/lib/rubocop/cop/style/for.rb +2 -0
- data/lib/rubocop/cop/style/format_string.rb +9 -9
- data/lib/rubocop/cop/style/hash_each_methods.rb +105 -11
- data/lib/rubocop/cop/style/hash_except.rb +10 -6
- data/lib/rubocop/cop/style/hash_syntax.rb +24 -2
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +12 -1
- data/lib/rubocop/cop/style/if_with_boolean_literal_branches.rb +5 -3
- data/lib/rubocop/cop/style/inverse_methods.rb +14 -13
- data/lib/rubocop/cop/style/invertible_unless_condition.rb +44 -2
- data/lib/rubocop/cop/style/map_compact_with_conditional_block.rb +82 -50
- data/lib/rubocop/cop/style/map_into_array.rb +175 -0
- data/lib/rubocop/cop/style/map_to_hash.rb +18 -8
- data/lib/rubocop/cop/style/map_to_set.rb +1 -1
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +19 -5
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +2 -4
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +20 -0
- data/lib/rubocop/cop/style/method_def_parentheses.rb +1 -1
- data/lib/rubocop/cop/style/missing_respond_to_missing.rb +2 -2
- data/lib/rubocop/cop/style/multiline_method_signature.rb +10 -1
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +5 -3
- data/lib/rubocop/cop/style/next.rb +1 -1
- data/lib/rubocop/cop/style/nil_comparison.rb +2 -0
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +1 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +10 -2
- data/lib/rubocop/cop/style/object_then.rb +5 -3
- data/lib/rubocop/cop/style/one_line_conditional.rb +1 -1
- data/lib/rubocop/cop/style/operator_method_call.rb +2 -2
- data/lib/rubocop/cop/style/parallel_assignment.rb +3 -5
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +8 -0
- data/lib/rubocop/cop/style/quoted_symbols.rb +1 -1
- data/lib/rubocop/cop/style/raise_args.rb +4 -1
- data/lib/rubocop/cop/style/redundant_argument.rb +27 -3
- data/lib/rubocop/cop/style/redundant_assignment.rb +10 -2
- data/lib/rubocop/cop/style/redundant_begin.rb +1 -1
- data/lib/rubocop/cop/style/redundant_current_directory_in_path.rb +5 -4
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +17 -10
- data/lib/rubocop/cop/style/redundant_each.rb +7 -4
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +3 -3
- data/lib/rubocop/cop/style/redundant_file_extension_in_require.rb +1 -1
- data/lib/rubocop/cop/style/redundant_filter_chain.rb +5 -4
- data/lib/rubocop/cop/style/redundant_line_continuation.rb +19 -2
- data/lib/rubocop/cop/style/redundant_parentheses.rb +50 -19
- data/lib/rubocop/cop/style/redundant_percent_q.rb +1 -1
- data/lib/rubocop/cop/style/redundant_return.rb +7 -1
- data/lib/rubocop/cop/style/redundant_self.rb +17 -2
- data/lib/rubocop/cop/style/redundant_sort.rb +9 -8
- data/lib/rubocop/cop/style/redundant_sort_by.rb +2 -2
- data/lib/rubocop/cop/style/redundant_string_escape.rb +1 -1
- data/lib/rubocop/cop/style/require_order.rb +1 -1
- data/lib/rubocop/cop/style/sample.rb +3 -4
- data/lib/rubocop/cop/style/select_by_regexp.rb +7 -6
- data/lib/rubocop/cop/style/self_assignment.rb +1 -1
- data/lib/rubocop/cop/style/semicolon.rb +8 -0
- data/lib/rubocop/cop/style/send.rb +4 -4
- data/lib/rubocop/cop/style/send_with_literal_method_name.rb +104 -0
- data/lib/rubocop/cop/style/single_argument_dig.rb +7 -3
- data/lib/rubocop/cop/style/single_line_do_end_block.rb +3 -1
- data/lib/rubocop/cop/style/slicing_with_range.rb +76 -10
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -2
- data/lib/rubocop/cop/style/string_chars.rb +1 -0
- data/lib/rubocop/cop/style/strip.rb +7 -4
- data/lib/rubocop/cop/style/super_arguments.rb +174 -0
- data/lib/rubocop/cop/style/super_with_args_parentheses.rb +35 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +75 -5
- data/lib/rubocop/cop/style/top_level_method_definition.rb +1 -1
- data/lib/rubocop/cop/style/unpack_first.rb +11 -14
- data/lib/rubocop/cop/style/zero_length_predicate.rb +28 -24
- data/lib/rubocop/cop/team.rb +13 -0
- data/lib/rubocop/cop/util.rb +7 -1
- data/lib/rubocop/cop/utils/regexp_ranges.rb +1 -1
- data/lib/rubocop/cops_documentation_generator.rb +16 -4
- data/lib/rubocop/directive_comment.rb +10 -8
- data/lib/rubocop/ext/regexp_node.rb +9 -4
- data/lib/rubocop/ext/regexp_parser.rb +4 -21
- data/lib/rubocop/formatter/clang_style_formatter.rb +3 -7
- data/lib/rubocop/formatter/disabled_config_formatter.rb +23 -8
- data/lib/rubocop/formatter/formatter_set.rb +7 -1
- data/lib/rubocop/formatter/html_formatter.rb +37 -14
- data/lib/rubocop/formatter/json_formatter.rb +0 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +12 -2
- data/lib/rubocop/formatter/tap_formatter.rb +3 -7
- data/lib/rubocop/formatter.rb +1 -1
- data/lib/rubocop/lockfile.rb +56 -7
- data/lib/rubocop/lsp/logger.rb +1 -1
- data/lib/rubocop/lsp/routes.rb +12 -15
- data/lib/rubocop/lsp/runtime.rb +1 -1
- data/lib/rubocop/lsp/server.rb +7 -2
- data/lib/rubocop/lsp/severity.rb +1 -1
- data/lib/rubocop/lsp.rb +36 -0
- data/lib/rubocop/magic_comment.rb +1 -1
- data/lib/rubocop/options.rb +14 -11
- data/lib/rubocop/path_util.rb +6 -2
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/result_cache.rb +0 -1
- data/lib/rubocop/rspec/cop_helper.rb +8 -2
- data/lib/rubocop/rspec/expect_offense.rb +16 -8
- data/lib/rubocop/rspec/shared_contexts.rb +73 -16
- data/lib/rubocop/rspec/support.rb +3 -0
- data/lib/rubocop/runner.rb +14 -3
- data/lib/rubocop/server/cache.rb +11 -2
- data/lib/rubocop/server/client_command/exec.rb +2 -3
- data/lib/rubocop/server/client_command/start.rb +1 -1
- data/lib/rubocop/server/core.rb +4 -0
- data/lib/rubocop/server/server_command/exec.rb +0 -1
- data/lib/rubocop/target_finder.rb +84 -78
- data/lib/rubocop/target_ruby.rb +82 -80
- data/lib/rubocop/version.rb +19 -4
- data/lib/rubocop.rb +8 -0
- metadata +27 -29
- /data/lib/rubocop/formatter/{git_hub_actions_formatter.rb → github_actions_formatter.rb} +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for usages of `each` with `<<`, `push`, or `append` which
|
|
7
|
+
# can be replaced by `map`.
|
|
8
|
+
#
|
|
9
|
+
# If `PreferredMethods` is configured for `map` in `Style/CollectionMethods`,
|
|
10
|
+
# this cop uses the specified method for replacement.
|
|
11
|
+
#
|
|
12
|
+
# NOTE: The return value of `Enumerable#each` is `self`, whereas the
|
|
13
|
+
# return value of `Enumerable#map` is an `Array`. They are not autocorrected
|
|
14
|
+
# when a return value could be used because these types differ.
|
|
15
|
+
#
|
|
16
|
+
# NOTE: It only detects when the mapping destination is a local variable
|
|
17
|
+
# initialized as an empty array and referred to only by the pushing operation.
|
|
18
|
+
# This is because, if not, it's challenging to statically guarantee that the
|
|
19
|
+
# mapping destination variable remains an empty array:
|
|
20
|
+
#
|
|
21
|
+
# [source,ruby]
|
|
22
|
+
# ----
|
|
23
|
+
# ret = []
|
|
24
|
+
# src.each { |e| ret << e * 2 } # `<<` method may mutate `ret`
|
|
25
|
+
#
|
|
26
|
+
# dest = []
|
|
27
|
+
# src.each { |e| dest << transform(e, dest) } # `transform` method may mutate `dest`
|
|
28
|
+
# ----
|
|
29
|
+
#
|
|
30
|
+
# @safety
|
|
31
|
+
# This cop is unsafe because not all objects that have an `each`
|
|
32
|
+
# method also have a `map` method (e.g. `ENV`). Additionally, for calls
|
|
33
|
+
# with a block, not all objects that have a `map` method return an array
|
|
34
|
+
# (e.g. `Enumerator::Lazy`).
|
|
35
|
+
#
|
|
36
|
+
# @example
|
|
37
|
+
# # bad
|
|
38
|
+
# dest = []
|
|
39
|
+
# src.each { |e| dest << e * 2 }
|
|
40
|
+
# dest
|
|
41
|
+
#
|
|
42
|
+
# # good
|
|
43
|
+
# dest = src.map { |e| e * 2 }
|
|
44
|
+
#
|
|
45
|
+
# # good - contains another operation
|
|
46
|
+
# dest = []
|
|
47
|
+
# src.each { |e| dest << e * 2; puts e }
|
|
48
|
+
# dest
|
|
49
|
+
#
|
|
50
|
+
class MapIntoArray < Base
|
|
51
|
+
include RangeHelp
|
|
52
|
+
extend AutoCorrector
|
|
53
|
+
|
|
54
|
+
MSG = 'Use `%<new_method_name>s` instead of `each` to map elements into an array.'
|
|
55
|
+
|
|
56
|
+
# @!method each_block_with_push?(node)
|
|
57
|
+
def_node_matcher :each_block_with_push?, <<-PATTERN
|
|
58
|
+
[
|
|
59
|
+
^({begin kwbegin} ...)
|
|
60
|
+
({block numblock} (send !{nil? self} :each) _
|
|
61
|
+
(send (lvar _) {:<< :push :append} _))
|
|
62
|
+
]
|
|
63
|
+
PATTERN
|
|
64
|
+
|
|
65
|
+
# @!method empty_array_asgn?(node)
|
|
66
|
+
def_node_matcher :empty_array_asgn?, '(lvasgn _ (array))'
|
|
67
|
+
|
|
68
|
+
# @!method lvar_ref?(node, name)
|
|
69
|
+
def_node_matcher :lvar_ref?, '(lvar %1)'
|
|
70
|
+
|
|
71
|
+
def self.joining_forces
|
|
72
|
+
VariableForce
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def after_leaving_scope(scope, _variable_table)
|
|
76
|
+
(@scopes ||= []) << scope
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def on_block(node)
|
|
80
|
+
return unless each_block_with_push?(node)
|
|
81
|
+
|
|
82
|
+
dest_var = find_dest_var(node)
|
|
83
|
+
return unless (asgn = find_closest_assignment(node, dest_var))
|
|
84
|
+
return unless empty_array_asgn?(asgn)
|
|
85
|
+
return unless dest_used_only_for_mapping?(node, dest_var, asgn)
|
|
86
|
+
|
|
87
|
+
register_offense(node, dest_var, asgn)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
alias on_numblock on_block
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
def find_dest_var(block)
|
|
95
|
+
node = block.body.receiver
|
|
96
|
+
name = node.children.first
|
|
97
|
+
|
|
98
|
+
candidates = @scopes.lazy.filter_map { |s| s.variables[name] }
|
|
99
|
+
candidates.find { |v| v.references.any? { |n| n.node.equal?(node) } }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def find_closest_assignment(block, dest_var)
|
|
103
|
+
dest_var.assignments.reverse_each.lazy.map(&:node).find do |node|
|
|
104
|
+
node.source_range.end_pos < block.source_range.begin_pos
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def dest_used_only_for_mapping?(block, dest_var, asgn)
|
|
109
|
+
range = asgn.source_range.join(block.source_range)
|
|
110
|
+
|
|
111
|
+
asgn.parent.equal?(block.parent) &&
|
|
112
|
+
dest_var.references.one? { |r| range.contains?(r.node.source_range) } &&
|
|
113
|
+
dest_var.assignments.one? { |a| range.contains?(a.node.source_range) }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def register_offense(block, dest_var, asgn)
|
|
117
|
+
add_offense(block, message: format(MSG, new_method_name: new_method_name)) do |corrector|
|
|
118
|
+
next if return_value_used?(block)
|
|
119
|
+
|
|
120
|
+
corrector.replace(block.send_node.selector, new_method_name)
|
|
121
|
+
remove_assignment(corrector, asgn)
|
|
122
|
+
correct_push_node(corrector, block.body)
|
|
123
|
+
correct_return_value_handling(corrector, block, dest_var)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def new_method_name
|
|
128
|
+
default = 'map'
|
|
129
|
+
alternative = config.for_cop('Style/CollectionMethods').dig('PreferredMethods', default)
|
|
130
|
+
alternative || default
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def return_value_used?(node)
|
|
134
|
+
parent = node.parent
|
|
135
|
+
|
|
136
|
+
case parent&.type
|
|
137
|
+
when nil
|
|
138
|
+
false
|
|
139
|
+
when :begin, :kwbegin
|
|
140
|
+
!node.right_sibling && return_value_used?(parent)
|
|
141
|
+
when :block, :numblock
|
|
142
|
+
!parent.void_context?
|
|
143
|
+
else
|
|
144
|
+
true
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def remove_assignment(corrector, asgn)
|
|
149
|
+
range = range_with_surrounding_space(asgn.source_range, side: :right)
|
|
150
|
+
range = range_with_surrounding_space(range, side: :right, newlines: false)
|
|
151
|
+
|
|
152
|
+
corrector.remove(range)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def correct_push_node(corrector, push_node)
|
|
156
|
+
range = push_node.source_range
|
|
157
|
+
arg_range = push_node.first_argument.source_range
|
|
158
|
+
|
|
159
|
+
corrector.remove(range_between(range.begin_pos, arg_range.begin_pos))
|
|
160
|
+
corrector.remove(range_between(arg_range.end_pos, range.end_pos))
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def correct_return_value_handling(corrector, block, dest_var)
|
|
164
|
+
next_node = block.right_sibling
|
|
165
|
+
|
|
166
|
+
if lvar_ref?(next_node, dest_var.name)
|
|
167
|
+
corrector.remove(range_with_surrounding_space(next_node.source_range, side: :left))
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
corrector.insert_before(block, "#{dest_var.name} = ")
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
@@ -34,37 +34,47 @@ module RuboCop
|
|
|
34
34
|
|
|
35
35
|
minimum_target_ruby_version 2.6
|
|
36
36
|
|
|
37
|
-
MSG = 'Pass a block to `to_h` instead of calling `%<method>s
|
|
37
|
+
MSG = 'Pass a block to `to_h` instead of calling `%<method>s%<dot>sto_h`.'
|
|
38
38
|
RESTRICT_ON_SEND = %i[to_h].freeze
|
|
39
39
|
|
|
40
|
-
# @!method map_to_h
|
|
41
|
-
def_node_matcher :map_to_h
|
|
40
|
+
# @!method map_to_h(node)
|
|
41
|
+
def_node_matcher :map_to_h, <<~PATTERN
|
|
42
42
|
{
|
|
43
|
-
$(
|
|
44
|
-
$(
|
|
43
|
+
$(call ({block numblock} $(call _ {:map :collect}) ...) :to_h)
|
|
44
|
+
$(call $(call _ {:map :collect} (block_pass sym)) :to_h)
|
|
45
45
|
}
|
|
46
46
|
PATTERN
|
|
47
47
|
|
|
48
|
+
def self.autocorrect_incompatible_with
|
|
49
|
+
[Layout::SingleLineBlockChain]
|
|
50
|
+
end
|
|
51
|
+
|
|
48
52
|
def on_send(node)
|
|
49
|
-
return unless (to_h_node, map_node = map_to_h
|
|
53
|
+
return unless (to_h_node, map_node = map_to_h(node))
|
|
50
54
|
|
|
51
|
-
message = format(MSG, method: map_node.loc.selector.source)
|
|
55
|
+
message = format(MSG, method: map_node.loc.selector.source, dot: to_h_node.loc.dot.source)
|
|
52
56
|
add_offense(map_node.loc.selector, message: message) do |corrector|
|
|
53
57
|
# If the `to_h` call already has a block, do not autocorrect.
|
|
54
|
-
next if to_h_node.
|
|
58
|
+
next if to_h_node.block_literal?
|
|
55
59
|
|
|
56
60
|
autocorrect(corrector, to_h_node, map_node)
|
|
57
61
|
end
|
|
58
62
|
end
|
|
63
|
+
alias on_csend on_send
|
|
59
64
|
|
|
60
65
|
private
|
|
61
66
|
|
|
67
|
+
# rubocop:disable Metrics/AbcSize
|
|
62
68
|
def autocorrect(corrector, to_h, map)
|
|
63
69
|
removal_range = range_between(to_h.loc.dot.begin_pos, to_h.loc.selector.end_pos)
|
|
64
70
|
|
|
65
71
|
corrector.remove(range_with_surrounding_space(removal_range, side: :left))
|
|
72
|
+
if (map_dot = map.loc.dot)
|
|
73
|
+
corrector.replace(map_dot, to_h.loc.dot.source)
|
|
74
|
+
end
|
|
66
75
|
corrector.replace(map.loc.selector, 'to_h')
|
|
67
76
|
end
|
|
77
|
+
# rubocop:enable Metrics/AbcSize
|
|
68
78
|
end
|
|
69
79
|
end
|
|
70
80
|
end
|
|
@@ -44,7 +44,7 @@ module RuboCop
|
|
|
44
44
|
message = format(MSG, method: map_node.loc.selector.source)
|
|
45
45
|
add_offense(map_node.loc.selector, message: message) do |corrector|
|
|
46
46
|
# If the `to_set` call already has a block, do not autocorrect.
|
|
47
|
-
next if to_set_node.
|
|
47
|
+
next if to_set_node.block_literal?
|
|
48
48
|
|
|
49
49
|
autocorrect(corrector, to_set_node, map_node)
|
|
50
50
|
end
|
|
@@ -18,6 +18,7 @@ module RuboCop
|
|
|
18
18
|
return if inside_endless_method_def?(node)
|
|
19
19
|
return if require_parentheses_for_hash_value_omission?(node)
|
|
20
20
|
return if syntax_like_method_call?(node)
|
|
21
|
+
return if method_call_before_constant_resolution?(node)
|
|
21
22
|
return if super_call_without_arguments?(node)
|
|
22
23
|
return if legitimate_call_with_parentheses?(node)
|
|
23
24
|
return if allowed_camel_case_method_call?(node)
|
|
@@ -63,6 +64,10 @@ module RuboCop
|
|
|
63
64
|
node.implicit_call? || node.operator_method?
|
|
64
65
|
end
|
|
65
66
|
|
|
67
|
+
def method_call_before_constant_resolution?(node)
|
|
68
|
+
node.parent&.const_type?
|
|
69
|
+
end
|
|
70
|
+
|
|
66
71
|
def super_call_without_arguments?(node)
|
|
67
72
|
node.super_type? && node.arguments.none?
|
|
68
73
|
end
|
|
@@ -86,6 +91,7 @@ module RuboCop
|
|
|
86
91
|
|
|
87
92
|
def legitimate_call_with_parentheses?(node) # rubocop:disable Metrics/PerceivedComplexity
|
|
88
93
|
call_in_literals?(node) ||
|
|
94
|
+
node.parent&.when_type? ||
|
|
89
95
|
call_with_ambiguous_arguments?(node) ||
|
|
90
96
|
call_in_logical_operators?(node) ||
|
|
91
97
|
call_in_optional_arguments?(node) ||
|
|
@@ -126,23 +132,31 @@ module RuboCop
|
|
|
126
132
|
|
|
127
133
|
def call_with_ambiguous_arguments?(node) # rubocop:disable Metrics/PerceivedComplexity
|
|
128
134
|
call_with_braced_block?(node) ||
|
|
135
|
+
call_in_argument_with_block?(node) ||
|
|
129
136
|
call_as_argument_or_chain?(node) ||
|
|
130
137
|
call_in_match_pattern?(node) ||
|
|
131
138
|
hash_literal_in_arguments?(node) ||
|
|
132
139
|
node.descendants.any? do |n|
|
|
133
|
-
n.forwarded_args_type? ||
|
|
134
|
-
|
|
140
|
+
n.forwarded_args_type? || n.block_type? || n.numblock_type? ||
|
|
141
|
+
ambiguous_literal?(n) || logical_operator?(n)
|
|
135
142
|
end
|
|
136
143
|
end
|
|
137
144
|
|
|
138
145
|
def call_with_braced_block?(node)
|
|
139
|
-
(node.
|
|
146
|
+
(node.call_type? || node.super_type?) && node.block_node&.braces?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def call_in_argument_with_block?(node)
|
|
150
|
+
parent = node.parent&.block_type? && node.parent&.parent
|
|
151
|
+
return false unless parent
|
|
152
|
+
|
|
153
|
+
parent.call_type? || parent.super_type? || parent.yield_type?
|
|
140
154
|
end
|
|
141
155
|
|
|
142
156
|
def call_as_argument_or_chain?(node)
|
|
143
157
|
node.parent &&
|
|
144
|
-
(
|
|
145
|
-
|
|
158
|
+
(node.parent.call_type? || node.parent.super_type? || node.parent.yield_type?) &&
|
|
159
|
+
!assigned_before?(node.parent, node)
|
|
146
160
|
end
|
|
147
161
|
|
|
148
162
|
def call_in_match_pattern?(node)
|
|
@@ -218,15 +218,13 @@ module RuboCop
|
|
|
218
218
|
send(style, node) # call require_parentheses or omit_parentheses
|
|
219
219
|
end
|
|
220
220
|
alias on_csend on_send
|
|
221
|
-
alias on_super on_send
|
|
222
221
|
alias on_yield on_send
|
|
223
222
|
|
|
224
223
|
private
|
|
225
224
|
|
|
226
225
|
def args_begin(node)
|
|
227
226
|
loc = node.loc
|
|
228
|
-
selector =
|
|
229
|
-
node.super_type? || node.yield_type? ? loc.keyword : loc.selector
|
|
227
|
+
selector = node.yield_type? ? loc.keyword : loc.selector
|
|
230
228
|
|
|
231
229
|
resize_by = args_parenthesized?(node) ? 2 : 1
|
|
232
230
|
selector.end.resize(resize_by)
|
|
@@ -239,7 +237,7 @@ module RuboCop
|
|
|
239
237
|
def args_parenthesized?(node)
|
|
240
238
|
return false unless node.arguments.one?
|
|
241
239
|
|
|
242
|
-
first_node = node.
|
|
240
|
+
first_node = node.first_argument
|
|
243
241
|
first_node.begin_type? && first_node.parenthesized_call?
|
|
244
242
|
end
|
|
245
243
|
end
|
|
@@ -8,6 +8,9 @@ module RuboCop
|
|
|
8
8
|
# This cop can be customized allowed methods with `AllowedMethods`.
|
|
9
9
|
# By default, there are no methods to allowed.
|
|
10
10
|
#
|
|
11
|
+
# NOTE: This cop allows the use of `it()` without arguments in blocks,
|
|
12
|
+
# as in `0.times { it() }`, following `Lint/ItWithoutArgumentsInBlock` cop.
|
|
13
|
+
#
|
|
11
14
|
# @example
|
|
12
15
|
# # bad
|
|
13
16
|
# object.some_method()
|
|
@@ -30,15 +33,18 @@ module RuboCop
|
|
|
30
33
|
|
|
31
34
|
MSG = 'Do not use parentheses for method calls with no arguments.'
|
|
32
35
|
|
|
36
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
|
33
37
|
def on_send(node)
|
|
34
38
|
return unless !node.arguments? && node.parenthesized?
|
|
35
39
|
return if ineligible_node?(node)
|
|
36
40
|
return if default_argument?(node)
|
|
37
41
|
return if allowed_method_name?(node.method_name)
|
|
38
42
|
return if same_name_assignment?(node)
|
|
43
|
+
return if parenthesized_it_method_in_block?(node)
|
|
39
44
|
|
|
40
45
|
register_offense(node)
|
|
41
46
|
end
|
|
47
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
|
42
48
|
|
|
43
49
|
private
|
|
44
50
|
|
|
@@ -71,6 +77,20 @@ module RuboCop
|
|
|
71
77
|
end
|
|
72
78
|
end
|
|
73
79
|
|
|
80
|
+
# Respects `Lint/ItWithoutArgumentsInBlock` cop and the following Ruby 3.3's warning:
|
|
81
|
+
#
|
|
82
|
+
# $ ruby -e '0.times { begin; it; end }'
|
|
83
|
+
# -e:1: warning: `it` calls without arguments will refer to the first block param in
|
|
84
|
+
# Ruby 3.4; use it() or self.it
|
|
85
|
+
#
|
|
86
|
+
def parenthesized_it_method_in_block?(node)
|
|
87
|
+
return false unless node.method?(:it)
|
|
88
|
+
return false unless (block_node = node.each_ancestor(:block).first)
|
|
89
|
+
return false unless block_node.arguments.empty_and_without_delimiters?
|
|
90
|
+
|
|
91
|
+
!node.receiver && node.arguments.empty? && !node.block_literal?
|
|
92
|
+
end
|
|
93
|
+
|
|
74
94
|
def any_assignment?(node)
|
|
75
95
|
node.each_ancestor(*AST::Node::ASSIGNMENTS).any? do |asgn_node|
|
|
76
96
|
# `obj.method = value` parses as (send ... :method= ...), and will
|
|
@@ -170,7 +170,7 @@ module RuboCop
|
|
|
170
170
|
return true if node.arguments.any? do |arg|
|
|
171
171
|
arg.forward_arg_type? || arg.restarg_type? || arg.kwrestarg_type?
|
|
172
172
|
end
|
|
173
|
-
return false unless (last_argument = node.
|
|
173
|
+
return false unless (last_argument = node.last_argument)
|
|
174
174
|
|
|
175
175
|
last_argument.blockarg_type? && last_argument.name.nil?
|
|
176
176
|
end
|
|
@@ -38,6 +38,7 @@ module RuboCop
|
|
|
38
38
|
|
|
39
39
|
private
|
|
40
40
|
|
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
|
41
42
|
def autocorrect(corrector, node, begin_of_arguments)
|
|
42
43
|
arguments = node.arguments
|
|
43
44
|
joined_arguments = arguments.map(&:source).join(', ')
|
|
@@ -49,9 +50,17 @@ module RuboCop
|
|
|
49
50
|
corrector.remove(range_by_whole_lines(arguments.loc.end, include_final_newline: true))
|
|
50
51
|
end
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
arguments_range = arguments_range(node)
|
|
54
|
+
# If the method name isn't on the same line as def, move it directly after def
|
|
55
|
+
if arguments_range.first_line != opening_line(node)
|
|
56
|
+
corrector.remove(node.loc.name)
|
|
57
|
+
corrector.insert_after(node.loc.keyword, " #{node.loc.name.source}")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
corrector.remove(arguments_range)
|
|
53
61
|
corrector.insert_after(begin_of_arguments, joined_arguments)
|
|
54
62
|
end
|
|
63
|
+
# rubocop:enable Metrics/AbcSize
|
|
55
64
|
|
|
56
65
|
def last_line_source_of_arguments(arguments)
|
|
57
66
|
processed_source[arguments.last_line - 1].strip
|
|
@@ -47,19 +47,21 @@ module RuboCop
|
|
|
47
47
|
message = enforce_single_line_ternary_operator?(node) ? MSG_SINGLE_LINE : MSG_IF
|
|
48
48
|
|
|
49
49
|
add_offense(node, message: message) do |corrector|
|
|
50
|
+
next if part_of_ignored_node?(node)
|
|
51
|
+
|
|
50
52
|
autocorrect(corrector, node)
|
|
53
|
+
|
|
54
|
+
ignore_node(node)
|
|
51
55
|
end
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
private
|
|
55
59
|
|
|
56
60
|
def offense?(node)
|
|
57
|
-
node.ternary? && node.multiline?
|
|
61
|
+
node.ternary? && node.multiline? && node.source != replacement(node)
|
|
58
62
|
end
|
|
59
63
|
|
|
60
64
|
def autocorrect(corrector, node)
|
|
61
|
-
return unless offense?(node)
|
|
62
|
-
|
|
63
65
|
corrector.replace(node, replacement(node))
|
|
64
66
|
return unless (parent = node.parent)
|
|
65
67
|
return unless (comments_in_condition = comments_in_condition(node))
|
|
@@ -118,12 +118,14 @@ module RuboCop
|
|
|
118
118
|
|
|
119
119
|
return unless numeric && operator && replacement_supported?(operator)
|
|
120
120
|
|
|
121
|
-
[numeric, replacement(numeric, operator)]
|
|
121
|
+
[numeric, replacement(node, numeric, operator)]
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
def replacement(numeric, operation)
|
|
124
|
+
def replacement(node, numeric, operation)
|
|
125
125
|
if style == :predicate
|
|
126
126
|
[parenthesized_source(numeric), REPLACEMENTS.invert[operation.to_s]].join('.')
|
|
127
|
+
elsif negated?(node)
|
|
128
|
+
"(#{numeric.source} #{REPLACEMENTS[operation.to_s]} 0)"
|
|
127
129
|
else
|
|
128
130
|
[numeric.source, REPLACEMENTS[operation.to_s], 0].join(' ')
|
|
129
131
|
end
|
|
@@ -157,6 +159,12 @@ module RuboCop
|
|
|
157
159
|
end
|
|
158
160
|
end
|
|
159
161
|
|
|
162
|
+
def negated?(node)
|
|
163
|
+
return false unless (parent = node.parent)
|
|
164
|
+
|
|
165
|
+
parent.send_type? && parent.method?(:!)
|
|
166
|
+
end
|
|
167
|
+
|
|
160
168
|
# @!method predicate(node)
|
|
161
169
|
def_node_matcher :predicate, <<~PATTERN
|
|
162
170
|
(send $(...) ${:zero? :positive? :negative?})
|
|
@@ -46,15 +46,17 @@ module RuboCop
|
|
|
46
46
|
private
|
|
47
47
|
|
|
48
48
|
def check_method_node(node)
|
|
49
|
-
return unless preferred_method(node)
|
|
49
|
+
return unless preferred_method?(node)
|
|
50
50
|
|
|
51
51
|
message = message(node)
|
|
52
52
|
add_offense(node.loc.selector, message: message) do |corrector|
|
|
53
|
-
|
|
53
|
+
prefer = style == :then && node.receiver.nil? ? 'self.then' : style
|
|
54
|
+
|
|
55
|
+
corrector.replace(node.loc.selector, prefer)
|
|
54
56
|
end
|
|
55
57
|
end
|
|
56
58
|
|
|
57
|
-
def preferred_method(node)
|
|
59
|
+
def preferred_method?(node)
|
|
58
60
|
case style
|
|
59
61
|
when :then
|
|
60
62
|
node.method?(:yield_self)
|
|
@@ -4,8 +4,8 @@ module RuboCop
|
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
6
|
# Checks for redundant dot before operator method call.
|
|
7
|
-
# The target operator methods are `|`, `^`, `&`,
|
|
8
|
-
#
|
|
7
|
+
# The target operator methods are `|`, `^`, `&`, ``<=>``, `==`, `===`, `=~`, `>`, `>=`, `<`,
|
|
8
|
+
# ``<=``, `<<`, `>>`, `+`, `-`, `*`, `/`, `%`, `**`, `~`, `!`, `!=`, and `!~`.
|
|
9
9
|
#
|
|
10
10
|
# @example
|
|
11
11
|
#
|
|
@@ -142,8 +142,8 @@ module RuboCop
|
|
|
142
142
|
@assignments = assignments
|
|
143
143
|
end
|
|
144
144
|
|
|
145
|
-
def tsort_each_node(
|
|
146
|
-
@assignments.each(
|
|
145
|
+
def tsort_each_node(...)
|
|
146
|
+
@assignments.each(...)
|
|
147
147
|
end
|
|
148
148
|
|
|
149
149
|
def tsort_each_child(assignment)
|
|
@@ -289,9 +289,7 @@ module RuboCop
|
|
|
289
289
|
private
|
|
290
290
|
|
|
291
291
|
def modifier_range(node)
|
|
292
|
-
|
|
293
|
-
node.loc.keyword.begin_pos,
|
|
294
|
-
node.source_range.end_pos)
|
|
292
|
+
node.loc.keyword.join(node.source_range.end)
|
|
295
293
|
end
|
|
296
294
|
end
|
|
297
295
|
end
|
|
@@ -81,6 +81,7 @@ module RuboCop
|
|
|
81
81
|
cond = node.condition
|
|
82
82
|
|
|
83
83
|
control_op_condition(cond) do |first_child, rest_children|
|
|
84
|
+
return if require_parentheses?(node, first_child)
|
|
84
85
|
return if semicolon_separated_expressions?(first_child, rest_children)
|
|
85
86
|
return if modifier_op?(first_child)
|
|
86
87
|
return if parens_allowed?(cond)
|
|
@@ -92,6 +93,13 @@ module RuboCop
|
|
|
92
93
|
end
|
|
93
94
|
end
|
|
94
95
|
|
|
96
|
+
def require_parentheses?(node, condition_body)
|
|
97
|
+
return false if !node.while_type? && !node.until_type?
|
|
98
|
+
return false if !condition_body.block_type? && !condition_body.numblock_type?
|
|
99
|
+
|
|
100
|
+
condition_body.send_node.block_literal? && condition_body.keywords?
|
|
101
|
+
end
|
|
102
|
+
|
|
95
103
|
def semicolon_separated_expressions?(first_exp, rest_exps)
|
|
96
104
|
return false unless (second_exp = rest_exps.first)
|
|
97
105
|
|
|
@@ -9,7 +9,7 @@ module RuboCop
|
|
|
9
9
|
#
|
|
10
10
|
# String interpolation is always kept in double quotes.
|
|
11
11
|
#
|
|
12
|
-
#
|
|
12
|
+
# NOTE: `Lint/SymbolConversion` can be used in parallel to ensure that symbols
|
|
13
13
|
# are not quoted that don't need to be. This cop is for configuring the quoting
|
|
14
14
|
# style to use for symbols that require quotes.
|
|
15
15
|
#
|
|
@@ -16,6 +16,9 @@ module RuboCop
|
|
|
16
16
|
# The exploded style has an `AllowedCompactTypes` configuration
|
|
17
17
|
# option that takes an Array of exception name Strings.
|
|
18
18
|
#
|
|
19
|
+
# @safety
|
|
20
|
+
# This cop is unsafe because `raise Foo` calls `Foo.exception`, not `Foo.new`.
|
|
21
|
+
#
|
|
19
22
|
# @example EnforcedStyle: exploded (default)
|
|
20
23
|
# # bad
|
|
21
24
|
# raise StandardError.new('message')
|
|
@@ -77,7 +80,7 @@ module RuboCop
|
|
|
77
80
|
|
|
78
81
|
def correction_exploded_to_compact(node)
|
|
79
82
|
exception_node, *message_nodes = *node.arguments
|
|
80
|
-
return
|
|
83
|
+
return if message_nodes.size > 1
|
|
81
84
|
|
|
82
85
|
argument = message_nodes.first.source
|
|
83
86
|
exception_class = exception_node.receiver&.source || exception_node.source
|