rubocop 1.91.0 → 1.92.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/config/default.yml +4 -1
- data/lib/rubocop/cached_data.rb +47 -7
- data/lib/rubocop/changed_files.rb +35 -13
- data/lib/rubocop/cli/command/cop_names.rb +57 -0
- data/lib/rubocop/cli/command/execute_runner.rb +2 -2
- 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 +3 -2
- data/lib/rubocop/comment_config.rb +17 -8
- data/lib/rubocop/config.rb +0 -4
- data/lib/rubocop/config_loader.rb +6 -3
- data/lib/rubocop/config_loader_resolver.rb +37 -12
- data/lib/rubocop/config_obsoletion/removed_cop.rb +1 -1
- data/lib/rubocop/config_obsoletion.rb +9 -0
- data/lib/rubocop/config_validator.rb +11 -0
- data/lib/rubocop/cop/autocorrect_logic.rb +10 -5
- data/lib/rubocop/cop/badge.rb +1 -1
- data/lib/rubocop/cop/base.rb +42 -21
- 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 +37 -7
- data/lib/rubocop/cop/correctors/empty_line_corrector.rb +1 -1
- data/lib/rubocop/cop/correctors/lambda_literal_to_method_corrector.rb +25 -4
- data/lib/rubocop/cop/correctors/multiline_literal_brace_corrector.rb +34 -0
- data/lib/rubocop/cop/correctors/parentheses_corrector.rb +45 -8
- 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/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/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 +5 -1
- 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 +29 -7
- data/lib/rubocop/cop/layout/def_end_alignment.rb +4 -0
- data/lib/rubocop/cop/layout/dot_position.rb +25 -15
- data/lib/rubocop/cop/layout/empty_line_after_multiline_condition.rb +21 -8
- 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 +9 -3
- data/lib/rubocop/cop/layout/empty_lines_around_exception_handling_keywords.rb +23 -1
- data/lib/rubocop/cop/layout/end_alignment.rb +21 -25
- data/lib/rubocop/cop/layout/extra_spacing.rb +21 -6
- data/lib/rubocop/cop/layout/first_argument_indentation.rb +27 -1
- data/lib/rubocop/cop/layout/first_array_element_line_break.rb +15 -0
- data/lib/rubocop/cop/layout/first_hash_element_indentation.rb +16 -8
- 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/hash_alignment.rb +16 -12
- data/lib/rubocop/cop/layout/heredoc_argument_closing_parenthesis.rb +7 -3
- data/lib/rubocop/cop/layout/heredoc_indentation.rb +15 -0
- data/lib/rubocop/cop/layout/indentation_consistency.rb +22 -5
- data/lib/rubocop/cop/layout/indentation_style.rb +4 -1
- data/lib/rubocop/cop/layout/indentation_width.rb +2 -2
- 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 +176 -26
- 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 +9 -0
- data/lib/rubocop/cop/layout/multiline_method_call_brace_layout.rb +6 -0
- data/lib/rubocop/cop/layout/multiline_method_call_indentation.rb +30 -5
- 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 +16 -3
- 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 +6 -11
- data/lib/rubocop/cop/layout/space_around_keyword.rb +10 -0
- data/lib/rubocop/cop/layout/space_around_operators.rb +31 -4
- data/lib/rubocop/cop/layout/space_before_block_braces.rb +16 -1
- data/lib/rubocop/cop/layout/space_inside_array_literal_brackets.rb +15 -2
- data/lib/rubocop/cop/layout/space_inside_block_braces.rb +32 -9
- data/lib/rubocop/cop/layout/space_inside_range_literal.rb +29 -11
- data/lib/rubocop/cop/layout/space_inside_reference_brackets.rb +2 -12
- 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/ambiguous_regexp_literal.rb +6 -1
- data/lib/rubocop/cop/lint/empty_conditional_body.rb +3 -1
- data/lib/rubocop/cop/lint/heredoc_method_call_position.rb +4 -0
- data/lib/rubocop/cop/lint/interpolation_check.rb +20 -17
- data/lib/rubocop/cop/lint/literal_as_condition.rb +15 -0
- 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 +71 -11
- data/lib/rubocop/cop/lint/missing_cop_enable_directive.rb +18 -3
- data/lib/rubocop/cop/lint/nested_percent_literal.rb +3 -0
- data/lib/rubocop/cop/lint/number_conversion.rb +3 -1
- data/lib/rubocop/cop/lint/parentheses_as_grouped_expression.rb +22 -1
- data/lib/rubocop/cop/lint/percent_string_array.rb +75 -9
- data/lib/rubocop/cop/lint/redundant_cop_disable_directive.rb +39 -9
- data/lib/rubocop/cop/lint/redundant_dir_glob_sort.rb +13 -2
- data/lib/rubocop/cop/lint/redundant_splat_expansion.rb +11 -4
- data/lib/rubocop/cop/lint/safe_navigation_consistency.rb +47 -1
- data/lib/rubocop/cop/lint/symbol_conversion.rb +1 -0
- 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/useless_setter_call.rb +7 -4
- data/lib/rubocop/cop/lint/void.rb +8 -1
- 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/mixin/alignment.rb +4 -0
- data/lib/rubocop/cop/mixin/check_line_breakable.rb +23 -19
- data/lib/rubocop/cop/mixin/check_single_line_suitability.rb +8 -2
- data/lib/rubocop/cop/mixin/code_length.rb +10 -2
- data/lib/rubocop/cop/mixin/comments_help.rb +1 -1
- data/lib/rubocop/cop/mixin/empty_lines_around_body.rb +12 -1
- data/lib/rubocop/cop/mixin/endless_method_body_help.rb +105 -0
- data/lib/rubocop/cop/mixin/forbidden_identifiers.rb +2 -2
- data/lib/rubocop/cop/mixin/hash_alignment_styles.rb +41 -6
- data/lib/rubocop/cop/mixin/hash_shorthand_syntax.rb +26 -2
- 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 +17 -2
- 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 +39 -5
- data/lib/rubocop/cop/mixin/trailing_comma.rb +1 -1
- data/lib/rubocop/cop/mixin/visibility_help.rb +2 -1
- data/lib/rubocop/cop/mixin.rb +2 -0
- data/lib/rubocop/cop/naming/accessor_method_name.rb +0 -16
- data/lib/rubocop/cop/naming/block_forwarding.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/naming/rescued_exceptions_variable_name.rb +1 -1
- data/lib/rubocop/cop/offense.rb +59 -3
- data/lib/rubocop/cop/registry.rb +1 -1
- data/lib/rubocop/cop/security/json_load.rb +16 -4
- data/lib/rubocop/cop/style/access_modifier_declarations.rb +37 -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 +37 -10
- data/lib/rubocop/cop/style/arguments_forwarding.rb +32 -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 +35 -3
- data/lib/rubocop/cop/style/case_equality.rb +14 -3
- data/lib/rubocop/cop/style/case_like_if.rb +6 -3
- data/lib/rubocop/cop/style/class_and_module_children.rb +57 -16
- data/lib/rubocop/cop/style/class_methods_definitions.rb +15 -0
- data/lib/rubocop/cop/style/collection_querying.rb +79 -46
- data/lib/rubocop/cop/style/combinable_loops.rb +89 -11
- data/lib/rubocop/cop/style/concat_array_literals.rb +58 -7
- data/lib/rubocop/cop/style/conditional_assignment.rb +4 -0
- data/lib/rubocop/cop/style/disable_cops_within_source_code_directive.rb +65 -9
- data/lib/rubocop/cop/style/double_negation.rb +11 -0
- data/lib/rubocop/cop/style/empty_literal.rb +1 -1
- data/lib/rubocop/cop/style/empty_method.rb +3 -1
- data/lib/rubocop/cop/style/empty_string_inside_interpolation.rb +53 -11
- data/lib/rubocop/cop/style/endless_method.rb +104 -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/float_division.rb +37 -2
- data/lib/rubocop/cop/style/for.rb +53 -2
- data/lib/rubocop/cop/style/format_string.rb +28 -6
- data/lib/rubocop/cop/style/frozen_string_literal_comment.rb +2 -1
- data/lib/rubocop/cop/style/guard_clause.rb +31 -22
- data/lib/rubocop/cop/style/hash_as_last_array_item.rb +4 -0
- data/lib/rubocop/cop/style/hash_conversion.rb +28 -8
- data/lib/rubocop/cop/style/hash_lookup_method.rb +42 -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 +32 -26
- 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 +94 -4
- data/lib/rubocop/cop/style/keyword_parameters_order.rb +3 -1
- data/lib/rubocop/cop/style/lambda.rb +34 -1
- data/lib/rubocop/cop/style/lambda_call.rb +7 -2
- data/lib/rubocop/cop/style/map_into_array.rb +1 -2
- data/lib/rubocop/cop/style/method_call_with_args_parentheses/omit_parentheses.rb +80 -13
- data/lib/rubocop/cop/style/method_call_with_args_parentheses.rb +26 -2
- data/lib/rubocop/cop/style/method_call_without_args_parentheses.rb +26 -3
- data/lib/rubocop/cop/style/method_def_parentheses.rb +38 -4
- data/lib/rubocop/cop/style/missing_else.rb +7 -1
- data/lib/rubocop/cop/style/mixin_grouping.rb +12 -3
- 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 +52 -7
- 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 +27 -8
- 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 +16 -4
- data/lib/rubocop/cop/style/non_nil_check.rb +1 -1
- data/lib/rubocop/cop/style/not.rb +10 -5
- data/lib/rubocop/cop/style/numeric_predicate.rb +28 -5
- data/lib/rubocop/cop/style/one_line_conditional.rb +13 -2
- data/lib/rubocop/cop/style/parentheses_around_condition.rb +19 -1
- data/lib/rubocop/cop/style/percent_literal_delimiters.rb +14 -3
- data/lib/rubocop/cop/style/quoted_symbols.rb +5 -7
- data/lib/rubocop/cop/style/raise_args.rb +80 -11
- data/lib/rubocop/cop/style/reduce_to_hash.rb +47 -33
- data/lib/rubocop/cop/style/redundant_begin.rb +45 -5
- data/lib/rubocop/cop/style/redundant_condition.rb +30 -13
- data/lib/rubocop/cop/style/redundant_double_splat_hash_braces.rb +6 -0
- data/lib/rubocop/cop/style/redundant_exception.rb +27 -11
- data/lib/rubocop/cop/style/redundant_fetch_block.rb +9 -1
- data/lib/rubocop/cop/style/redundant_freeze.rb +11 -3
- data/lib/rubocop/cop/style/redundant_interpolation_unfreeze.rb +24 -1
- data/lib/rubocop/cop/style/redundant_parentheses.rb +12 -1
- data/lib/rubocop/cop/style/redundant_regexp_argument.rb +7 -0
- data/lib/rubocop/cop/style/redundant_regexp_constructor.rb +20 -0
- data/lib/rubocop/cop/style/redundant_regexp_escape.rb +4 -0
- data/lib/rubocop/cop/style/redundant_self.rb +9 -1
- data/lib/rubocop/cop/style/redundant_self_assignment_branch.rb +28 -0
- data/lib/rubocop/cop/style/redundant_sort.rb +38 -4
- data/lib/rubocop/cop/style/regexp_literal.rb +75 -26
- data/lib/rubocop/cop/style/require_order.rb +25 -8
- data/lib/rubocop/cop/style/rescue_modifier.rb +11 -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/send_with_literal_method_name.rb +4 -0
- data/lib/rubocop/cop/style/single_line_methods.rb +42 -4
- data/lib/rubocop/cop/style/stabby_lambda_parentheses.rb +29 -5
- data/lib/rubocop/cop/style/string_concatenation.rb +21 -4
- data/lib/rubocop/cop/style/struct_inheritance.rb +6 -0
- data/lib/rubocop/cop/style/super_arguments.rb +3 -0
- data/lib/rubocop/cop/style/symbol_proc.rb +24 -6
- data/lib/rubocop/cop/style/ternary_parentheses.rb +23 -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/team.rb +10 -5
- data/lib/rubocop/cop/variable_force/assignment.rb +1 -1
- data/lib/rubocop/cop/variable_force/variable.rb +14 -1
- data/lib/rubocop/formatter/base_formatter.rb +22 -0
- data/lib/rubocop/formatter/formatter_set.rb +4 -0
- data/lib/rubocop/formatter/json_formatter.rb +71 -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 +12 -7
- data/lib/rubocop/formatter/worst_offenders_formatter.rb +3 -1
- data/lib/rubocop/lsp/routes.rb +23 -23
- 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/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 +45 -10
- data/lib/rubocop/plugin/configuration_integrator.rb +36 -8
- data/lib/rubocop/remote_config.rb +4 -1
- data/lib/rubocop/result_cache.rb +20 -13
- data/lib/rubocop/runner.rb +110 -42
- data/lib/rubocop/server/cache.rb +6 -6
- data/lib/rubocop/target_ruby.rb +21 -9
- data/lib/rubocop/util.rb +69 -0
- data/lib/rubocop/version.rb +1 -1
- data/lib/rubocop.rb +5 -0
- metadata +16 -5
|
@@ -60,7 +60,7 @@ module RuboCop
|
|
|
60
60
|
add_offense(node.loc.keyword, message: MSG_ALIAS) do |corrector|
|
|
61
61
|
autocorrect(corrector, node)
|
|
62
62
|
end
|
|
63
|
-
elsif node.children.
|
|
63
|
+
elsif node.children.all? { |arg| !bareword?(arg) && bareword_symbol?(arg) }
|
|
64
64
|
add_offense_for_args(node) { |corrector| autocorrect(corrector, node) }
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -97,7 +97,7 @@ module RuboCop
|
|
|
97
97
|
|
|
98
98
|
def add_offense_for_args(node, &block)
|
|
99
99
|
existing_args = node.children.map(&:source).join(' ')
|
|
100
|
-
preferred_args = node.children.map { |
|
|
100
|
+
preferred_args = node.children.map { |node| bareword_for(node) }.join(' ')
|
|
101
101
|
arg_ranges = node.children.map(&:source_range)
|
|
102
102
|
msg = format(MSG_SYMBOL_ARGS, prefer: preferred_args, current: existing_args)
|
|
103
103
|
add_offense(arg_ranges.reduce(&:join), message: msg, &block)
|
|
@@ -138,6 +138,15 @@ module RuboCop
|
|
|
138
138
|
!sym_node.source.start_with?(':') || sym_node.dsym_type?
|
|
139
139
|
end
|
|
140
140
|
|
|
141
|
+
def bareword_symbol?(sym_node)
|
|
142
|
+
return false unless sym_node.sym_type?
|
|
143
|
+
|
|
144
|
+
value = sym_node.value.to_s
|
|
145
|
+
return true if value.match?(/\A[A-Za-z_]\w*[?!=]?\z/)
|
|
146
|
+
|
|
147
|
+
!sym_node.source.start_with?(':"', ":'") && !value.start_with?('@', '$')
|
|
148
|
+
end
|
|
149
|
+
|
|
141
150
|
def correct_alias_method_to_alias(corrector, send_node)
|
|
142
151
|
new, old = *send_node.arguments
|
|
143
152
|
replacement = "alias #{identifier(new)} #{identifier(old)}"
|
|
@@ -153,17 +162,21 @@ module RuboCop
|
|
|
153
162
|
end
|
|
154
163
|
|
|
155
164
|
def correct_alias_with_symbol_args(corrector, node)
|
|
156
|
-
corrector.replace(node.new_identifier, node.new_identifier
|
|
157
|
-
corrector.replace(node.old_identifier, node.old_identifier
|
|
165
|
+
corrector.replace(node.new_identifier, bareword_for(node.new_identifier))
|
|
166
|
+
corrector.replace(node.old_identifier, bareword_for(node.old_identifier))
|
|
158
167
|
end
|
|
159
168
|
|
|
160
169
|
def identifier(node)
|
|
161
|
-
if node
|
|
170
|
+
if bareword_symbol?(node)
|
|
162
171
|
":#{node.children.first}"
|
|
163
172
|
else
|
|
164
173
|
node.source
|
|
165
174
|
end
|
|
166
175
|
end
|
|
176
|
+
|
|
177
|
+
def bareword_for(sym_node)
|
|
178
|
+
sym_node.value.to_s
|
|
179
|
+
end
|
|
167
180
|
end
|
|
168
181
|
end
|
|
169
182
|
end
|
|
@@ -39,9 +39,9 @@ module RuboCop
|
|
|
39
39
|
# @!method ambiguous_endless_method_body(node)
|
|
40
40
|
def_node_matcher :ambiguous_endless_method_body, <<~PATTERN
|
|
41
41
|
^${
|
|
42
|
-
(if _ <
|
|
43
|
-
({and or}
|
|
44
|
-
({while until} _
|
|
42
|
+
(if _ <any_def _>)
|
|
43
|
+
({and or} any_def _)
|
|
44
|
+
({while until} _ any_def)
|
|
45
45
|
}
|
|
46
46
|
PATTERN
|
|
47
47
|
|
|
@@ -57,6 +57,7 @@ module RuboCop
|
|
|
57
57
|
correct_to_multiline(corrector, node)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
|
+
alias on_defs on_def
|
|
60
61
|
|
|
61
62
|
private
|
|
62
63
|
|
|
@@ -48,6 +48,10 @@ module RuboCop
|
|
|
48
48
|
|
|
49
49
|
MSG = 'Use `%<prefer>s` instead of `%<current>s`.'
|
|
50
50
|
|
|
51
|
+
def self.autocorrect_incompatible_with
|
|
52
|
+
[Style::MethodCallWithArgsParentheses, Style::ReturnNil, Style::ReturnNilInPredicateMethodDefinition]
|
|
53
|
+
end
|
|
54
|
+
|
|
51
55
|
def on_and(node)
|
|
52
56
|
process_logical_operator(node) if style == :always
|
|
53
57
|
end
|
|
@@ -68,13 +72,7 @@ module RuboCop
|
|
|
68
72
|
|
|
69
73
|
message = message(node)
|
|
70
74
|
add_offense(node.loc.operator, message: message) do |corrector|
|
|
71
|
-
node.each_child_node
|
|
72
|
-
if expr.send_type?
|
|
73
|
-
correct_send(expr, corrector)
|
|
74
|
-
elsif expr.type?(:return, :next, :break, :yield) || expr.assignment?
|
|
75
|
-
correct_other(expr, corrector)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
75
|
+
node.each_child_node { |expr| correct_operand(expr, corrector) }
|
|
78
76
|
|
|
79
77
|
corrector.replace(node.loc.operator, node.alternate_operator)
|
|
80
78
|
|
|
@@ -82,6 +80,22 @@ module RuboCop
|
|
|
82
80
|
end
|
|
83
81
|
end
|
|
84
82
|
|
|
83
|
+
def correct_operand(expr, corrector)
|
|
84
|
+
expr = expr.send_node if expr.any_block_type?
|
|
85
|
+
|
|
86
|
+
if expr.type?(:call, :super)
|
|
87
|
+
correct_send(expr, corrector)
|
|
88
|
+
elsif wrap_in_parentheses?(expr)
|
|
89
|
+
correct_other(expr, corrector)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# These bind looser than `&&` and `||`, or can't be their operands at all.
|
|
94
|
+
def wrap_in_parentheses?(node)
|
|
95
|
+
node.type?(:return, :next, :break, :yield, :any_match_pattern, :range, :defined?) ||
|
|
96
|
+
node.assignment? || (node.if_type? && node.ternary?)
|
|
97
|
+
end
|
|
98
|
+
|
|
85
99
|
def on_conditionals(node)
|
|
86
100
|
node.condition.each_node(*AST::Node::OPERATOR_KEYWORDS) do |operator|
|
|
87
101
|
process_logical_operator(operator)
|
|
@@ -97,6 +111,7 @@ module RuboCop
|
|
|
97
111
|
return correct_setter(node, corrector) if node.setter_method?
|
|
98
112
|
return correct_other(node, corrector) if node.comparison_method?
|
|
99
113
|
|
|
114
|
+
correct_block_receiver(node, corrector)
|
|
100
115
|
return unless correctable_send?(node)
|
|
101
116
|
|
|
102
117
|
whitespace_before_arg_range = whitespace_before_arg(node)
|
|
@@ -116,7 +131,8 @@ module RuboCop
|
|
|
116
131
|
# however, 'not x' also parses as (send x :!)
|
|
117
132
|
def correct_not(node, receiver, corrector)
|
|
118
133
|
if node.prefix_bang?
|
|
119
|
-
|
|
134
|
+
receiver = receiver.send_node if receiver.any_block_type?
|
|
135
|
+
return unless receiver.type?(:call, :super)
|
|
120
136
|
|
|
121
137
|
correct_send(receiver, corrector)
|
|
122
138
|
elsif node.prefix_not?
|
|
@@ -141,12 +157,23 @@ module RuboCop
|
|
|
141
157
|
end
|
|
142
158
|
end
|
|
143
159
|
|
|
160
|
+
# A method chained onto a `do` block, as in `bar baz do ... end.qux`,
|
|
161
|
+
# still needs parentheses around the arguments of the call that takes the block.
|
|
162
|
+
def correct_block_receiver(node, corrector)
|
|
163
|
+
receiver = node.receiver
|
|
164
|
+
receiver = receiver.receiver while receiver&.call_type?
|
|
165
|
+
correct_operand(receiver, corrector) if receiver&.any_block_type?
|
|
166
|
+
end
|
|
167
|
+
|
|
144
168
|
def correctable_send?(node)
|
|
145
|
-
|
|
169
|
+
# Operator syntax such as `a + b` or `a[b]` already binds tighter than `&&` and `||`.
|
|
170
|
+
return false if node.operator_method? && !node.loc.dot
|
|
171
|
+
|
|
172
|
+
!node.parenthesized? && node.arguments?
|
|
146
173
|
end
|
|
147
174
|
|
|
148
175
|
def whitespace_before_arg(node)
|
|
149
|
-
begin_paren = node.
|
|
176
|
+
begin_paren = node.selector.end_pos
|
|
150
177
|
end_paren = begin_paren
|
|
151
178
|
# Increment position of parenthesis, unless message is a predicate
|
|
152
179
|
# method followed by a non-whitespace char (e.g. is_a?String).
|
|
@@ -153,7 +153,7 @@ module RuboCop
|
|
|
153
153
|
BLOCK_MSG = 'Use anonymous block arguments forwarding (`&`).'
|
|
154
154
|
|
|
155
155
|
def self.autocorrect_incompatible_with
|
|
156
|
-
[Naming::BlockForwarding, Style::MethodDefParentheses]
|
|
156
|
+
[Naming::BlockForwarding, Style::EndlessMethod, Style::MethodDefParentheses]
|
|
157
157
|
end
|
|
158
158
|
|
|
159
159
|
def on_def(node)
|
|
@@ -169,7 +169,7 @@ module RuboCop
|
|
|
169
169
|
|
|
170
170
|
return if send_classifications.empty?
|
|
171
171
|
|
|
172
|
-
if
|
|
172
|
+
if forward_all?(send_nodes, send_classifications)
|
|
173
173
|
add_forward_all_offenses(node, send_classifications, forwardable_args)
|
|
174
174
|
elsif target_ruby_version >= 3.2
|
|
175
175
|
add_post_ruby_32_offenses(node, send_classifications, forwardable_args)
|
|
@@ -192,11 +192,33 @@ module RuboCop
|
|
|
192
192
|
[restarg_node, kwrestarg_node, blockarg_node]
|
|
193
193
|
end
|
|
194
194
|
|
|
195
|
+
def forward_all?(send_nodes, send_classifications)
|
|
196
|
+
only_forwards_all?(send_classifications) &&
|
|
197
|
+
!anonymous_forwarding_elsewhere?(send_nodes, send_classifications)
|
|
198
|
+
end
|
|
199
|
+
|
|
195
200
|
def only_forwards_all?(send_classifications)
|
|
196
201
|
all_classifications = %i[all all_anonymous].freeze
|
|
197
202
|
send_classifications.all? { |_, c, _, _| all_classifications.include?(c) }
|
|
198
203
|
end
|
|
199
204
|
|
|
205
|
+
def anonymous_forwarding_elsewhere?(send_nodes, send_classifications)
|
|
206
|
+
classified = send_classifications.map(&:first)
|
|
207
|
+
|
|
208
|
+
send_nodes.any? do |send_node|
|
|
209
|
+
classified.none? { |node| node.equal?(send_node) } &&
|
|
210
|
+
forwards_anonymous_args?(send_node)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def forwards_anonymous_args?(send_node)
|
|
215
|
+
send_node.arguments.any? do |arg|
|
|
216
|
+
next arg.children.any?(&:forwarded_kwrestarg_type?) if arg.hash_type?
|
|
217
|
+
|
|
218
|
+
arg.forwarded_restarg_type?
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
200
222
|
# rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
|
|
201
223
|
def add_forward_all_offenses(node, send_classifications, forwardable_args)
|
|
202
224
|
rest_arg, kwrest_arg, block_arg = *forwardable_args
|
|
@@ -376,11 +398,16 @@ module RuboCop
|
|
|
376
398
|
|
|
377
399
|
def add_parens_if_missing(node, corrector)
|
|
378
400
|
return if parentheses?(node)
|
|
379
|
-
return if node.
|
|
401
|
+
return if node.call_type? && operator_or_setter_call?(node)
|
|
402
|
+
return unless (@parenthesized_nodes ||= Set.new.compare_by_identity).add?(node)
|
|
380
403
|
|
|
381
404
|
add_parentheses(node, corrector)
|
|
382
405
|
end
|
|
383
406
|
|
|
407
|
+
def operator_or_setter_call?(node)
|
|
408
|
+
node.setter_method? || (node.operator_method? && !node.loc.dot)
|
|
409
|
+
end
|
|
410
|
+
|
|
384
411
|
# Classifies send nodes for possible rest/kwrest/all (including block) forwarding.
|
|
385
412
|
class SendNodeClassifier
|
|
386
413
|
extend NodePattern::Macros
|
|
@@ -499,6 +526,8 @@ module RuboCop
|
|
|
499
526
|
end
|
|
500
527
|
|
|
501
528
|
def offensive_block_forwarding?
|
|
529
|
+
return false if @send_node.block_literal?
|
|
530
|
+
|
|
502
531
|
@block_arg ? forwarded_block_arg : allow_offense_for_no_block?
|
|
503
532
|
end
|
|
504
533
|
|
|
@@ -50,10 +50,9 @@ module RuboCop
|
|
|
50
50
|
def autocorrect(corrector, node)
|
|
51
51
|
attr_name, setter = *node.arguments
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
remove = range_between(attr_expr.end_pos, node_expr.end_pos) if setter&.boolean_type?
|
|
53
|
+
if setter&.boolean_type?
|
|
54
|
+
remove = range_between(attr_name.source_range.end_pos, setter.source_range.end_pos)
|
|
55
|
+
end
|
|
57
56
|
|
|
58
57
|
corrector.replace(node.loc.selector, replacement_method(node))
|
|
59
58
|
corrector.remove(remove) if remove
|
|
@@ -66,16 +66,18 @@ module RuboCop
|
|
|
66
66
|
|
|
67
67
|
# @!method bit_operation?(node)
|
|
68
68
|
def_node_matcher :bit_operation?, <<~PATTERN
|
|
69
|
-
|
|
70
|
-
(send _ :& _))
|
|
69
|
+
{
|
|
70
|
+
(begin (send _ :& _))
|
|
71
|
+
(send _ :& _)
|
|
72
|
+
}
|
|
71
73
|
PATTERN
|
|
72
74
|
|
|
73
75
|
# rubocop:disable-next Metrics/AbcSize
|
|
74
76
|
def on_send(node)
|
|
75
|
-
return unless node.receiver
|
|
77
|
+
return unless bit_operation?(node.receiver)
|
|
76
78
|
return unless (preferred_method = preferred_method(node))
|
|
77
79
|
|
|
78
|
-
bit_operation = node.receiver.children.first
|
|
80
|
+
bit_operation = node.receiver.begin_type? ? node.receiver.children.first : node.receiver
|
|
79
81
|
lhs, _operator, rhs = *bit_operation
|
|
80
82
|
|
|
81
83
|
preferred = if preferred_method == 'allbits?' && lhs.source == node.first_argument.source
|
|
@@ -177,7 +177,7 @@ module RuboCop
|
|
|
177
177
|
BRACES_REQUIRED_MESSAGE = "Brace delimiters `{...}` required for '%<method_name>s' method."
|
|
178
178
|
|
|
179
179
|
def self.autocorrect_incompatible_with
|
|
180
|
-
[Style::RedundantBegin]
|
|
180
|
+
[Layout::SpaceBeforeBlockBraces, Style::MethodCallWithArgsParentheses, Style::RedundantBegin]
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def on_send(node)
|
|
@@ -196,6 +196,8 @@ module RuboCop
|
|
|
196
196
|
end
|
|
197
197
|
end
|
|
198
198
|
alias on_csend on_send
|
|
199
|
+
alias on_super on_send
|
|
200
|
+
alias on_yield on_send
|
|
199
201
|
|
|
200
202
|
def on_block(node)
|
|
201
203
|
return if part_of_ignored_node?(node)
|
|
@@ -292,7 +294,7 @@ module RuboCop
|
|
|
292
294
|
corrector.replace(b, '{')
|
|
293
295
|
corrector.replace(e, '}')
|
|
294
296
|
|
|
295
|
-
corrector
|
|
297
|
+
wrap_body_with_begin(corrector, node.body) if begin_required?(node)
|
|
296
298
|
end
|
|
297
299
|
|
|
298
300
|
def whitespace_before?(range)
|
|
@@ -304,6 +306,8 @@ module RuboCop
|
|
|
304
306
|
end
|
|
305
307
|
|
|
306
308
|
def move_comment_before_block(corrector, comment, block_node, closing_brace)
|
|
309
|
+
return if directive_comment?(comment)
|
|
310
|
+
|
|
307
311
|
range = block_node.chained? ? end_of_chain(block_node.parent).source_range : closing_brace
|
|
308
312
|
|
|
309
313
|
# It is possible that there is code between the block and the comment
|
|
@@ -317,6 +321,10 @@ module RuboCop
|
|
|
317
321
|
corrector.insert_before(block_node, "#{comment.text}\n")
|
|
318
322
|
end
|
|
319
323
|
|
|
324
|
+
def directive_comment?(comment)
|
|
325
|
+
comment.text.match?(DirectiveComment::DIRECTIVE_COMMENT_REGEXP)
|
|
326
|
+
end
|
|
327
|
+
|
|
320
328
|
def source_range_before_comment(range, comment)
|
|
321
329
|
range = range.end.join(comment.source_range.begin)
|
|
322
330
|
|
|
@@ -372,6 +380,7 @@ module RuboCop
|
|
|
372
380
|
# rubocop:disable-next Metrics/CyclomaticComplexity -- inlined special_method checks to avoid double evaluation
|
|
373
381
|
def proper_block_style?(node)
|
|
374
382
|
return true if require_do_end?(node)
|
|
383
|
+
return true if collection_of_for_loop?(node)
|
|
375
384
|
|
|
376
385
|
method_name = node.method_name
|
|
377
386
|
return true if allowed_method?(method_name) || matches_allowed_pattern?(method_name)
|
|
@@ -398,6 +407,10 @@ module RuboCop
|
|
|
398
407
|
!modifier_rescue?(body)
|
|
399
408
|
end
|
|
400
409
|
|
|
410
|
+
def collection_of_for_loop?(node)
|
|
411
|
+
node.parent&.for_type? && node.parent.collection == node
|
|
412
|
+
end
|
|
413
|
+
|
|
401
414
|
def modifier_rescue?(rescue_node)
|
|
402
415
|
return false if rescue_node.body.nil? || rescue_node.else_branch
|
|
403
416
|
return false unless rescue_node.resbody_branches.one?
|
|
@@ -438,11 +451,20 @@ module RuboCop
|
|
|
438
451
|
end
|
|
439
452
|
|
|
440
453
|
def correction_would_break_code?(node)
|
|
441
|
-
return
|
|
454
|
+
return loop_condition?(node) if node.braces?
|
|
442
455
|
|
|
443
456
|
node.send_node.arguments? && !node.send_node.parenthesized?
|
|
444
457
|
end
|
|
445
458
|
|
|
459
|
+
# A `do` in the condition of `while` or `until` is taken as the start of
|
|
460
|
+
# the loop body. Inside the body of another block it is unambiguous again.
|
|
461
|
+
def loop_condition?(node)
|
|
462
|
+
ancestors = node.each_ancestor.take_while { |ancestor| !ancestor.any_block_type? }
|
|
463
|
+
[node, *ancestors].each_cons(2).any? do |child, parent|
|
|
464
|
+
parent.type?(:while, :until) && parent.condition.equal?(child)
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
446
468
|
def functional_method?(method_name)
|
|
447
469
|
functional_methods.include?(method_name)
|
|
448
470
|
end
|
|
@@ -490,6 +512,16 @@ module RuboCop
|
|
|
490
512
|
node.type?(:array, :range)
|
|
491
513
|
end
|
|
492
514
|
|
|
515
|
+
def wrap_body_with_begin(corrector, body)
|
|
516
|
+
heredoc_ends = body.each_node(:any_str).select(&:heredoc?).map do |str|
|
|
517
|
+
str.loc.heredoc_end
|
|
518
|
+
end
|
|
519
|
+
body_end = [body.source_range, *heredoc_ends].max_by(&:end_pos)
|
|
520
|
+
|
|
521
|
+
corrector.insert_before(body, "begin\n")
|
|
522
|
+
corrector.insert_after(body_end, "\nend")
|
|
523
|
+
end
|
|
524
|
+
|
|
493
525
|
def begin_required?(block_node)
|
|
494
526
|
# If the block contains `rescue` or `ensure`, it needs to be wrapped in
|
|
495
527
|
# `begin`...`end` when changing `do-end` to `{}`.
|
|
@@ -7,7 +7,7 @@ module RuboCop
|
|
|
7
7
|
# The `===` operator has different behavior depending on the
|
|
8
8
|
# receiver and its use outside of `case`/`when` is confusing.
|
|
9
9
|
# Prefer more explicit alternatives like `is_a?`, `include?`,
|
|
10
|
-
# or `match?`.
|
|
10
|
+
# `cover?`, or `match?`.
|
|
11
11
|
#
|
|
12
12
|
# If `AllowOnConstant` option is enabled, the cop will ignore violations when the receiver of
|
|
13
13
|
# the case equality operator is a constant.
|
|
@@ -22,9 +22,11 @@ module RuboCop
|
|
|
22
22
|
# @example
|
|
23
23
|
# # bad
|
|
24
24
|
# (1..100) === 7
|
|
25
|
+
# ('a'..'z') === char
|
|
25
26
|
#
|
|
26
27
|
# # good
|
|
27
28
|
# (1..100).include?(7)
|
|
29
|
+
# ('a'..'z').cover?(char)
|
|
28
30
|
#
|
|
29
31
|
# @example AllowOnConstant: false (default)
|
|
30
32
|
# # bad
|
|
@@ -90,9 +92,18 @@ module RuboCop
|
|
|
90
92
|
end
|
|
91
93
|
|
|
92
94
|
def begin_replacement(lhs, rhs)
|
|
93
|
-
|
|
95
|
+
range = lhs.children.first
|
|
96
|
+
return unless range&.range_type?
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
method = cover_semantics?(range) ? 'cover?' : 'include?'
|
|
99
|
+
|
|
100
|
+
"#{lhs.source}.#{method}(#{rhs.source})"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# `Range#===` behaves like `Range#cover?` since Ruby 2.7 (since Ruby 2.6 for ranges
|
|
104
|
+
# that aren't string ranges), and `Range#include?` only matches that for numeric ranges.
|
|
105
|
+
def cover_semantics?(range)
|
|
106
|
+
target_ruby_version >= 2.7 && !range.children.compact.all?(&:numeric_type?)
|
|
96
107
|
end
|
|
97
108
|
|
|
98
109
|
def const_replacement(lhs, rhs)
|
|
@@ -54,6 +54,10 @@ module RuboCop
|
|
|
54
54
|
|
|
55
55
|
MSG = 'Convert `if-elsif` to `case-when`.'
|
|
56
56
|
|
|
57
|
+
def self.autocorrect_incompatible_with
|
|
58
|
+
[Style::IfInsideElse]
|
|
59
|
+
end
|
|
60
|
+
|
|
57
61
|
def on_if(node)
|
|
58
62
|
return unless should_check?(node)
|
|
59
63
|
|
|
@@ -224,10 +228,9 @@ module RuboCop
|
|
|
224
228
|
end
|
|
225
229
|
|
|
226
230
|
def branch_conditions(node)
|
|
227
|
-
conditions = []
|
|
228
|
-
while node&.if_type? &&
|
|
231
|
+
conditions = [node.condition]
|
|
232
|
+
while (node = node.else_branch)&.if_type? && node.elsif?
|
|
229
233
|
conditions << node.condition
|
|
230
|
-
node = node.else_branch
|
|
231
234
|
end
|
|
232
235
|
conditions
|
|
233
236
|
end
|
|
@@ -65,6 +65,13 @@ module RuboCop
|
|
|
65
65
|
NESTED_MSG = 'Use nested module/class definitions instead of compact style.'
|
|
66
66
|
COMPACT_MSG = 'Use compact module/class definition instead of nested style.'
|
|
67
67
|
|
|
68
|
+
# `Style/StructInheritance` and `Style/DataInheritance` turn a class definition into
|
|
69
|
+
# a constant assignment in the same pass, which the compacted `class` keyword would
|
|
70
|
+
# then precede.
|
|
71
|
+
def self.autocorrect_incompatible_with
|
|
72
|
+
[Style::DataInheritance, Style::StructInheritance]
|
|
73
|
+
end
|
|
74
|
+
|
|
68
75
|
def on_class(node)
|
|
69
76
|
return if node.parent_class && style_for_classes != :nested
|
|
70
77
|
|
|
@@ -117,7 +124,10 @@ module RuboCop
|
|
|
117
124
|
end
|
|
118
125
|
|
|
119
126
|
def heuristic_namespace_keyword(node)
|
|
120
|
-
|
|
127
|
+
left_sibling = node.left_sibling
|
|
128
|
+
return 'module' unless left_sibling.is_a?(AST::Node)
|
|
129
|
+
|
|
130
|
+
class_definition = left_sibling.each_node(:class).find do |class_node|
|
|
121
131
|
class_node.identifier == node.identifier.namespace
|
|
122
132
|
end
|
|
123
133
|
|
|
@@ -143,7 +153,9 @@ module RuboCop
|
|
|
143
153
|
# making autocorrection ping-pong between the two forms.
|
|
144
154
|
return if style_for_kind(node.body.type) == :nested
|
|
145
155
|
return unless compactible_namespace?(node)
|
|
156
|
+
return if node.each_ancestor(:class, :module).any? { |ancestor| ignored_node?(ancestor) }
|
|
146
157
|
|
|
158
|
+
ignore_node(node)
|
|
147
159
|
compact_node(corrector, node)
|
|
148
160
|
remove_end(corrector, node.body)
|
|
149
161
|
unindent(corrector, node)
|
|
@@ -194,33 +206,62 @@ module RuboCop
|
|
|
194
206
|
"#{node.body.children.first.const_name}"
|
|
195
207
|
end
|
|
196
208
|
|
|
197
|
-
# rubocop:disable-next Metrics/AbcSize
|
|
198
209
|
def remove_end(corrector, body)
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
|
|
205
|
-
range = range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
|
|
210
|
+
range = if same_line?(body.loc.name, body.loc.end)
|
|
211
|
+
single_line_end_range(body)
|
|
212
|
+
else
|
|
213
|
+
multiline_end_range(body)
|
|
214
|
+
end
|
|
206
215
|
|
|
207
216
|
corrector.remove(range)
|
|
208
217
|
end
|
|
209
218
|
|
|
210
|
-
def
|
|
211
|
-
|
|
219
|
+
def single_line_end_range(body)
|
|
220
|
+
raw = processed_source.raw_source
|
|
221
|
+
pos = body.loc.end.begin_pos
|
|
222
|
+
pos -= 1 while raw[pos - 1] == ' '
|
|
223
|
+
pos -= 1 if raw[pos - 1] == ';'
|
|
224
|
+
range_between(pos, body.loc.end.end_pos)
|
|
225
|
+
end
|
|
212
226
|
|
|
213
|
-
|
|
214
|
-
|
|
227
|
+
def multiline_end_range(body)
|
|
228
|
+
remove_begin_pos = body.loc.end.begin_pos - leading_spaces(body).size
|
|
229
|
+
adjustment = processed_source.raw_source[remove_begin_pos] == ';' ? 0 : 1
|
|
230
|
+
range_between(remove_begin_pos, body.loc.end.end_pos + adjustment)
|
|
231
|
+
end
|
|
215
232
|
|
|
216
|
-
|
|
217
|
-
|
|
233
|
+
def unindent(corrector, node)
|
|
234
|
+
column_delta = unindent_column_delta(node)
|
|
235
|
+
return unless column_delta&.negative?
|
|
236
|
+
|
|
237
|
+
range = unindentable_range(node.body)
|
|
238
|
+
return unless range
|
|
218
239
|
|
|
219
240
|
AlignmentCorrector.correct(
|
|
220
|
-
corrector, processed_source,
|
|
241
|
+
corrector, processed_source, range, column_delta, tab_indentation: true
|
|
221
242
|
)
|
|
222
243
|
end
|
|
223
244
|
|
|
245
|
+
def unindent_column_delta(node)
|
|
246
|
+
body = node.body.children.last
|
|
247
|
+
return unless body
|
|
248
|
+
|
|
249
|
+
node_indentation = spaces_size(leading_spaces(node))
|
|
250
|
+
body_indentation = spaces_size(leading_spaces(body))
|
|
251
|
+
|
|
252
|
+
node_indentation + configured_indentation_width - body_indentation
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def unindentable_range(body)
|
|
256
|
+
first_line = body.loc.name.line + 1
|
|
257
|
+
last_line = body.loc.end.line - 1
|
|
258
|
+
return if first_line > last_line
|
|
259
|
+
|
|
260
|
+
buffer = processed_source.buffer
|
|
261
|
+
range_between(buffer.line_range(first_line).begin_pos,
|
|
262
|
+
buffer.line_range(last_line).end_pos)
|
|
263
|
+
end
|
|
264
|
+
|
|
224
265
|
def leading_spaces(node)
|
|
225
266
|
node.source_range.source_line[/\A\s*/]
|
|
226
267
|
end
|
|
@@ -72,9 +72,13 @@ module RuboCop
|
|
|
72
72
|
return unless def_self_style?
|
|
73
73
|
return unless node.identifier.self_type?
|
|
74
74
|
return unless all_methods_public?(node)
|
|
75
|
+
return unless def_nodes(node).all? { |def_node| no_code_after?(def_node.source_range) }
|
|
75
76
|
|
|
76
77
|
add_offense(node, message: MSG_SCLASS) do |corrector|
|
|
78
|
+
next if inside_corrected_sclass?(node)
|
|
79
|
+
|
|
77
80
|
autocorrect_sclass(node, corrector)
|
|
81
|
+
ignore_node(node)
|
|
78
82
|
end
|
|
79
83
|
end
|
|
80
84
|
|
|
@@ -112,6 +116,17 @@ module RuboCop
|
|
|
112
116
|
end
|
|
113
117
|
end
|
|
114
118
|
|
|
119
|
+
def no_code_after?(range)
|
|
120
|
+
trailing = processed_source.lines[range.last_line - 1][range.last_column..].to_s.strip
|
|
121
|
+
trailing = trailing.sub(/\A;+\s*/, '')
|
|
122
|
+
|
|
123
|
+
trailing.empty? || trailing.start_with?('#')
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def inside_corrected_sclass?(node)
|
|
127
|
+
node.each_ancestor(:sclass).any? { |ancestor| ignored_node?(ancestor) }
|
|
128
|
+
end
|
|
129
|
+
|
|
115
130
|
def autocorrect_sclass(node, corrector)
|
|
116
131
|
rewritten_defs = []
|
|
117
132
|
|