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
|
@@ -35,7 +35,7 @@ module RuboCop
|
|
|
35
35
|
|
|
36
36
|
# @!method sample_candidate?(node)
|
|
37
37
|
def_node_matcher :sample_candidate?, <<~PATTERN
|
|
38
|
-
(
|
|
38
|
+
(call $(call _ :shuffle $...) ${:#{RESTRICT_ON_SEND.join(' :')}} $...)
|
|
39
39
|
PATTERN
|
|
40
40
|
|
|
41
41
|
def on_send(node)
|
|
@@ -52,6 +52,7 @@ module RuboCop
|
|
|
52
52
|
end
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
|
+
alias on_csend on_send
|
|
55
56
|
|
|
56
57
|
private
|
|
57
58
|
|
|
@@ -109,9 +110,7 @@ module RuboCop
|
|
|
109
110
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
110
111
|
|
|
111
112
|
def source_range(shuffle_node, node)
|
|
112
|
-
|
|
113
|
-
shuffle_node.loc.selector.begin_pos,
|
|
114
|
-
node.source_range.end_pos)
|
|
113
|
+
shuffle_node.loc.selector.join(node.source_range.end)
|
|
115
114
|
end
|
|
116
115
|
|
|
117
116
|
def message(shuffle_arg, method, method_args, range)
|
|
@@ -55,8 +55,8 @@ module RuboCop
|
|
|
55
55
|
# @!method regexp_match?(node)
|
|
56
56
|
def_node_matcher :regexp_match?, <<~PATTERN
|
|
57
57
|
{
|
|
58
|
-
(block
|
|
59
|
-
(numblock
|
|
58
|
+
(block call (args (arg $_)) ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
|
59
|
+
(numblock call $1 ${(send _ %REGEXP_METHODS _) match-with-lvasgn})
|
|
60
60
|
}
|
|
61
61
|
PATTERN
|
|
62
62
|
|
|
@@ -64,9 +64,9 @@ module RuboCop
|
|
|
64
64
|
# @!method creates_hash?(node)
|
|
65
65
|
def_node_matcher :creates_hash?, <<~PATTERN
|
|
66
66
|
{
|
|
67
|
-
(
|
|
68
|
-
(block (
|
|
69
|
-
(
|
|
67
|
+
(call (const _ :Hash) {:new :[]} ...)
|
|
68
|
+
(block (call (const _ :Hash) :new ...) ...)
|
|
69
|
+
(call _ { :to_h :to_hash } ...)
|
|
70
70
|
}
|
|
71
71
|
PATTERN
|
|
72
72
|
|
|
@@ -100,6 +100,7 @@ module RuboCop
|
|
|
100
100
|
register_offense(node, block_node, regexp, replacement)
|
|
101
101
|
end
|
|
102
102
|
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
103
|
+
alias on_csend on_send
|
|
103
104
|
|
|
104
105
|
private
|
|
105
106
|
|
|
@@ -146,7 +147,7 @@ module RuboCop
|
|
|
146
147
|
return node.child_nodes.first if node.match_with_lvasgn_type?
|
|
147
148
|
|
|
148
149
|
if node.receiver.lvar_type? &&
|
|
149
|
-
(block.numblock_type? || node.receiver.source == block.
|
|
150
|
+
(block.numblock_type? || node.receiver.source == block.first_argument.source)
|
|
150
151
|
node.first_argument
|
|
151
152
|
elsif node.first_argument.lvar_type?
|
|
152
153
|
node.receiver
|
|
@@ -80,6 +80,7 @@ module RuboCop
|
|
|
80
80
|
processed_source.tokens.group_by(&:line)
|
|
81
81
|
end
|
|
82
82
|
|
|
83
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
83
84
|
def semicolon_position(tokens)
|
|
84
85
|
if tokens.last.semicolon?
|
|
85
86
|
-1
|
|
@@ -90,10 +91,13 @@ module RuboCop
|
|
|
90
91
|
elsif exist_semicolon_after_left_curly_brace?(tokens) ||
|
|
91
92
|
exist_semicolon_after_left_string_interpolation_brace?(tokens)
|
|
92
93
|
2
|
|
94
|
+
elsif exist_semicolon_after_left_lambda_curly_brace?(tokens)
|
|
95
|
+
3
|
|
93
96
|
elsif exist_semicolon_before_right_string_interpolation_brace?(tokens)
|
|
94
97
|
-4
|
|
95
98
|
end
|
|
96
99
|
end
|
|
100
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
97
101
|
|
|
98
102
|
def exist_semicolon_before_right_curly_brace?(tokens)
|
|
99
103
|
tokens[-2]&.right_curly_brace? && tokens[-3]&.semicolon?
|
|
@@ -103,6 +107,10 @@ module RuboCop
|
|
|
103
107
|
tokens[1]&.left_curly_brace? && tokens[2]&.semicolon?
|
|
104
108
|
end
|
|
105
109
|
|
|
110
|
+
def exist_semicolon_after_left_lambda_curly_brace?(tokens)
|
|
111
|
+
tokens[2]&.type == :tLAMBEG && tokens[3]&.semicolon?
|
|
112
|
+
end
|
|
113
|
+
|
|
106
114
|
def exist_semicolon_before_right_string_interpolation_brace?(tokens)
|
|
107
115
|
tokens[-3]&.type == :tSTRING_DEND && tokens[-4]&.semicolon?
|
|
108
116
|
end
|
|
@@ -7,12 +7,12 @@ module RuboCop
|
|
|
7
7
|
#
|
|
8
8
|
# @example
|
|
9
9
|
# # bad
|
|
10
|
-
# Foo.send(
|
|
11
|
-
# quuz.send(
|
|
10
|
+
# Foo.send(bar)
|
|
11
|
+
# quuz.send(fred)
|
|
12
12
|
#
|
|
13
13
|
# # good
|
|
14
|
-
# Foo.__send__(
|
|
15
|
-
# quuz.public_send(
|
|
14
|
+
# Foo.__send__(bar)
|
|
15
|
+
# quuz.public_send(fred)
|
|
16
16
|
class Send < Base
|
|
17
17
|
MSG = 'Prefer `Object#__send__` or `Object#public_send` to `send`.'
|
|
18
18
|
RESTRICT_ON_SEND = %i[send].freeze
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Detects the use of the `public_send` method with a literal method name argument.
|
|
7
|
+
# Since the `send` method can be used to call private methods, by default,
|
|
8
|
+
# only the `public_send` method is detected.
|
|
9
|
+
#
|
|
10
|
+
# NOTE: Writer methods with names ending in `=` are always permitted because their
|
|
11
|
+
# behavior differs as follows:
|
|
12
|
+
#
|
|
13
|
+
# [source,ruby]
|
|
14
|
+
# ----
|
|
15
|
+
# def foo=(foo)
|
|
16
|
+
# @foo = foo
|
|
17
|
+
# 42
|
|
18
|
+
# end
|
|
19
|
+
#
|
|
20
|
+
# self.foo = 1 # => 1
|
|
21
|
+
# send(:foo=, 1) # => 42
|
|
22
|
+
# ----
|
|
23
|
+
#
|
|
24
|
+
# @safety
|
|
25
|
+
# This cop is not safe because it can incorrectly detect based on the receiver.
|
|
26
|
+
# Additionally, when `AllowSend` is set to `true`, it cannot determine whether
|
|
27
|
+
# the `send` method being detected is calling a private method.
|
|
28
|
+
#
|
|
29
|
+
# @example
|
|
30
|
+
# # bad
|
|
31
|
+
# obj.public_send(:method_name)
|
|
32
|
+
# obj.public_send('method_name')
|
|
33
|
+
#
|
|
34
|
+
# # good
|
|
35
|
+
# obj.method_name
|
|
36
|
+
#
|
|
37
|
+
# @example AllowSend: true (default)
|
|
38
|
+
# # good
|
|
39
|
+
# obj.send(:method_name)
|
|
40
|
+
# obj.send('method_name')
|
|
41
|
+
# obj.__send__(:method_name)
|
|
42
|
+
# obj.__send__('method_name')
|
|
43
|
+
#
|
|
44
|
+
# @example AllowSend: false
|
|
45
|
+
# # bad
|
|
46
|
+
# obj.send(:method_name)
|
|
47
|
+
# obj.send('method_name')
|
|
48
|
+
# obj.__send__(:method_name)
|
|
49
|
+
# obj.__send__('method_name')
|
|
50
|
+
#
|
|
51
|
+
# # good
|
|
52
|
+
# obj.method_name
|
|
53
|
+
#
|
|
54
|
+
class SendWithLiteralMethodName < Base
|
|
55
|
+
extend AutoCorrector
|
|
56
|
+
|
|
57
|
+
MSG = 'Use `%<method_name>s` method call directly instead.'
|
|
58
|
+
RESTRICT_ON_SEND = %i[public_send send __send__].freeze
|
|
59
|
+
STATIC_METHOD_NAME_NODE_TYPES = %i[sym str].freeze
|
|
60
|
+
METHOD_NAME_PATTERN = /\A[a-zA-Z_][a-zA-Z0-9_]*[!?]?\z/.freeze
|
|
61
|
+
RESERVED_WORDS = %i[
|
|
62
|
+
BEGIN END alias and begin break case class def defined? do else elsif end ensure
|
|
63
|
+
false for if in module next nil not or redo rescue retry return self super then true
|
|
64
|
+
undef unless until when while yield
|
|
65
|
+
].freeze
|
|
66
|
+
|
|
67
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
68
|
+
def on_send(node)
|
|
69
|
+
return if allow_send? && !node.method?(:public_send)
|
|
70
|
+
return unless (first_argument = node.first_argument)
|
|
71
|
+
return unless STATIC_METHOD_NAME_NODE_TYPES.include?(first_argument.type)
|
|
72
|
+
|
|
73
|
+
offense_range = offense_range(node)
|
|
74
|
+
method_name = first_argument.value
|
|
75
|
+
return if !METHOD_NAME_PATTERN.match?(method_name) || RESERVED_WORDS.include?(method_name)
|
|
76
|
+
|
|
77
|
+
add_offense(offense_range, message: format(MSG, method_name: method_name)) do |corrector|
|
|
78
|
+
if node.arguments.one?
|
|
79
|
+
corrector.replace(offense_range, method_name)
|
|
80
|
+
else
|
|
81
|
+
corrector.replace(node.loc.selector, method_name)
|
|
82
|
+
corrector.remove(removal_argument_range(first_argument, node.arguments[1]))
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
def allow_send?
|
|
91
|
+
!!cop_config['AllowSend']
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def offense_range(node)
|
|
95
|
+
node.loc.selector.join(node.source_range.end)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def removal_argument_range(first_argument, second_argument)
|
|
99
|
+
first_argument.source_range.begin.join(second_argument.source_range.begin)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Sometimes using dig method ends up with just a single
|
|
7
|
-
# argument. In such cases, dig should be replaced with []
|
|
6
|
+
# Sometimes using `dig` method ends up with just a single
|
|
7
|
+
# argument. In such cases, dig should be replaced with `[]`.
|
|
8
|
+
#
|
|
9
|
+
# Since replacing `hash&.dig(:key)` with `hash[:key]` could potentially lead to error,
|
|
10
|
+
# calls to the `dig` method using safe navigation will be ignored.
|
|
8
11
|
#
|
|
9
12
|
# @safety
|
|
10
13
|
# This cop is unsafe because it cannot be guaranteed that the receiver
|
|
@@ -33,6 +36,7 @@ module RuboCop
|
|
|
33
36
|
|
|
34
37
|
MSG = 'Use `%<receiver>s[%<argument>s]` instead of `%<original>s`.'
|
|
35
38
|
RESTRICT_ON_SEND = %i[dig].freeze
|
|
39
|
+
IGNORED_ARGUMENT_TYPES = %i[block_pass forwarded_restarg forwarded_args hash].freeze
|
|
36
40
|
|
|
37
41
|
# @!method single_argument_dig?(node)
|
|
38
42
|
def_node_matcher :single_argument_dig?, <<~PATTERN
|
|
@@ -44,7 +48,7 @@ module RuboCop
|
|
|
44
48
|
|
|
45
49
|
expression = single_argument_dig?(node)
|
|
46
50
|
return unless expression
|
|
47
|
-
return if expression.
|
|
51
|
+
return if IGNORED_ARGUMENT_TYPES.include?(expression.type)
|
|
48
52
|
|
|
49
53
|
receiver = node.receiver.source
|
|
50
54
|
argument = expression.source
|
|
@@ -30,6 +30,7 @@ module RuboCop
|
|
|
30
30
|
|
|
31
31
|
MSG = 'Prefer multiline `do`...`end` block.'
|
|
32
32
|
|
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
|
33
34
|
def on_block(node)
|
|
34
35
|
return if !node.single_line? || node.braces?
|
|
35
36
|
|
|
@@ -42,10 +43,11 @@ module RuboCop
|
|
|
42
43
|
corrector.remove(node.loc.end)
|
|
43
44
|
corrector.insert_after(node_body.loc.heredoc_end, "\nend")
|
|
44
45
|
else
|
|
45
|
-
corrector.
|
|
46
|
+
corrector.insert_before(node.loc.end, "\n")
|
|
46
47
|
end
|
|
47
48
|
end
|
|
48
49
|
end
|
|
50
|
+
# rubocop:enable Metrics/AbcSize
|
|
49
51
|
alias on_numblock on_block
|
|
50
52
|
|
|
51
53
|
private
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
module RuboCop
|
|
4
4
|
module Cop
|
|
5
5
|
module Style
|
|
6
|
-
# Checks that arrays are sliced with
|
|
7
|
-
# `ary[start..-1]` on Ruby 2.6
|
|
6
|
+
# Checks that arrays are not sliced with the redundant `ary[0..-1]`, replacing it with `ary`,
|
|
7
|
+
# and ensures arrays are sliced with endless ranges instead of `ary[start..-1]` on Ruby 2.6+,
|
|
8
|
+
# and with beginless ranges instead of `ary[nil..end]` on Ruby 2.7+.
|
|
8
9
|
#
|
|
9
10
|
# @safety
|
|
10
11
|
# This cop is unsafe because `x..-1` and `x..` are only guaranteed to
|
|
@@ -21,29 +22,94 @@ module RuboCop
|
|
|
21
22
|
#
|
|
22
23
|
# @example
|
|
23
24
|
# # bad
|
|
24
|
-
# items[
|
|
25
|
+
# items[0..-1]
|
|
26
|
+
# items[0..nil]
|
|
27
|
+
# items[0...nil]
|
|
25
28
|
#
|
|
26
29
|
# # good
|
|
27
|
-
# items
|
|
30
|
+
# items
|
|
31
|
+
#
|
|
32
|
+
# # bad
|
|
33
|
+
# items[1..-1] # Ruby 2.6+
|
|
34
|
+
# items[1..nil] # Ruby 2.6+
|
|
35
|
+
#
|
|
36
|
+
# # good
|
|
37
|
+
# items[1..] # Ruby 2.6+
|
|
38
|
+
#
|
|
39
|
+
# # bad
|
|
40
|
+
# items[nil..42] # Ruby 2.7+
|
|
41
|
+
#
|
|
42
|
+
# # good
|
|
43
|
+
# items[..42] # Ruby 2.7+
|
|
44
|
+
# items[0..42] # Ruby 2.7+
|
|
45
|
+
#
|
|
28
46
|
class SlicingWithRange < Base
|
|
29
47
|
extend AutoCorrector
|
|
30
48
|
extend TargetRubyVersion
|
|
31
49
|
|
|
32
50
|
minimum_target_ruby_version 2.6
|
|
33
51
|
|
|
34
|
-
MSG = 'Prefer
|
|
52
|
+
MSG = 'Prefer `%<prefer>s` over `%<current>s`.'
|
|
53
|
+
MSG_USELESS_RANGE = 'Remove the useless `%<prefer>s`.'
|
|
35
54
|
RESTRICT_ON_SEND = %i[[]].freeze
|
|
36
55
|
|
|
56
|
+
# @!method range_from_zero_till_minus_one?(node)
|
|
57
|
+
def_node_matcher :range_from_zero_till_minus_one?, <<~PATTERN
|
|
58
|
+
{
|
|
59
|
+
(irange (int 0) {(int -1) nil})
|
|
60
|
+
(erange (int 0) nil)
|
|
61
|
+
}
|
|
62
|
+
PATTERN
|
|
63
|
+
|
|
37
64
|
# @!method range_till_minus_one?(node)
|
|
38
|
-
def_node_matcher :range_till_minus_one?,
|
|
65
|
+
def_node_matcher :range_till_minus_one?, <<~PATTERN
|
|
66
|
+
{
|
|
67
|
+
(irange !nil? {(int -1) nil})
|
|
68
|
+
(erange !nil? nil)
|
|
69
|
+
}
|
|
70
|
+
PATTERN
|
|
71
|
+
|
|
72
|
+
# @!method range_from_zero?(node)
|
|
73
|
+
def_node_matcher :range_from_zero?, <<~PATTERN
|
|
74
|
+
(irange nil !nil?)
|
|
75
|
+
PATTERN
|
|
39
76
|
|
|
40
77
|
def on_send(node)
|
|
41
|
-
return unless node.arguments.
|
|
42
|
-
return unless range_till_minus_one?(node.arguments.first)
|
|
78
|
+
return unless node.arguments.one?
|
|
43
79
|
|
|
44
|
-
|
|
45
|
-
|
|
80
|
+
range_node = node.first_argument
|
|
81
|
+
selector = node.loc.selector
|
|
82
|
+
unless (message, removal_range = offense_message_with_removal_range(range_node, selector))
|
|
83
|
+
return
|
|
46
84
|
end
|
|
85
|
+
|
|
86
|
+
add_offense(selector, message: message) do |corrector|
|
|
87
|
+
corrector.remove(removal_range)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
def offense_message_with_removal_range(range_node, selector)
|
|
94
|
+
if range_from_zero_till_minus_one?(range_node)
|
|
95
|
+
[format(MSG_USELESS_RANGE, prefer: selector.source), selector]
|
|
96
|
+
elsif range_till_minus_one?(range_node)
|
|
97
|
+
[
|
|
98
|
+
format(MSG, prefer: endless(range_node), current: selector.source), range_node.end
|
|
99
|
+
]
|
|
100
|
+
elsif range_from_zero?(range_node) && target_ruby_version >= 2.7
|
|
101
|
+
[
|
|
102
|
+
format(MSG, prefer: beginless(range_node), current: selector.source), range_node.begin
|
|
103
|
+
]
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def endless(range_node)
|
|
108
|
+
"[#{range_node.begin.source}#{range_node.loc.operator.source}]"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def beginless(range_node)
|
|
112
|
+
"[#{range_node.loc.operator.source}#{range_node.end.source}]"
|
|
47
113
|
end
|
|
48
114
|
end
|
|
49
115
|
end
|
|
@@ -58,9 +58,8 @@ module RuboCop
|
|
|
58
58
|
#
|
|
59
59
|
# @example EnforcedStyle: use_builtin_english_names
|
|
60
60
|
#
|
|
61
|
-
# Like `use_perl_names` but allows builtin global vars.
|
|
62
|
-
#
|
|
63
61
|
# # good
|
|
62
|
+
# # Like `use_perl_names` but allows builtin global vars.
|
|
64
63
|
# puts $LOAD_PATH
|
|
65
64
|
# puts $LOADED_FEATURES
|
|
66
65
|
# puts $PROGRAM_NAME
|
|
@@ -22,20 +22,23 @@ module RuboCop
|
|
|
22
22
|
|
|
23
23
|
# @!method lstrip_rstrip(node)
|
|
24
24
|
def_node_matcher :lstrip_rstrip, <<~PATTERN
|
|
25
|
-
{
|
|
26
|
-
|
|
25
|
+
{
|
|
26
|
+
(call $(call _ :rstrip) :lstrip)
|
|
27
|
+
(call $(call _ :lstrip) :rstrip)
|
|
28
|
+
}
|
|
27
29
|
PATTERN
|
|
28
30
|
|
|
29
31
|
def on_send(node)
|
|
30
|
-
lstrip_rstrip(node) do |first_send
|
|
32
|
+
lstrip_rstrip(node) do |first_send|
|
|
31
33
|
range = range_between(first_send.loc.selector.begin_pos, node.source_range.end_pos)
|
|
32
|
-
message = format(MSG, methods:
|
|
34
|
+
message = format(MSG, methods: range.source)
|
|
33
35
|
|
|
34
36
|
add_offense(range, message: message) do |corrector|
|
|
35
37
|
corrector.replace(range, 'strip')
|
|
36
38
|
end
|
|
37
39
|
end
|
|
38
40
|
end
|
|
41
|
+
alias on_csend on_send
|
|
39
42
|
end
|
|
40
43
|
end
|
|
41
44
|
end
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Checks for redundant argument forwarding when calling super with arguments identical to
|
|
7
|
+
# the method definition.
|
|
8
|
+
#
|
|
9
|
+
# Using zero arity `super` within a `define_method` block results in `RuntimeError`:
|
|
10
|
+
#
|
|
11
|
+
# [source,ruby]
|
|
12
|
+
# ----
|
|
13
|
+
# def m
|
|
14
|
+
# define_method(:foo) { super() } # => OK
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# def m
|
|
18
|
+
# define_method(:foo) { super } # => RuntimeError
|
|
19
|
+
# end
|
|
20
|
+
# ----
|
|
21
|
+
#
|
|
22
|
+
# Furthermore, any arguments accompanied by a block may potentially be delegating to
|
|
23
|
+
# `define_method`, therefore, `super` used within these blocks will be allowed.
|
|
24
|
+
# This approach might result in false negatives, yet ensuring safe detection takes precedence.
|
|
25
|
+
#
|
|
26
|
+
# @example
|
|
27
|
+
# # bad
|
|
28
|
+
# def method(*args, **kwargs)
|
|
29
|
+
# super(*args, **kwargs)
|
|
30
|
+
# end
|
|
31
|
+
#
|
|
32
|
+
# # good - implicitly passing all arguments
|
|
33
|
+
# def method(*args, **kwargs)
|
|
34
|
+
# super
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# # good - forwarding a subset of the arguments
|
|
38
|
+
# def method(*args, **kwargs)
|
|
39
|
+
# super(*args)
|
|
40
|
+
# end
|
|
41
|
+
#
|
|
42
|
+
# # good - forwarding no arguments
|
|
43
|
+
# def method(*args, **kwargs)
|
|
44
|
+
# super()
|
|
45
|
+
# end
|
|
46
|
+
#
|
|
47
|
+
# # good - assigning to the block variable before calling super
|
|
48
|
+
# def method(&block)
|
|
49
|
+
# # Assigning to the block variable would pass the old value to super,
|
|
50
|
+
# # under this circumstance the block must be referenced explicitly.
|
|
51
|
+
# block ||= proc { 'fallback behavior' }
|
|
52
|
+
# super(&block)
|
|
53
|
+
# end
|
|
54
|
+
class SuperArguments < Base
|
|
55
|
+
extend AutoCorrector
|
|
56
|
+
|
|
57
|
+
DEF_TYPES = %i[def defs].freeze
|
|
58
|
+
ASSIGN_TYPES = %i[or_asgn lvasgn].freeze
|
|
59
|
+
|
|
60
|
+
MSG = 'Call `super` without arguments and parentheses when the signature is identical.'
|
|
61
|
+
|
|
62
|
+
def on_super(super_node)
|
|
63
|
+
def_node = super_node.ancestors.find do |node|
|
|
64
|
+
# When defining dynamic methods, implicitly calling `super` is not possible.
|
|
65
|
+
# Since there is a possibility of delegation to `define_method`,
|
|
66
|
+
# `super` used within the block is always allowed.
|
|
67
|
+
break if node.block_type?
|
|
68
|
+
|
|
69
|
+
break node if DEF_TYPES.include?(node.type)
|
|
70
|
+
end
|
|
71
|
+
return unless def_node
|
|
72
|
+
return unless arguments_identical?(def_node, def_node.arguments.argument_list,
|
|
73
|
+
super_node.arguments)
|
|
74
|
+
|
|
75
|
+
add_offense(super_node) { |corrector| corrector.replace(super_node, 'super') }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
81
|
+
def arguments_identical?(def_node, def_args, super_args)
|
|
82
|
+
super_args = preprocess_super_args(super_args)
|
|
83
|
+
return false if def_args.size != super_args.size
|
|
84
|
+
|
|
85
|
+
def_args.zip(super_args).each do |def_arg, super_arg|
|
|
86
|
+
next if positional_arg_same?(def_arg, super_arg)
|
|
87
|
+
next if positional_rest_arg_same(def_arg, super_arg)
|
|
88
|
+
next if keyword_arg_same?(def_arg, super_arg)
|
|
89
|
+
next if keyword_rest_arg_same?(def_arg, super_arg)
|
|
90
|
+
next if block_arg_same?(def_node, def_arg, super_arg)
|
|
91
|
+
next if forward_arg_same?(def_arg, super_arg)
|
|
92
|
+
|
|
93
|
+
return false
|
|
94
|
+
end
|
|
95
|
+
true
|
|
96
|
+
end
|
|
97
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
98
|
+
|
|
99
|
+
def positional_arg_same?(def_arg, super_arg)
|
|
100
|
+
return false unless def_arg.arg_type? || def_arg.optarg_type?
|
|
101
|
+
return false unless super_arg.lvar_type?
|
|
102
|
+
|
|
103
|
+
def_arg.name == super_arg.children.first
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def positional_rest_arg_same(def_arg, super_arg)
|
|
107
|
+
return false unless def_arg.restarg_type?
|
|
108
|
+
# anonymous forwarding
|
|
109
|
+
return true if def_arg.name.nil? && super_arg.forwarded_restarg_type?
|
|
110
|
+
return false unless super_arg.splat_type?
|
|
111
|
+
return false unless (lvar_node = super_arg.children.first).lvar_type?
|
|
112
|
+
|
|
113
|
+
def_arg.name == lvar_node.children.first
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def keyword_arg_same?(def_arg, super_arg)
|
|
117
|
+
return false unless def_arg.kwarg_type? || def_arg.kwoptarg_type?
|
|
118
|
+
return false unless (pair_node = super_arg).pair_type?
|
|
119
|
+
return false unless (sym_node = pair_node.key).sym_type?
|
|
120
|
+
return false unless (lvar_node = pair_node.value).lvar_type?
|
|
121
|
+
return false unless sym_node.source == lvar_node.source
|
|
122
|
+
|
|
123
|
+
def_arg.name == sym_node.value
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def keyword_rest_arg_same?(def_arg, super_arg)
|
|
127
|
+
return false unless def_arg.kwrestarg_type?
|
|
128
|
+
# anonymous forwarding
|
|
129
|
+
return true if def_arg.name.nil? && super_arg.forwarded_kwrestarg_type?
|
|
130
|
+
return false unless super_arg.kwsplat_type?
|
|
131
|
+
return false unless (lvar_node = super_arg.children.first).lvar_type?
|
|
132
|
+
|
|
133
|
+
def_arg.name == lvar_node.children.first
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def block_arg_same?(def_node, def_arg, super_arg)
|
|
137
|
+
return false unless def_arg.blockarg_type? && super_arg.block_pass_type?
|
|
138
|
+
# anonymous forwarding
|
|
139
|
+
return true if (block_pass_child = super_arg.children.first).nil? && def_arg.name.nil?
|
|
140
|
+
|
|
141
|
+
block_arg_name = block_pass_child.children.first
|
|
142
|
+
def_arg.name == block_arg_name && !block_reassigned?(def_node, block_arg_name)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Reassigning the block argument will still pass along the original block to super
|
|
146
|
+
# https://bugs.ruby-lang.org/issues/20505
|
|
147
|
+
def block_reassigned?(def_node, block_arg_name)
|
|
148
|
+
def_node.each_node(*ASSIGN_TYPES).any? do |assign_node|
|
|
149
|
+
# TODO: Since `Symbol#name` is supported from Ruby 3.0, the inheritance check for
|
|
150
|
+
# `AST::Node` can be removed when requiring Ruby 3.0+.
|
|
151
|
+
lhs = assign_node.node_parts[0]
|
|
152
|
+
next if lhs.is_a?(AST::Node) && !lhs.respond_to?(:name)
|
|
153
|
+
|
|
154
|
+
assign_node.name == block_arg_name
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def forward_arg_same?(def_arg, super_arg)
|
|
159
|
+
def_arg.forward_arg_type? && super_arg.forwarded_args_type?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def preprocess_super_args(super_args)
|
|
163
|
+
super_args.flat_map do |node|
|
|
164
|
+
if node.hash_type? && !node.braces?
|
|
165
|
+
node.children
|
|
166
|
+
else
|
|
167
|
+
node
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Style
|
|
6
|
+
# Enforces the presence of parentheses in `super` containing arguments.
|
|
7
|
+
#
|
|
8
|
+
# `super` is a keyword and is provided as a distinct cop from those designed for method call.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
#
|
|
12
|
+
# # bad
|
|
13
|
+
# super name, age
|
|
14
|
+
#
|
|
15
|
+
# # good
|
|
16
|
+
# super(name, age)
|
|
17
|
+
#
|
|
18
|
+
class SuperWithArgsParentheses < Base
|
|
19
|
+
extend AutoCorrector
|
|
20
|
+
|
|
21
|
+
MSG = 'Use parentheses for `super` with arguments.'
|
|
22
|
+
|
|
23
|
+
def on_super(node)
|
|
24
|
+
return if node.parenthesized?
|
|
25
|
+
|
|
26
|
+
add_offense(node) do |corrector|
|
|
27
|
+
range = node.loc.keyword.end.join(node.first_argument.source_range.begin)
|
|
28
|
+
corrector.replace(range, '(')
|
|
29
|
+
corrector.insert_after(node.last_argument, ')')
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|