rubocop 1.90.0 → 1.92.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/README.md +1 -1
- data/config/default.yml +241 -11
- data/config/obsoletion.yml +9 -0
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +134 -0
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +23 -3
- data/lib/rubocop/cli/command/explain.rb +34 -0
- data/lib/rubocop/cli/command/show_cops.rb +6 -0
- data/lib/rubocop/cli/command/show_docs_url.rb +6 -4
- data/lib/rubocop/cli.rb +11 -4
- data/lib/rubocop/comment_config/directive_range.rb +3 -1
- data/lib/rubocop/comment_config/disable_next.rb +49 -3
- data/lib/rubocop/comment_config/push_pop.rb +55 -0
- data/lib/rubocop/comment_config.rb +32 -53
- data/lib/rubocop/config.rb +10 -0
- data/lib/rubocop/config_loader.rb +18 -7
- data/lib/rubocop/config_loader_resolver.rb +79 -12
- data/lib/rubocop/config_obsoletion/cop_rule.rb +2 -1
- data/lib/rubocop/config_obsoletion/removed_cop.rb +9 -1
- data/lib/rubocop/config_obsoletion.rb +1 -1
- data/lib/rubocop/config_validator.rb +29 -3
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +57 -24
- data/lib/rubocop/cop/bundler/gem_comment.rb +0 -1
- data/lib/rubocop/cop/bundler/ordered_gems.rb +0 -8
- data/lib/rubocop/cop/cop_documentation.rb +81 -0
- data/lib/rubocop/cop/cop_explanation.rb +140 -0
- data/lib/rubocop/cop/correctors/alignment_corrector.rb +13 -1
- data/lib/rubocop/cop/correctors/each_to_for_corrector.rb +22 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +23 -2
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- data/lib/rubocop/cop/correctors.rb +2 -2
- data/lib/rubocop/cop/documentation.rb +1 -1
- data/lib/rubocop/cop/gemspec/dependency_version.rb +0 -6
- data/lib/rubocop/cop/gemspec/ordered_dependencies.rb +0 -6
- data/lib/rubocop/cop/gemspec/require_mfa.rb +1 -1
- data/lib/rubocop/cop/generator.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/node_matcher_directive.rb +2 -5
- data/lib/rubocop/cop/internal_affairs/node_type_group.rb +0 -7
- data/lib/rubocop/cop/internal_affairs/on_send_without_on_csend.rb +1 -1
- data/lib/rubocop/cop/internal_affairs/redundant_context_config_parameter.rb +1 -7
- data/lib/rubocop/cop/internal_affairs/style_detected_api_use.rb +1 -7
- data/lib/rubocop/cop/layout/argument_alignment.rb +2 -0
- data/lib/rubocop/cop/layout/block_alignment.rb +27 -0
- data/lib/rubocop/cop/layout/case_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/class_structure.rb +9 -1
- data/lib/rubocop/cop/layout/comment_indentation.rb +8 -5
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/else_alignment.rb +1 -0
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +14 -5
- data/lib/rubocop/cop/layout/empty_lines.rb +5 -2
- data/lib/rubocop/cop/layout/empty_lines_after_module_inclusion.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_attribute_accessor.rb +1 -0
- data/lib/rubocop/cop/layout/empty_lines_around_block_body.rb +1 -1
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +16 -10
- data/lib/rubocop/cop/layout/extra_spacing.rb +4 -0
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +1 -0
- data/lib/rubocop/cop/layout/first_array_element_indentation.rb +17 -4
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +5 -3
- data/lib/rubocop/cop/layout/first_method_argument_line_break.rb +6 -0
- data/lib/rubocop/cop/layout/first_method_parameter_line_break.rb +4 -0
- data/lib/rubocop/cop/layout/first_parameter_indentation.rb +11 -0
- data/lib/rubocop/cop/layout/hash_alignment.rb +15 -10
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +2 -0
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +4 -4
- data/lib/rubocop/cop/layout/line_continuation_spacing.rb +8 -1
- data/lib/rubocop/cop/layout/line_end_string_concatenation_indentation.rb +25 -9
- data/lib/rubocop/cop/layout/line_length.rb +71 -19
- data/lib/rubocop/cop/layout/multiline_array_brace_layout.rb +12 -0
- data/lib/rubocop/cop/layout/multiline_block_layout.rb +8 -1
- data/lib/rubocop/cop/layout/multiline_hash_brace_layout.rb +7 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +14 -0
- data/lib/rubocop/cop/layout/multiline_method_definition_brace_layout.rb +4 -0
- data/lib/rubocop/cop/layout/redundant_line_break.rb +22 -1
- data/lib/rubocop/cop/layout/rescue_ensure_alignment.rb +15 -2
- data/lib/rubocop/cop/layout/single_line_block_chain.rb +10 -2
- data/lib/rubocop/cop/layout/space_after_not.rb +5 -0
- data/lib/rubocop/cop/layout/space_around_block_parameters.rb +10 -4
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +5 -1
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +4 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +31 -8
- data/lib/rubocop/cop/lint/ambiguous_operator.rb +1 -1
- data/lib/rubocop/cop/lint/ambiguous_operator_precedence.rb +2 -1
- data/lib/rubocop/cop/lint/argument_mismatch.rb +14 -4
- data/lib/rubocop/cop/lint/assignment_in_condition.rb +2 -0
- data/lib/rubocop/cop/lint/cop_directive_syntax.rb +88 -14
- data/lib/rubocop/cop/lint/duplicate_methods.rb +1 -1
- data/lib/rubocop/cop/lint/empty_block.rb +1 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/literal_as_condition.rb +23 -2
- data/lib/rubocop/cop/lint/literal_in_interpolation.rb +63 -19
- data/lib/rubocop/cop/lint/loop.rb +24 -2
- data/lib/rubocop/cop/lint/misplaced_magic_comment.rb +245 -0
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +19 -4
- data/lib/rubocop/cop/lint/nested_method_definition.rb +1 -1
- data/lib/rubocop/cop/lint/non_deterministic_require_order.rb +1 -1
- data/lib/rubocop/cop/lint/number_conversion.rb +1 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +17 -1
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +42 -17
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/unescaped_bracket_in_regexp.rb +18 -1
- data/lib/rubocop/cop/lint/useless_assignment.rb +14 -7
- data/lib/rubocop/cop/lint/void.rb +8 -1
- data/lib/rubocop/cop/lint.rb +1 -0
- data/lib/rubocop/cop/metrics/class_length.rb +4 -2
- data/lib/rubocop/cop/metrics/cyclomatic_complexity.rb +0 -4
- data/lib/rubocop/cop/metrics/module_length.rb +4 -2
- data/lib/rubocop/cop/migration/department_name.rb +1 -1
- data/lib/rubocop/cop/mixin/alignment.rb +5 -1
- data/lib/rubocop/cop/mixin/annotation_comment.rb +1 -1
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +17 -14
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +5 -1
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +69 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +26 -2
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +31 -3
- data/lib/rubocop/cop/mixin/hash_transform_method.rb +1 -1
- data/lib/rubocop/cop/mixin/min_branches_count.rb +3 -1
- data/lib/rubocop/cop/mixin/multiline_element_line_breaks.rb +11 -1
- data/lib/rubocop/cop/mixin/multiline_literal_brace_layout.rb +9 -0
- data/lib/rubocop/cop/mixin/ordered_gem_node.rb +1 -1
- data/lib/rubocop/cop/mixin/pattern_matching_help.rb +35 -0
- data/lib/rubocop/cop/mixin/preceding_following_alignment.rb +29 -3
- data/lib/rubocop/cop/mixin/project_index_help.rb +15 -0
- data/lib/rubocop/cop/mixin/reparsed_equivalence.rb +13 -3
- data/lib/rubocop/cop/mixin/statement_modifier.rb +22 -2
- data/lib/rubocop/cop/mixin.rb +4 -2
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.rb +4 -1
- data/lib/rubocop/cop/naming/block_parameter_name.rb +1 -1
- data/lib/rubocop/cop/naming/heredoc_delimiter_case.rb +9 -2
- data/lib/rubocop/cop/naming/heredoc_delimiter_naming.rb +5 -3
- data/lib/rubocop/cop/naming/predicate_prefix.rb +7 -22
- data/lib/rubocop/cop/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +10 -2
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/severity.rb +12 -0
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +10 -2
- data/lib/rubocop/cop/style/alias.rb +18 -5
- data/lib/rubocop/cop/style/ambiguous_endless_method_definition.rb +4 -3
- data/lib/rubocop/cop/style/and_or.rb +4 -0
- data/lib/rubocop/cop/style/arguments_forwarding.rb +6 -3
- data/lib/rubocop/cop/style/attr.rb +3 -4
- data/lib/rubocop/cop/style/bitwise_predicate.rb +6 -4
- data/lib/rubocop/cop/style/block_delimiters.rb +29 -3
- data/lib/rubocop/cop/style/case_like_if.rb +9 -6
- data/lib/rubocop/cop/style/class_and_module_children.rb +54 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +8 -0
- data/lib/rubocop/cop/style/combinable_loops.rb +85 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +46 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/constant_visibility.rb +6 -2
- data/lib/rubocop/cop/style/data_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/directive_scope.rb +154 -21
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +118 -18
- data/lib/rubocop/cop/style/documentation_method.rb +1 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/each_for_simple_loop.rb +1 -1
- data/lib/rubocop/cop/style/empty_block_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_lambda_parameter.rb +1 -1
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +15 -3
- data/lib/rubocop/cop/style/endless_method.rb +91 -11
- data/lib/rubocop/cop/style/exact_regexp_match.rb +45 -8
- data/lib/rubocop/cop/style/explicit_block_argument.rb +50 -10
- data/lib/rubocop/cop/style/file_null.rb +2 -2
- data/lib/rubocop/cop/style/float_division.rb +28 -14
- data/lib/rubocop/cop/style/for.rb +44 -1
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/format_string_token.rb +1 -1
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +13 -1
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +35 -9
- data/lib/rubocop/cop/style/hash_syntax.rb +16 -3
- data/lib/rubocop/cop/style/identical_conditional_branches.rb +22 -3
- data/lib/rubocop/cop/style/if_inside_else.rb +21 -1
- data/lib/rubocop/cop/style/if_unless_modifier.rb +19 -20
- data/lib/rubocop/cop/style/if_unless_modifier_of_if_unless.rb +4 -0
- data/lib/rubocop/cop/style/if_with_semicolon.rb +47 -4
- data/lib/rubocop/cop/style/inverse_methods.rb +24 -2
- data/lib/rubocop/cop/style/it_block_parameter.rb +32 -3
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +18 -0
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/magic_comment_format.rb +1 -1
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +45 -10
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +25 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +29 -3
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/multiline_if_modifier.rb +45 -5
- data/lib/rubocop/cop/style/multiline_in_pattern_then.rb +7 -0
- data/lib/rubocop/cop/style/multiline_method_signature.rb +2 -5
- data/lib/rubocop/cop/style/multiline_ternary_operator.rb +7 -3
- data/lib/rubocop/cop/style/multiline_when_then.rb +7 -0
- data/lib/rubocop/cop/style/mutable_constant.rb +28 -1
- data/lib/rubocop/cop/style/negated_if_else_condition.rb +2 -1
- data/lib/rubocop/cop/style/negative_array_index.rb +9 -1
- data/lib/rubocop/cop/style/nested_modifier.rb +36 -12
- data/lib/rubocop/cop/style/nested_ternary_operator.rb +26 -8
- data/lib/rubocop/cop/style/next.rb +24 -10
- data/lib/rubocop/cop/style/nil_comparison.rb +48 -8
- data/lib/rubocop/cop/style/nil_lambda.rb +1 -1
- data/lib/rubocop/cop/style/non_nil_check.rb +18 -2
- data/lib/rubocop/cop/style/not.rb +10 -3
- data/lib/rubocop/cop/style/numeric_literal_prefix.rb +11 -1
- data/lib/rubocop/cop/style/numeric_predicate.rb +21 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +14 -3
- data/lib/rubocop/cop/style/parallel_assignment.rb +1 -1
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +6 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/reduce_to_hash.rb +17 -1
- data/lib/rubocop/cop/style/redundant_begin.rb +20 -3
- data/lib/rubocop/cop/style/redundant_condition.rb +34 -17
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +16 -1
- data/lib/rubocop/cop/style/redundant_exception.rb +15 -3
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +10 -2
- data/lib/rubocop/cop/style/redundant_freeze.rb +10 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +23 -2
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_character_class.rb +6 -5
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +25 -5
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +9 -0
- data/lib/rubocop/cop/style/rescue_modifier.rb +5 -9
- data/lib/rubocop/cop/style/return_nil.rb +17 -2
- data/lib/rubocop/cop/style/return_nil_in_predicate_method_definition.rb +11 -1
- data/lib/rubocop/cop/style/sample.rb +9 -8
- data/lib/rubocop/cop/style/self_assignment.rb +12 -15
- data/lib/rubocop/cop/style/semicolon.rb +16 -5
- data/lib/rubocop/cop/style/single_line_block_params.rb +1 -1
- data/lib/rubocop/cop/style/single_line_methods.rb +16 -4
- data/lib/rubocop/cop/style/special_global_vars.rb +1 -1
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +9 -3
- data/lib/rubocop/cop/style/struct_inheritance.rb +14 -0
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +23 -5
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -1
- data/lib/rubocop/cop/style/trailing_comma_in_block_args.rb +1 -1
- data/lib/rubocop/cop/style/trailing_underscore_variable.rb +23 -19
- data/lib/rubocop/cop/style/while_until_modifier.rb +1 -1
- data/lib/rubocop/cop/style/yoda_condition.rb +24 -9
- data/lib/rubocop/cop/style/yoda_expression.rb +10 -1
- data/lib/rubocop/cop/style.rb +0 -1
- data/lib/rubocop/cop/team.rb +10 -5
- data/lib/rubocop/cop/util.rb +1 -1
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/cops_documentation_generator.rb +23 -2
- data/lib/rubocop/directive_comment.rb +37 -8
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/disabled_config_formatter.rb +19 -1
- data/lib/rubocop/formatter/formatter_set.rb +6 -1
- data/lib/rubocop/formatter/github_actions_formatter.rb +6 -5
- data/lib/rubocop/formatter/html_formatter.rb +2 -2
- data/lib/rubocop/formatter/json_formatter.rb +71 -1
- data/lib/rubocop/formatter/junit_formatter.rb +1 -1
- data/lib/rubocop/formatter/offense_count_formatter.rb +3 -1
- data/lib/rubocop/formatter/pacman_formatter.rb +3 -1
- data/lib/rubocop/formatter/sarif_formatter.rb +186 -0
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/formatter.rb +1 -0
- data/lib/rubocop/lsp/runtime.rb +47 -11
- data/lib/rubocop/lsp/stdin_runner.rb +11 -5
- data/lib/rubocop/lsp.rb +5 -2
- data/lib/rubocop/magic_comment.rb +27 -0
- data/lib/rubocop/mcp/autocorrection_request.rb +52 -0
- data/lib/rubocop/mcp/explain_tool.rb +68 -0
- data/lib/rubocop/mcp/scope.rb +65 -0
- data/lib/rubocop/mcp/server.rb +184 -76
- data/lib/rubocop/mcp/source_files.rb +35 -0
- data/lib/rubocop/offense_limit.rb +30 -0
- data/lib/rubocop/options.rb +97 -4
- data/lib/rubocop/path_util.rb +1 -1
- data/lib/rubocop/plugin/configuration_integrator.rb +12 -5
- data/lib/rubocop/plugin/loader.rb +1 -1
- data/lib/rubocop/rake_task.rb +1 -1
- data/lib/rubocop/remote_config.rb +8 -5
- data/lib/rubocop/result_cache.rb +36 -18
- data/lib/rubocop/runner.rb +160 -49
- data/lib/rubocop/server/cache.rb +2 -2
- data/lib/rubocop/unified_diff.rb +257 -0
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +9 -1
- metadata +21 -6
- data/lib/rubocop/cop/style/double_cop_disable_directive.rb +0 -46
|
@@ -49,7 +49,7 @@ module RuboCop
|
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
def replaced_exploded(node, command, message)
|
|
52
|
-
arg =
|
|
52
|
+
arg = message_source(message)
|
|
53
53
|
arg = node.parenthesized? ? "(#{arg})" : " #{arg}"
|
|
54
54
|
"#{command}#{arg}"
|
|
55
55
|
end
|
|
@@ -63,19 +63,31 @@ module RuboCop
|
|
|
63
63
|
next if message.nil_type?
|
|
64
64
|
|
|
65
65
|
add_offense(node, message: MSG_2) do |corrector|
|
|
66
|
-
corrector.replace(new_call,
|
|
66
|
+
corrector.replace(new_call, message_source(message))
|
|
67
67
|
end
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
-
def
|
|
71
|
+
def message_source(message)
|
|
72
72
|
if string_message?(message)
|
|
73
73
|
message.source
|
|
74
|
+
elsif require_parentheses?(message)
|
|
75
|
+
"(#{message.source}).to_s"
|
|
74
76
|
else
|
|
75
77
|
"#{message.source}.to_s"
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
|
|
81
|
+
def require_parentheses?(message)
|
|
82
|
+
if message.call_type?
|
|
83
|
+
!message.method?(:[]) &&
|
|
84
|
+
(message.operator_method? || (message.arguments? && !message.parenthesized?))
|
|
85
|
+
else
|
|
86
|
+
!(message.basic_literal? || message.variable? ||
|
|
87
|
+
message.type?(:const, :self, :begin, :array))
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
79
91
|
# @!method exploded?(node)
|
|
80
92
|
def_node_matcher :exploded?, <<~PATTERN
|
|
81
93
|
(send nil? ${:raise :fail} (const {nil? cbase} :RuntimeError) $_)
|
|
@@ -52,7 +52,7 @@ module RuboCop
|
|
|
52
52
|
${nil? basic_literal? const_type?})
|
|
53
53
|
PATTERN
|
|
54
54
|
|
|
55
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
55
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- the matched body is a literal or a constant
|
|
56
56
|
redundant_fetch_block_candidate?(node) do |send, body|
|
|
57
57
|
return if should_not_check?(send, body)
|
|
58
58
|
|
|
@@ -74,7 +74,8 @@ module RuboCop
|
|
|
74
74
|
def should_not_check?(send, body)
|
|
75
75
|
(body&.const_type? && !check_for_constant?) ||
|
|
76
76
|
(body&.str_type? && !check_for_string?) ||
|
|
77
|
-
rails_cache?(send.receiver)
|
|
77
|
+
rails_cache?(send.receiver) ||
|
|
78
|
+
unappendable_argument?(send)
|
|
78
79
|
end
|
|
79
80
|
|
|
80
81
|
# @!method rails_cache?(node)
|
|
@@ -107,6 +108,13 @@ module RuboCop
|
|
|
107
108
|
def check_for_string?
|
|
108
109
|
frozen_string_literals_enabled?
|
|
109
110
|
end
|
|
111
|
+
|
|
112
|
+
def unappendable_argument?(send)
|
|
113
|
+
argument = send.first_argument
|
|
114
|
+
|
|
115
|
+
argument.type?(:splat, :forwarded_restarg) ||
|
|
116
|
+
(argument.hash_type? && !argument.braces?)
|
|
117
|
+
end
|
|
110
118
|
end
|
|
111
119
|
end
|
|
112
120
|
end
|
|
@@ -57,12 +57,21 @@ module RuboCop
|
|
|
57
57
|
def_node_matcher :operation_produces_immutable_object?, <<~PATTERN
|
|
58
58
|
{
|
|
59
59
|
(begin (send {float int} {:+ :- :* :** :/ :% :<<} _))
|
|
60
|
-
(begin (send
|
|
60
|
+
(begin (send #numeric_operation? {:+ :- :* :** :/ :%} {float int}))
|
|
61
61
|
(begin (send _ {:== :=== :!= :<= :>= :< :>} _))
|
|
62
62
|
(send _ {:count :length :size} ...)
|
|
63
63
|
(any_block (send _ {:count :length :size} ...) ...)
|
|
64
64
|
}
|
|
65
65
|
PATTERN
|
|
66
|
+
|
|
67
|
+
# @!method numeric_operation?(node)
|
|
68
|
+
def_node_matcher :numeric_operation?, <<~PATTERN
|
|
69
|
+
{
|
|
70
|
+
float int
|
|
71
|
+
(begin #numeric_operation?)
|
|
72
|
+
(send #numeric_operation? {:+ :- :* :** :/ :%} #numeric_operation?)
|
|
73
|
+
}
|
|
74
|
+
PATTERN
|
|
66
75
|
end
|
|
67
76
|
end
|
|
68
77
|
end
|
|
@@ -66,7 +66,8 @@ module RuboCop
|
|
|
66
66
|
rescue?(node) ||
|
|
67
67
|
in_pattern_matching_in_method_argument?(node) ||
|
|
68
68
|
allowed_pin_operator?(node) ||
|
|
69
|
-
allowed_expression?(node)
|
|
69
|
+
allowed_expression?(node) ||
|
|
70
|
+
ParenthesesCorrector.heredoc_strands_code_after_close_paren?(node)
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
def ignore_syntax?(node)
|
|
@@ -170,7 +171,10 @@ module RuboCop
|
|
|
170
171
|
return 'a one-line pattern matching'
|
|
171
172
|
end
|
|
172
173
|
return 'an interpolated expression' if interpolation?(begin_node)
|
|
173
|
-
|
|
174
|
+
if argument_of_parenthesized_method_call?(begin_node, node) &&
|
|
175
|
+
!keyword_logical_operator?(node)
|
|
176
|
+
return 'a method argument'
|
|
177
|
+
end
|
|
174
178
|
return 'a one-line rescue' if oneline_rescue_parentheses_required?(begin_node, node)
|
|
175
179
|
|
|
176
180
|
return if begin_node.chained?
|
|
@@ -229,12 +233,22 @@ module RuboCop
|
|
|
229
233
|
node = node.send_node if node.any_block_type?
|
|
230
234
|
|
|
231
235
|
return check_unary(begin_node, node) if node.unary_operation?
|
|
236
|
+
return if setter_in_condition?(begin_node, node)
|
|
232
237
|
|
|
233
238
|
return unless method_call_with_redundant_parentheses?(begin_node, node)
|
|
234
239
|
|
|
235
240
|
offense(begin_node, 'a method call')
|
|
236
241
|
end
|
|
237
242
|
|
|
243
|
+
# Like a variable assignment, `if (foo.bar = baz)` is a safe assignment
|
|
244
|
+
# that `Lint/AssignmentInCondition` asks for, not redundant parentheses.
|
|
245
|
+
def setter_in_condition?(begin_node, node)
|
|
246
|
+
return false unless node.setter_method?
|
|
247
|
+
return false unless (parent = begin_node.parent)&.basic_conditional?
|
|
248
|
+
|
|
249
|
+
parent.condition.equal?(begin_node)
|
|
250
|
+
end
|
|
251
|
+
|
|
238
252
|
def check_unary(begin_node, node)
|
|
239
253
|
return if begin_node.chained?
|
|
240
254
|
|
|
@@ -315,6 +329,13 @@ module RuboCop
|
|
|
315
329
|
(node.end.nil? && begin_node == parent.children.last)
|
|
316
330
|
end
|
|
317
331
|
|
|
332
|
+
# `and`/`or` keyword operators bind looser than the method-argument
|
|
333
|
+
# boundary, so `foo((x and y))` cannot drop its parentheses without
|
|
334
|
+
# becoming a syntax error (unlike `&&`/`||`).
|
|
335
|
+
def keyword_logical_operator?(node)
|
|
336
|
+
node.operator_keyword? && node.semantic_operator?
|
|
337
|
+
end
|
|
338
|
+
|
|
318
339
|
def disallowed_one_line_pattern_matching?(begin_node, node)
|
|
319
340
|
if (parent = begin_node.parent)
|
|
320
341
|
return false if parent.any_def_type? && parent.endless?
|
|
@@ -90,6 +90,8 @@ module RuboCop
|
|
|
90
90
|
quote = enforce_double_quotes? ? '"' : "'"
|
|
91
91
|
end
|
|
92
92
|
|
|
93
|
+
new_argument = escape_interpolation_like_text(new_argument) if quote == '"'
|
|
94
|
+
|
|
93
95
|
"#{quote}#{new_argument}#{quote}"
|
|
94
96
|
end
|
|
95
97
|
|
|
@@ -109,6 +111,11 @@ module RuboCop
|
|
|
109
111
|
char
|
|
110
112
|
end.join
|
|
111
113
|
end
|
|
114
|
+
|
|
115
|
+
# `#{`, `#$` and `#@` would start an interpolation in a double-quoted string.
|
|
116
|
+
def escape_interpolation_like_text(string)
|
|
117
|
+
string.gsub(/#(?=[{$@])/) { '\#' }
|
|
118
|
+
end
|
|
112
119
|
end
|
|
113
120
|
end
|
|
114
121
|
end
|
|
@@ -74,7 +74,7 @@ module RuboCop
|
|
|
74
74
|
|
|
75
75
|
non_redundant =
|
|
76
76
|
whitespace_in_free_space_mode?(node, class_elem) ||
|
|
77
|
-
backslash_b?(class_elem) ||
|
|
77
|
+
backslash_b?(class_elem) || backreference_requiring_char_class?(class_elem) ||
|
|
78
78
|
requires_escape_outside_char_class?(class_elem)
|
|
79
79
|
|
|
80
80
|
!non_redundant
|
|
@@ -104,10 +104,11 @@ module RuboCop
|
|
|
104
104
|
elem == '\b'
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
-
def
|
|
108
|
-
#
|
|
109
|
-
#
|
|
110
|
-
|
|
107
|
+
def backreference_requiring_char_class?(elem)
|
|
108
|
+
# `\1` to `\9` only match a literal digit inside a character class;
|
|
109
|
+
# outside it they are backreferences (and a syntax error when the
|
|
110
|
+
# referenced group does not exist), so the class is not redundant.
|
|
111
|
+
elem.match?(/\A\\[1-9]\z/)
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
def requires_escape_outside_char_class?(elem)
|
|
@@ -27,19 +27,39 @@ module RuboCop
|
|
|
27
27
|
def_node_matcher :redundant_regexp_constructor, <<~PATTERN
|
|
28
28
|
(send
|
|
29
29
|
(const {nil? cbase} :Regexp) {:new :compile}
|
|
30
|
-
(regexp
|
|
30
|
+
$(regexp _* (regopt _*)))
|
|
31
31
|
PATTERN
|
|
32
32
|
|
|
33
33
|
def on_send(node)
|
|
34
|
-
return unless (regexp
|
|
34
|
+
return unless (regexp = redundant_regexp_constructor(node))
|
|
35
35
|
|
|
36
36
|
add_offense(node, message: format(MSG, method: node.method_name)) do |corrector|
|
|
37
|
-
|
|
38
|
-
regopt = regopt.join
|
|
37
|
+
next if ambiguous_slash_regexp?(node, regexp)
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
# Reuse the inner literal's own source so its delimiters are preserved.
|
|
40
|
+
# Forcing `/.../` would break patterns like `%r{foo/bar}` that contain
|
|
41
|
+
# an unescaped slash.
|
|
42
|
+
corrector.replace(node, regexp.source)
|
|
41
43
|
end
|
|
42
44
|
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# `p / a/` and `p /=a/` parse as division, so a slash regexp starting
|
|
49
|
+
# with whitespace or `=` can't begin the first argument of a command.
|
|
50
|
+
def ambiguous_slash_regexp?(node, regexp)
|
|
51
|
+
return false unless regexp.slash_literal? && regexp.content.match?(/\A[\s=]/)
|
|
52
|
+
|
|
53
|
+
begin_pos = node.source_range.begin_pos
|
|
54
|
+
|
|
55
|
+
node.each_ancestor(:call).any? do |call|
|
|
56
|
+
command?(call) && call.first_argument.source_range.begin_pos == begin_pos
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def command?(call)
|
|
61
|
+
call.arguments? && !call.parenthesized? && !call.operator_method? && !call.setter_method?
|
|
62
|
+
end
|
|
43
63
|
end
|
|
44
64
|
end
|
|
45
65
|
end
|
|
@@ -43,6 +43,10 @@ module RuboCop
|
|
|
43
43
|
ALLOWED_OUTSIDE_CHAR_CLASS_METACHAR_ESCAPES = '.*+?{}()|$'.chars.freeze
|
|
44
44
|
INTERPOLATION_SIGILS = %w[@ $].freeze
|
|
45
45
|
|
|
46
|
+
def self.autocorrect_incompatible_with
|
|
47
|
+
[Style::RegexpLiteral]
|
|
48
|
+
end
|
|
49
|
+
|
|
46
50
|
def on_regexp(node)
|
|
47
51
|
each_escape(node) do |char, index, within_character_class|
|
|
48
52
|
next if char.valid_encoding? && allowed_escape?(node, char, index,
|
|
@@ -104,6 +104,7 @@ module RuboCop
|
|
|
104
104
|
['{', '}'] => /\\.|[{}]/,
|
|
105
105
|
['<', '>'] => /\\.|[<>]/
|
|
106
106
|
}.freeze
|
|
107
|
+
DELIMITERS_KEEPING_ESCAPE = %w[$ * + . ? ^ | ( ) [ ] { } < >].freeze
|
|
107
108
|
|
|
108
109
|
def on_regexp(node)
|
|
109
110
|
return if slash_literal?(node) && percent_r_delimiters_conflict?(node)
|
|
@@ -119,6 +120,7 @@ module RuboCop
|
|
|
119
120
|
add_offense(node, message: message) do |corrector|
|
|
120
121
|
correct_delimiters(node, corrector)
|
|
121
122
|
correct_inner_slashes(node, corrector)
|
|
123
|
+
correct_escaped_delimiters(node, corrector)
|
|
122
124
|
end
|
|
123
125
|
end
|
|
124
126
|
|
|
@@ -174,9 +176,8 @@ module RuboCop
|
|
|
174
176
|
cop_config['AllowInnerSlashes']
|
|
175
177
|
end
|
|
176
178
|
|
|
177
|
-
def node_body(node
|
|
178
|
-
|
|
179
|
-
node.each_child_node(*types).map(&:source).join
|
|
179
|
+
def node_body(node)
|
|
180
|
+
node.each_child_node(:str).map(&:source).join
|
|
180
181
|
end
|
|
181
182
|
|
|
182
183
|
def slash_literal?(node)
|
|
@@ -190,12 +191,20 @@ module RuboCop
|
|
|
190
191
|
def allowed_omit_parentheses_with_percent_r_literal?(node)
|
|
191
192
|
return false unless node.parent&.call_type?
|
|
192
193
|
return true if node.content.start_with?(' ', '=')
|
|
194
|
+
return true if first_argument_of_command?(node) && node.content.match?(/\A\s/)
|
|
193
195
|
|
|
194
196
|
enforced_style = config.for_cop('Style/MethodCallWithArgsParentheses')['EnforcedStyle']
|
|
195
197
|
|
|
196
198
|
enforced_style == 'omit_parentheses'
|
|
197
199
|
end
|
|
198
200
|
|
|
201
|
+
def first_argument_of_command?(node)
|
|
202
|
+
call = node.parent
|
|
203
|
+
return false unless call.first_argument.equal?(node)
|
|
204
|
+
|
|
205
|
+
!call.parenthesized? && !call.operator_method? && !call.setter_method?
|
|
206
|
+
end
|
|
207
|
+
|
|
199
208
|
def correct_delimiters(node, corrector)
|
|
200
209
|
replacement = calculate_replacement(node)
|
|
201
210
|
corrector.replace(node.loc.begin, replacement.first)
|
|
@@ -203,32 +212,16 @@ module RuboCop
|
|
|
203
212
|
end
|
|
204
213
|
|
|
205
214
|
def correct_inner_slashes(node, corrector)
|
|
206
|
-
regexp_begin = node.loc.begin.end_pos
|
|
207
|
-
|
|
208
|
-
inner_slash_indices(node).each do |index|
|
|
209
|
-
start = regexp_begin + index
|
|
210
|
-
|
|
211
|
-
corrector.replace(
|
|
212
|
-
range_between(
|
|
213
|
-
start,
|
|
214
|
-
start + inner_slash_before_correction(node).length
|
|
215
|
-
),
|
|
216
|
-
inner_slash_after_correction(node)
|
|
217
|
-
)
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def inner_slash_indices(node)
|
|
222
|
-
text = node_body(node, include_begin_nodes: true)
|
|
223
215
|
pattern = inner_slash_before_correction(node)
|
|
224
|
-
|
|
225
|
-
indices = []
|
|
216
|
+
replacement = inner_slash_after_correction(node)
|
|
226
217
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
218
|
+
node.each_child_node(:str) do |str_node|
|
|
219
|
+
inner_slash_indices(str_node.source, pattern).each do |index|
|
|
220
|
+
start = str_node.source_range.begin_pos + index
|
|
230
221
|
|
|
231
|
-
|
|
222
|
+
corrector.replace(range_between(start, start + pattern.length), replacement)
|
|
223
|
+
end
|
|
224
|
+
end
|
|
232
225
|
end
|
|
233
226
|
|
|
234
227
|
def inner_slash_before_correction(node)
|
|
@@ -239,6 +232,17 @@ module RuboCop
|
|
|
239
232
|
inner_slash_for(calculate_replacement(node).first)
|
|
240
233
|
end
|
|
241
234
|
|
|
235
|
+
def inner_slash_indices(text, pattern)
|
|
236
|
+
index = -1
|
|
237
|
+
indices = []
|
|
238
|
+
|
|
239
|
+
while (index = text.index(pattern, index + 1))
|
|
240
|
+
indices << index
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
indices
|
|
244
|
+
end
|
|
245
|
+
|
|
242
246
|
def inner_slash_for(opening_delimiter)
|
|
243
247
|
if ['/', '%r/'].include?(opening_delimiter)
|
|
244
248
|
'\/'
|
|
@@ -254,6 +258,51 @@ module RuboCop
|
|
|
254
258
|
%w[/ /]
|
|
255
259
|
end
|
|
256
260
|
end
|
|
261
|
+
|
|
262
|
+
def correct_escaped_delimiters(node, corrector)
|
|
263
|
+
return unless (delimiter = delimiter_to_unescape(node))
|
|
264
|
+
|
|
265
|
+
node.each_child_node(:str) do |str_node|
|
|
266
|
+
text = str_node.source
|
|
267
|
+
|
|
268
|
+
escaped_delimiter_indices(text, delimiter).each do |index|
|
|
269
|
+
start = str_node.source_range.begin_pos + index
|
|
270
|
+
replacement = escaped_delimiter_replacement(node, delimiter, text[index + 2])
|
|
271
|
+
|
|
272
|
+
corrector.replace(range_between(start, start + 2), replacement)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def delimiter_to_unescape(node)
|
|
278
|
+
return if slash_literal?(node)
|
|
279
|
+
|
|
280
|
+
delimiter = node.delimiters.first
|
|
281
|
+
|
|
282
|
+
delimiter unless delimiter == '/' || DELIMITERS_KEEPING_ESCAPE.include?(delimiter)
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
def escaped_delimiter_indices(text, delimiter)
|
|
286
|
+
indices = []
|
|
287
|
+
index = 0
|
|
288
|
+
|
|
289
|
+
while (index = text.index('\\', index))
|
|
290
|
+
indices << index if text[index + 1] == delimiter
|
|
291
|
+
index += 2
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
indices
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
# A bare `#` before `{`, `@` or `$` would start an interpolation between slashes.
|
|
298
|
+
# `\#` still reads as a literal `#` there, except in extended mode, where `%r#a\#{b}#x`
|
|
299
|
+
# reads `#{b}` as a comment; `#\{` keeps both that comment and a `#` inside
|
|
300
|
+
# a character class.
|
|
301
|
+
def escaped_delimiter_replacement(node, delimiter, next_char)
|
|
302
|
+
return delimiter unless delimiter == '#' && next_char&.match?(/[{@$]/)
|
|
303
|
+
|
|
304
|
+
node.extended? ? '#\\' : '\\#'
|
|
305
|
+
end
|
|
257
306
|
end
|
|
258
307
|
end
|
|
259
308
|
end
|
|
@@ -88,6 +88,8 @@ module RuboCop
|
|
|
88
88
|
return unless previous_older_sibling
|
|
89
89
|
|
|
90
90
|
add_offense(node, message: format(MSG, name: node.method_name)) do |corrector|
|
|
91
|
+
next unless own_lines?(previous_older_sibling) && own_lines?(search_node(node))
|
|
92
|
+
|
|
91
93
|
autocorrect(corrector, node, previous_older_sibling)
|
|
92
94
|
end
|
|
93
95
|
end
|
|
@@ -112,6 +114,13 @@ module RuboCop
|
|
|
112
114
|
end
|
|
113
115
|
end
|
|
114
116
|
|
|
117
|
+
def own_lines?(node)
|
|
118
|
+
range = node.source_range
|
|
119
|
+
rest_of_line = range.source_buffer.source_line(range.last_line)[range.last_column..]
|
|
120
|
+
|
|
121
|
+
begins_its_line?(range) && rest_of_line.match?(/\A\s*(#.*)?\z/)
|
|
122
|
+
end
|
|
123
|
+
|
|
115
124
|
def autocorrect(corrector, node, previous_older_sibling)
|
|
116
125
|
range1 = range_with_comments_and_lines(previous_older_sibling)
|
|
117
126
|
range2 = range_with_comments_and_lines(node.parent.if_type? ? node.parent : node)
|
|
@@ -54,6 +54,9 @@ module RuboCop
|
|
|
54
54
|
|
|
55
55
|
rescue_node = node.parent
|
|
56
56
|
add_offense(rescue_node) do |corrector|
|
|
57
|
+
# The heredoc body would be left behind when the rescue body is moved.
|
|
58
|
+
next if heredoc_end(node)
|
|
59
|
+
|
|
57
60
|
parenthesized = parenthesized?(rescue_node)
|
|
58
61
|
|
|
59
62
|
correct_rescue_block(corrector, rescue_node, parenthesized)
|
|
@@ -95,15 +98,8 @@ module RuboCop
|
|
|
95
98
|
end
|
|
96
99
|
|
|
97
100
|
def heredoc_end(node)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
heredoc = node.arguments.reverse.find do |argument|
|
|
101
|
-
argument.respond_to?(:heredoc?) && argument.heredoc?
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
return unless heredoc
|
|
105
|
-
|
|
106
|
-
heredoc.loc.heredoc_end
|
|
101
|
+
node.each_node(:any_str).select(&:heredoc?).map { |heredoc| heredoc.loc.heredoc_end }
|
|
102
|
+
.max_by(&:end_pos)
|
|
107
103
|
end
|
|
108
104
|
end
|
|
109
105
|
end
|
|
@@ -65,7 +65,7 @@ module RuboCop
|
|
|
65
65
|
return if correct_style?(node)
|
|
66
66
|
|
|
67
67
|
add_offense(node) do |corrector|
|
|
68
|
-
corrected = style == :return ? 'return' :
|
|
68
|
+
corrected = style == :return ? 'return' : return_nil(node)
|
|
69
69
|
|
|
70
70
|
corrector.replace(node, corrected)
|
|
71
71
|
end
|
|
@@ -79,13 +79,28 @@ module RuboCop
|
|
|
79
79
|
|
|
80
80
|
def correct_style?(node)
|
|
81
81
|
(style == :return && !return_nil_node?(node)) ||
|
|
82
|
-
(style == :return_nil && !return_node?(node))
|
|
82
|
+
(style == :return_nil && (!return_node?(node) || top_level_return?(node)))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def top_level_return?(node)
|
|
86
|
+
node.each_ancestor(:any_block, :any_def).none?
|
|
83
87
|
end
|
|
84
88
|
|
|
85
89
|
def scoped_node?(node)
|
|
86
90
|
node.any_def_type? || node.lambda?
|
|
87
91
|
end
|
|
88
92
|
|
|
93
|
+
def return_nil(node)
|
|
94
|
+
return 'return nil' unless (parent = node.parent)
|
|
95
|
+
|
|
96
|
+
if (parent.operator_keyword? && parent.logical_operator?) ||
|
|
97
|
+
(parent.if_type? && parent.ternary?)
|
|
98
|
+
'(return nil)'
|
|
99
|
+
else
|
|
100
|
+
'return nil'
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
89
104
|
# @!method chained_send?(node)
|
|
90
105
|
def_node_matcher :chained_send?, '(send !nil? ...)'
|
|
91
106
|
|
|
@@ -116,7 +116,17 @@ module RuboCop
|
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def handle_return(return_node)
|
|
119
|
-
|
|
119
|
+
return unless return_nil?(return_node)
|
|
120
|
+
|
|
121
|
+
replacement = requires_parentheses?(return_node) ? '(return false)' : 'return false'
|
|
122
|
+
register_offense(return_node, replacement)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def requires_parentheses?(node)
|
|
126
|
+
parent = node.parent
|
|
127
|
+
|
|
128
|
+
(parent.operator_keyword? && parent.logical_operator?) ||
|
|
129
|
+
(parent.if_type? && parent.ternary?)
|
|
120
130
|
end
|
|
121
131
|
|
|
122
132
|
def handle_nil(nil_node)
|
|
@@ -98,22 +98,23 @@ module RuboCop
|
|
|
98
98
|
second.int_type? ? second.to_a.first : :unknown
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
# rubocop:disable-next Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
|
102
101
|
def range_size(range_node)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
low, high = vals.map { |val| val.nil? ? 0 : val.children[0] }
|
|
107
|
-
return :unknown unless low.zero? && high >= 0
|
|
102
|
+
low, high = range_node.to_a
|
|
103
|
+
# An endless range takes the rest of the collection, whatever its size.
|
|
104
|
+
return :unknown unless zero_or_beginless?(low) && high&.int_type? && high.value >= 0
|
|
108
105
|
|
|
109
106
|
case range_node.type
|
|
110
107
|
when :erange
|
|
111
|
-
|
|
108
|
+
high.value
|
|
112
109
|
when :irange
|
|
113
|
-
|
|
110
|
+
high.value + 1
|
|
114
111
|
end
|
|
115
112
|
end
|
|
116
113
|
|
|
114
|
+
def zero_or_beginless?(low)
|
|
115
|
+
low.nil? || (low.int_type? && low.value.zero?)
|
|
116
|
+
end
|
|
117
|
+
|
|
117
118
|
def source_range(shuffle_node, node)
|
|
118
119
|
shuffle_node.loc.selector.join(node.source_range.end)
|
|
119
120
|
end
|
|
@@ -37,15 +37,20 @@ module RuboCop
|
|
|
37
37
|
private
|
|
38
38
|
|
|
39
39
|
def check(node, var_type)
|
|
40
|
-
return unless (rhs = node.expression)
|
|
40
|
+
return unless (rhs = unparenthesized(node.expression))
|
|
41
41
|
|
|
42
42
|
if rhs.send_type? && rhs.arguments.one?
|
|
43
43
|
check_send_node(node, rhs, node.name, var_type)
|
|
44
|
-
elsif rhs.operator_keyword?
|
|
44
|
+
elsif rhs.operator_keyword? && rhs.logical_operator?
|
|
45
45
|
check_boolean_node(node, rhs, node.name, var_type)
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
def unparenthesized(node)
|
|
50
|
+
node = node.children.first while node&.begin_type? && node.children.one?
|
|
51
|
+
node
|
|
52
|
+
end
|
|
53
|
+
|
|
49
54
|
def check_send_node(node, rhs, var_name, var_type)
|
|
50
55
|
return unless OPS.include?(rhs.method_name)
|
|
51
56
|
|
|
@@ -68,26 +73,18 @@ module RuboCop
|
|
|
68
73
|
end
|
|
69
74
|
|
|
70
75
|
def autocorrect(corrector, node)
|
|
71
|
-
rhs = node.expression
|
|
76
|
+
rhs = unparenthesized(node.expression)
|
|
72
77
|
|
|
73
78
|
if rhs.send_type?
|
|
74
|
-
|
|
79
|
+
apply_autocorrect(corrector, node, rhs.method_name, rhs.first_argument)
|
|
75
80
|
elsif rhs.operator_keyword?
|
|
76
|
-
|
|
81
|
+
apply_autocorrect(corrector, node, rhs.loc.operator.source, rhs.rhs)
|
|
77
82
|
end
|
|
78
83
|
end
|
|
79
84
|
|
|
80
|
-
def
|
|
81
|
-
apply_autocorrect(corrector, node, rhs, rhs.method_name, rhs.first_argument)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def autocorrect_boolean_node(corrector, node, rhs)
|
|
85
|
-
apply_autocorrect(corrector, node, rhs, rhs.loc.operator.source, rhs.rhs)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def apply_autocorrect(corrector, node, rhs, operator, new_rhs)
|
|
85
|
+
def apply_autocorrect(corrector, node, operator, new_rhs)
|
|
89
86
|
corrector.insert_before(node.loc.operator, operator)
|
|
90
|
-
corrector.replace(
|
|
87
|
+
corrector.replace(node.expression, new_rhs.source)
|
|
91
88
|
end
|
|
92
89
|
end
|
|
93
90
|
end
|
|
@@ -121,7 +121,6 @@ module RuboCop
|
|
|
121
121
|
tokens[1]&.type == :tSTRING_DBEG && tokens[2]&.semicolon?
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
# rubocop:disable-next Metrics/AbcSize, Metrics/MethodLength
|
|
125
124
|
def register_semicolon(line, column, after_expression, token_before_semicolon = nil)
|
|
126
125
|
range = source_range(processed_source.buffer, line, column)
|
|
127
126
|
|
|
@@ -134,13 +133,11 @@ module RuboCop
|
|
|
134
133
|
# See: https://github.com/rubocop/rubocop/issues/10791
|
|
135
134
|
if token_before_semicolon&.regexp_dots?
|
|
136
135
|
node = find_node(range_nodes, token_before_semicolon)
|
|
136
|
+
corrector.wrap(node, '(', ')') if node
|
|
137
137
|
elsif token_before_semicolon&.type == :tLABEL
|
|
138
|
-
|
|
139
|
-
space = node.parent.loc.selector.end.join(node.source_range.begin)
|
|
140
|
-
corrector.remove(space)
|
|
138
|
+
parenthesize_arguments(corrector, value_omission_hash(token_before_semicolon))
|
|
141
139
|
end
|
|
142
140
|
|
|
143
|
-
corrector.wrap(node, '(', ')') if node
|
|
144
141
|
corrector.remove(range)
|
|
145
142
|
end
|
|
146
143
|
end
|
|
@@ -161,6 +158,20 @@ module RuboCop
|
|
|
161
158
|
end
|
|
162
159
|
end
|
|
163
160
|
|
|
161
|
+
def value_omission_hash(token_before_semicolon)
|
|
162
|
+
find_node(value_omission_pair_nodes, token_before_semicolon)&.parent
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def parenthesize_arguments(corrector, hash_node)
|
|
166
|
+
return unless hash_node
|
|
167
|
+
|
|
168
|
+
call = hash_node.parent
|
|
169
|
+
before_arguments = args_begin(call).begin.join(call.first_argument.source_range.begin)
|
|
170
|
+
|
|
171
|
+
corrector.replace(before_arguments, '(')
|
|
172
|
+
corrector.insert_after(call.last_argument, ')')
|
|
173
|
+
end
|
|
174
|
+
|
|
164
175
|
def expressions_per_line(exprs)
|
|
165
176
|
# create a map matching lines to the number of expressions on them
|
|
166
177
|
exprs_lines = exprs.map(&:last_line)
|
|
@@ -33,7 +33,7 @@ module RuboCop
|
|
|
33
33
|
|
|
34
34
|
MSG = 'Name `%<method>s` block params `|%<params>s|`.'
|
|
35
35
|
|
|
36
|
-
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
36
|
+
def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- checks block parameter names
|
|
37
37
|
return unless node.single_line?
|
|
38
38
|
|
|
39
39
|
return unless eligible_method?(node)
|