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
|
@@ -51,14 +51,6 @@ module RuboCop
|
|
|
51
51
|
end
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
private
|
|
55
|
-
|
|
56
|
-
def previous_declaration(node)
|
|
57
|
-
declarations = gem_declarations(processed_source.ast)
|
|
58
|
-
node_index = declarations.map(&:location).find_index(node.location)
|
|
59
|
-
declarations.to_a[node_index - 1]
|
|
60
|
-
end
|
|
61
|
-
|
|
62
54
|
# @!method gem_declarations(node)
|
|
63
55
|
def_node_search :gem_declarations, <<~PATTERN
|
|
64
56
|
(:send nil? :gem str ...)
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Reads the documentation comment a cop carries above its class definition
|
|
6
|
+
# and splits it into the sections worth showing on their own.
|
|
7
|
+
#
|
|
8
|
+
# YARD is a development dependency, so the comment is read straight from the
|
|
9
|
+
# source rather than through a doclet.
|
|
10
|
+
# @api private
|
|
11
|
+
class CopDocumentation
|
|
12
|
+
TAG = /^@(\w+)\s*(.*)$/.freeze
|
|
13
|
+
|
|
14
|
+
def initialize(cop_class)
|
|
15
|
+
@cop_class = cop_class
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @return [Array<Array(String, Array<String>)>] title and body per section
|
|
19
|
+
def sections
|
|
20
|
+
comment = comment_lines
|
|
21
|
+
return [] if comment.empty?
|
|
22
|
+
|
|
23
|
+
prose, tagged = split_on_first_tag(comment)
|
|
24
|
+
|
|
25
|
+
[['Details', strip_blank(prose)], *tagged_sections(tagged)].reject { |_, b| b.empty? }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def comment_lines
|
|
31
|
+
path, line = source_location
|
|
32
|
+
return [] unless path && File.file?(path)
|
|
33
|
+
|
|
34
|
+
lines = File.readlines(path, chomp: true)
|
|
35
|
+
collect_comment_above(lines, line - 2)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def source_location
|
|
39
|
+
name = @cop_class.name
|
|
40
|
+
return [] unless name
|
|
41
|
+
|
|
42
|
+
Module.const_source_location(name) || []
|
|
43
|
+
rescue NameError
|
|
44
|
+
[]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Walks up from the class definition for as long as the lines are comments.
|
|
48
|
+
def collect_comment_above(lines, index)
|
|
49
|
+
block = []
|
|
50
|
+
while index >= 0 && lines[index].match?(/^\s*#/)
|
|
51
|
+
block.unshift(lines[index].sub(/^\s*# ?/, ''))
|
|
52
|
+
index -= 1
|
|
53
|
+
end
|
|
54
|
+
block
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def split_on_first_tag(comment)
|
|
58
|
+
first_tag = comment.index { |line| line.match?(TAG) }
|
|
59
|
+
return [comment, []] unless first_tag
|
|
60
|
+
|
|
61
|
+
[comment[0...first_tag], comment[first_tag..]]
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def tagged_sections(lines)
|
|
65
|
+
lines.slice_before { |line| line.match?(TAG) }.map do |(head, *body)|
|
|
66
|
+
tag, argument = head.match(TAG).captures
|
|
67
|
+
[section_title(tag, argument), strip_blank(body)]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def section_title(tag, argument)
|
|
72
|
+
title = tag.capitalize
|
|
73
|
+
argument.empty? ? title : "#{title}: #{argument}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def strip_blank(lines)
|
|
77
|
+
lines.drop_while(&:empty?).reverse.drop_while(&:empty?).reverse
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
# Explains what a single cop does: its description, how it is configured,
|
|
6
|
+
# whether it corrects, and the examples from its own documentation.
|
|
7
|
+
#
|
|
8
|
+
# Rendered as plain text, which is what `--explain` prints and what the MCP
|
|
9
|
+
# server hands to an agent.
|
|
10
|
+
# @api private
|
|
11
|
+
class CopExplanation
|
|
12
|
+
# Keys that describe the cop to RuboCop itself rather than something a
|
|
13
|
+
# user would set, so they are reported in their own section or not at all.
|
|
14
|
+
METADATA_KEYS = %w[
|
|
15
|
+
Description StyleGuide Reference References Enabled Safe SafeAutoCorrect
|
|
16
|
+
AutoCorrect VersionAdded VersionChanged Include Exclude Details Preview
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
def initialize(cop_class, config)
|
|
20
|
+
@cop_class = cop_class
|
|
21
|
+
@config = config
|
|
22
|
+
@cop_config = config.for_cop(cop_class.cop_name)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_s
|
|
26
|
+
lines.join("\n")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def lines
|
|
32
|
+
description = description_lines
|
|
33
|
+
|
|
34
|
+
[
|
|
35
|
+
@cop_class.cop_name,
|
|
36
|
+
*section(nil, description),
|
|
37
|
+
*section('Properties', property_lines),
|
|
38
|
+
*documentation_sections(description).flat_map { |title, body| section(title, body) },
|
|
39
|
+
*section('Configuration', configuration_lines),
|
|
40
|
+
*section('References', reference_lines)
|
|
41
|
+
]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def section(title, body)
|
|
45
|
+
return [] if body.empty?
|
|
46
|
+
|
|
47
|
+
heading = title ? [title, ''] : []
|
|
48
|
+
['', *heading, *body.map { |line| line.empty? ? '' : " #{line}" }]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def description_lines
|
|
52
|
+
Array(@cop_config['Description']).flat_map { |line| line.split("\n") }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def property_lines
|
|
56
|
+
[
|
|
57
|
+
"Enabled: #{@cop_config.fetch('Enabled', true)}",
|
|
58
|
+
"Safe: #{@cop_config.fetch('Safe', true)}",
|
|
59
|
+
"Autocorrect: #{autocorrect_description}",
|
|
60
|
+
*version_lines,
|
|
61
|
+
*scope_lines
|
|
62
|
+
]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Which files the cop looks at. A cop that only runs on Gemfiles
|
|
66
|
+
# explains an absent offense better than anything else here does.
|
|
67
|
+
def scope_lines
|
|
68
|
+
[
|
|
69
|
+
*patterns_line('Applies to: ', @cop_config['Include']),
|
|
70
|
+
*patterns_line('Excludes: ', @cop_config['Exclude'])
|
|
71
|
+
]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def patterns_line(label, patterns)
|
|
75
|
+
patterns = Array(patterns).compact
|
|
76
|
+
return [] if patterns.empty?
|
|
77
|
+
|
|
78
|
+
["#{label}#{patterns.map { |pattern| readable_pattern(pattern) }.join(', ')}"]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# `Exclude` patterns are absolutized against the config that set them,
|
|
82
|
+
# which makes for a wall of identical prefixes. A user config can also
|
|
83
|
+
# hold a regexp rather than a glob.
|
|
84
|
+
def readable_pattern(pattern)
|
|
85
|
+
pattern.is_a?(String) ? PathUtil.smart_path(pattern) : pattern.inspect
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def autocorrect_description
|
|
89
|
+
return 'not supported' unless @cop_class.support_autocorrect?
|
|
90
|
+
|
|
91
|
+
# Asks the cop, so `AutoCorrect` is read the way the cop reads it.
|
|
92
|
+
cop = @cop_class.new(@config)
|
|
93
|
+
return 'disabled' unless cop.always_autocorrect? || cop.contextual_autocorrect?
|
|
94
|
+
|
|
95
|
+
description = cop.safe_autocorrect? ? 'safe, applied by -a' : 'unsafe, applied by -A only'
|
|
96
|
+
# Contextual corrections wait until the code is finished, which an
|
|
97
|
+
# editor or an agent mid-edit cannot promise, so they have to ask.
|
|
98
|
+
description += ', but through LSP or MCP only on request' if cop.contextual_autocorrect?
|
|
99
|
+
description
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def version_lines
|
|
103
|
+
lines = []
|
|
104
|
+
lines << "Added: #{@cop_config['VersionAdded']}" if @cop_config['VersionAdded']
|
|
105
|
+
lines << "Changed: #{@cop_config['VersionChanged']}" if @cop_config['VersionChanged']
|
|
106
|
+
lines
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def configuration_lines
|
|
110
|
+
(@cop_config.keys - METADATA_KEYS).sort.map do |key|
|
|
111
|
+
"#{key}: #{format_value(@cop_config[key])}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def format_value(value)
|
|
116
|
+
value.is_a?(Array) ? value.join(', ') : value.to_s
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def reference_lines
|
|
120
|
+
annotator = MessageAnnotator.new(@config, @cop_class.cop_name, @cop_config, {})
|
|
121
|
+
|
|
122
|
+
[*annotator.urls, Documentation.url_for(@cop_class, @config)].compact
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# The comment above the class opens by restating the description, which
|
|
126
|
+
# is already printed above, so that opening is dropped.
|
|
127
|
+
def documentation_sections(description)
|
|
128
|
+
CopDocumentation.new(@cop_class).sections.filter_map do |title, body|
|
|
129
|
+
body -= description if title == 'Details'
|
|
130
|
+
body = strip_blank(body)
|
|
131
|
+
[title, body] unless body.empty?
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def strip_blank(lines)
|
|
136
|
+
lines.drop_while(&:empty?).reverse.drop_while(&:empty?).reverse
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -109,8 +109,20 @@ module RuboCop
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def inside_string_ranges(node)
|
|
112
|
-
return
|
|
112
|
+
return source_string_ranges unless node.is_a?(Parser::AST::Node)
|
|
113
113
|
|
|
114
|
+
string_ranges(node)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def source_string_ranges
|
|
118
|
+
return [] unless processed_source.ast
|
|
119
|
+
return @source_string_ranges if @source_string_ranges_source.equal?(processed_source)
|
|
120
|
+
|
|
121
|
+
@source_string_ranges_source = processed_source
|
|
122
|
+
@source_string_ranges = string_ranges(processed_source.ast)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def string_ranges(node)
|
|
114
126
|
node.each_node(:any_str).filter_map { |n| inside_string_range(n) }
|
|
115
127
|
end
|
|
116
128
|
|
|
@@ -17,6 +17,7 @@ module RuboCop
|
|
|
17
17
|
|
|
18
18
|
def call(corrector)
|
|
19
19
|
corrector.replace(offending_range, correction)
|
|
20
|
+
corrector.replace(block_node.loc.end, closing_keyword) if block_node.braces?
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
private
|
|
@@ -24,13 +25,27 @@ module RuboCop
|
|
|
24
25
|
attr_reader :block_node, :collection_node, :argument_node
|
|
25
26
|
|
|
26
27
|
def correction
|
|
27
|
-
if block_node.arguments?
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
keyword = if block_node.arguments?
|
|
29
|
+
format(
|
|
30
|
+
CORRECTION_WITH_ARGUMENTS,
|
|
31
|
+
collection: collection_node.source,
|
|
32
|
+
variables: argument_node.children.map(&:source).join(', ')
|
|
33
|
+
)
|
|
34
|
+
else
|
|
35
|
+
format(CORRECTION_WITHOUT_ARGUMENTS, enumerable: collection_node.source)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
padding_needed?(offending_range.end_pos) ? "#{keyword} " : keyword
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def closing_keyword
|
|
42
|
+
padding_needed?(block_node.loc.end.begin_pos - 1) ? ' end' : 'end'
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def padding_needed?(position)
|
|
46
|
+
character = block_node.source_range.source_buffer.source[position]
|
|
47
|
+
|
|
48
|
+
!character.nil? && !character.match?(/\s/)
|
|
34
49
|
end
|
|
35
50
|
|
|
36
51
|
def offending_range
|
|
@@ -29,6 +29,10 @@ module RuboCop
|
|
|
29
29
|
insert_arguments(corrector)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
+
def replace_delimiters?
|
|
33
|
+
!block_node.braces? && arg_to_unparenthesized_call?
|
|
34
|
+
end
|
|
35
|
+
|
|
32
36
|
private
|
|
33
37
|
|
|
34
38
|
attr_reader :block_node, :method, :arguments
|
|
@@ -77,7 +81,7 @@ module RuboCop
|
|
|
77
81
|
end
|
|
78
82
|
|
|
79
83
|
def replace_delimiters(corrector)
|
|
80
|
-
return
|
|
84
|
+
return unless replace_delimiters?
|
|
81
85
|
|
|
82
86
|
corrector.insert_after(block_begin, ' ') unless separating_space?
|
|
83
87
|
|
|
@@ -90,7 +94,7 @@ module RuboCop
|
|
|
90
94
|
# `;`; joining everything with `,` would turn them into extra parameters
|
|
91
95
|
# and change the lambda's arity.
|
|
92
96
|
regular, shadow = arguments.children.partition { |arg| !arg.shadowarg_type? }
|
|
93
|
-
arg_string = regular.map(
|
|
97
|
+
arg_string = regular.map { |arg| argument_source(arg) }.join(', ')
|
|
94
98
|
arg_string += "; #{shadow.map(&:source).join(', ')}" unless shadow.empty?
|
|
95
99
|
arg_string
|
|
96
100
|
end
|
|
@@ -140,6 +144,23 @@ module RuboCop
|
|
|
140
144
|
def separating_space?
|
|
141
145
|
block_begin.source_buffer.source[block_begin.begin_pos + 2].match?(/\s/)
|
|
142
146
|
end
|
|
147
|
+
|
|
148
|
+
def argument_source(argument)
|
|
149
|
+
return argument.source unless argument.type?(:optarg, :kwoptarg)
|
|
150
|
+
return argument.source unless operator_expression?(argument.default_value)
|
|
151
|
+
|
|
152
|
+
default_value = argument.default_value
|
|
153
|
+
name = argument.source_range.begin.join(default_value.source_range.begin).source
|
|
154
|
+
|
|
155
|
+
"#{name}(#{default_value.source})"
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def operator_expression?(node)
|
|
159
|
+
return true if node.type?(:range, :if, :and, :or)
|
|
160
|
+
return false unless node.call_type?
|
|
161
|
+
|
|
162
|
+
node.operator_method? && !node.method?(:[])
|
|
163
|
+
end
|
|
143
164
|
end
|
|
144
165
|
end
|
|
145
166
|
end
|
|
@@ -21,14 +21,55 @@ module RuboCop
|
|
|
21
21
|
corrector.insert_after(node.loc.end, ' ')
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def heredoc_strands_code_after_close_paren?(node)
|
|
25
|
+
return false unless heredoc_body_before_close_paren?(node)
|
|
26
|
+
|
|
27
|
+
after_paren = text_after_close_paren(node)
|
|
28
|
+
|
|
29
|
+
!after_paren.empty? && !after_paren.start_with?('.', '&.', ',')
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
private
|
|
25
33
|
|
|
26
34
|
# When the line above `)` ends with a comment and a chained call follows `)`,
|
|
27
35
|
# crossing the newline would pull the chain into the comment. Preserve the newline.
|
|
36
|
+
# When a heredoc body comes before `)`, a chained call has to start on the line
|
|
37
|
+
# after the terminator instead, since the terminator must stay alone on its line.
|
|
28
38
|
def remove_close_paren(corrector, node, buffer)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
39
|
+
if heredoc_above_close_paren_swallows_chain?(node)
|
|
40
|
+
range = range_with_surrounding_space(range: node.loc.end, buffer: buffer, side: :left)
|
|
41
|
+
|
|
42
|
+
corrector.replace(range, "\n")
|
|
43
|
+
else
|
|
44
|
+
newlines = !comment_above_close_paren_swallows_chain?(node, buffer)
|
|
45
|
+
range = range_with_surrounding_space(
|
|
46
|
+
range: node.loc.end, buffer: buffer, side: :left, newlines: newlines
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
corrector.remove(range)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def heredoc_above_close_paren_swallows_chain?(node)
|
|
54
|
+
return false unless heredoc_body_before_close_paren?(node)
|
|
55
|
+
|
|
56
|
+
text_after_close_paren(node).start_with?('.', '&.')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def heredoc_body_before_close_paren?(node)
|
|
60
|
+
return false unless (last_child = node.children.last)
|
|
61
|
+
|
|
62
|
+
close_paren_pos = node.loc.end.begin_pos
|
|
63
|
+
|
|
64
|
+
last_child.each_node(:any_str).any? do |str_node|
|
|
65
|
+
str_node.heredoc? && str_node.loc.heredoc_end.end_pos <= close_paren_pos
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def text_after_close_paren(node)
|
|
70
|
+
close_paren = node.loc.end
|
|
71
|
+
|
|
72
|
+
close_paren.source_line[(close_paren.column + 1)..].to_s.lstrip
|
|
32
73
|
end
|
|
33
74
|
|
|
34
75
|
def comment_above_close_paren_swallows_chain?(node, buffer)
|
|
@@ -46,12 +87,8 @@ module RuboCop
|
|
|
46
87
|
end
|
|
47
88
|
|
|
48
89
|
def chained_after_close_paren?(node)
|
|
49
|
-
|
|
50
|
-
line_text = close_paren.source_line
|
|
51
|
-
after_paren = line_text[(close_paren.column + 1)..]
|
|
52
|
-
return false if after_paren.nil?
|
|
90
|
+
trimmed = text_after_close_paren(node)
|
|
53
91
|
|
|
54
|
-
trimmed = after_paren.lstrip
|
|
55
92
|
!trimmed.empty? && !trimmed.start_with?('#')
|
|
56
93
|
end
|
|
57
94
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module RuboCop
|
|
4
|
-
module Cop # rubocop:disable Style/Documentation
|
|
4
|
+
module Cop # rubocop:disable Style/Documentation -- a namespace that only autoloads the correctors below
|
|
5
5
|
# Autoloads corrector classes used by cops. Classes are autoloaded to reduce the number of
|
|
6
6
|
# required classes because they're referenced only when autocorrection is performed.
|
|
7
7
|
|
|
8
|
-
# rubocop:disable Layout/LineLength
|
|
8
|
+
# rubocop:disable Layout/LineLength -- the autoload paths do not wrap
|
|
9
9
|
autoload :AlignmentCorrector, 'rubocop/cop/correctors/alignment_corrector'
|
|
10
10
|
autoload :ConditionCorrector, 'rubocop/cop/correctors/condition_corrector'
|
|
11
11
|
autoload :EachToForCorrector, 'rubocop/cop/correctors/each_to_for_corrector'
|
|
@@ -14,7 +14,7 @@ module RuboCop
|
|
|
14
14
|
# @api private
|
|
15
15
|
def url_for(cop_class, config = nil)
|
|
16
16
|
base = department_to_basename(cop_class.department)
|
|
17
|
-
fragment = cop_class.cop_name.downcase.
|
|
17
|
+
fragment = cop_class.cop_name.downcase.delete('/')
|
|
18
18
|
base_url = base_url_for(cop_class, config)
|
|
19
19
|
extension = extension_for(cop_class, config)
|
|
20
20
|
|
|
@@ -109,12 +109,6 @@ module RuboCop
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
-
def match_block_variable_name?(receiver_name)
|
|
113
|
-
gem_specification(processed_source.ast) do |block_variable_name|
|
|
114
|
-
return block_variable_name == receiver_name
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
112
|
def add_dependency_method?(method_name)
|
|
119
113
|
ADD_DEPENDENCY_METHODS.include?(method_name)
|
|
120
114
|
end
|
|
@@ -80,12 +80,6 @@ module RuboCop
|
|
|
80
80
|
|
|
81
81
|
private
|
|
82
82
|
|
|
83
|
-
def previous_declaration(node)
|
|
84
|
-
declarations = dependency_declarations(processed_source.ast)
|
|
85
|
-
node_index = declarations.find_index(node)
|
|
86
|
-
declarations.to_a[node_index - 1]
|
|
87
|
-
end
|
|
88
|
-
|
|
89
83
|
def get_dependency_name(node)
|
|
90
84
|
node.method_name
|
|
91
85
|
end
|
|
@@ -92,7 +92,7 @@ module RuboCop
|
|
|
92
92
|
(str "true")
|
|
93
93
|
PATTERN
|
|
94
94
|
|
|
95
|
-
def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler
|
|
95
|
+
def on_block(node) # rubocop:disable Metrics/MethodLength, InternalAffairs/NumblockHandler, InternalAffairs/ItblockHandler -- the gemspec block is matched by its named block variable
|
|
96
96
|
gem_specification(node) do |block_var|
|
|
97
97
|
metadata_value = metadata(node)
|
|
98
98
|
mfa_value = mfa_value(metadata_value)
|
|
@@ -147,7 +147,7 @@ module RuboCop
|
|
|
147
147
|
badge: badge,
|
|
148
148
|
version_added: version_added)
|
|
149
149
|
|
|
150
|
-
injector.inject do # rubocop:disable Lint/UnexpectedBlockArity
|
|
150
|
+
injector.inject do # rubocop:disable Lint/UnexpectedBlockArity -- this `inject` is the injector API, not `Enumerable#inject`
|
|
151
151
|
output.puts(format(CONFIGURATION_ADDED_MESSAGE,
|
|
152
152
|
configuration_file_path: config_file_path))
|
|
153
153
|
end
|
|
@@ -201,11 +201,8 @@ module RuboCop
|
|
|
201
201
|
def add_newline?(node)
|
|
202
202
|
# Determine if a blank line should be inserted before the new directive
|
|
203
203
|
# in order to spread out pattern matchers
|
|
204
|
-
|
|
205
|
-
return false unless
|
|
206
|
-
|
|
207
|
-
prev_sibling = node.parent.child_nodes[node.sibling_index - 1]
|
|
208
|
-
return false unless prev_sibling && pattern_matcher?(prev_sibling)
|
|
204
|
+
prev_sibling = node.left_sibling
|
|
205
|
+
return false unless prev_sibling.is_a?(AST::Node) && pattern_matcher?(prev_sibling)
|
|
209
206
|
|
|
210
207
|
node.loc.line == last_line(prev_sibling) + 1
|
|
211
208
|
end
|
|
@@ -46,13 +46,6 @@ module RuboCop
|
|
|
46
46
|
|
|
47
47
|
private
|
|
48
48
|
|
|
49
|
-
def arguments_range(node)
|
|
50
|
-
range_between(
|
|
51
|
-
node.first_argument.source_range.begin_pos,
|
|
52
|
-
node.last_argument.source_range.end_pos
|
|
53
|
-
)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
49
|
def group_satisfied?(group_types, symbol_args)
|
|
57
50
|
group_types.all? { |type| symbol_args.any? { |arg| arg.value == type } }
|
|
58
51
|
end
|
|
@@ -75,7 +75,7 @@ module RuboCop
|
|
|
75
75
|
@on_csend_definition = node if node.new_identifier.value == :on_csend
|
|
76
76
|
end
|
|
77
77
|
|
|
78
|
-
def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend
|
|
78
|
+
def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend -- this cop is what enforces the rule, and does not apply to itself
|
|
79
79
|
return unless (new_identifier = node.first_argument)
|
|
80
80
|
return unless new_identifier.basic_literal?
|
|
81
81
|
|
|
@@ -31,15 +31,9 @@ module RuboCop
|
|
|
31
31
|
dup_arguments = arguments.dup
|
|
32
32
|
dup_arguments.delete(config_node)
|
|
33
33
|
|
|
34
|
-
corrector.replace(
|
|
34
|
+
corrector.replace(arguments_range(node), dup_arguments.map(&:source).join(', '))
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def offense_range(arguments)
|
|
41
|
-
range_between(arguments.first.source_range.begin_pos, arguments.last.source_range.end_pos)
|
|
42
|
-
end
|
|
43
37
|
end
|
|
44
38
|
end
|
|
45
39
|
end
|
|
@@ -109,7 +109,7 @@ module RuboCop
|
|
|
109
109
|
end
|
|
110
110
|
|
|
111
111
|
def on_if(node)
|
|
112
|
-
|
|
112
|
+
node.condition.each_node(:send) do |cond|
|
|
113
113
|
add_offense(cond, message: MSG_FOR_CONDITIONAL_USE) if style_detected_api_used?(cond)
|
|
114
114
|
end
|
|
115
115
|
end
|
|
@@ -134,12 +134,6 @@ module RuboCop
|
|
|
134
134
|
no_acceptable_style_check(node) ||
|
|
135
135
|
style_detected_check(node)
|
|
136
136
|
end
|
|
137
|
-
|
|
138
|
-
def traverse_condition(condition, &block)
|
|
139
|
-
yield condition if condition.send_type?
|
|
140
|
-
|
|
141
|
-
condition.each_child_node { |child| traverse_condition(child, &block) }
|
|
142
|
-
end
|
|
143
137
|
end
|
|
144
138
|
end
|
|
145
139
|
end
|
|
@@ -68,6 +68,7 @@ module RuboCop
|
|
|
68
68
|
# end
|
|
69
69
|
#
|
|
70
70
|
class BlockAlignment < Base
|
|
71
|
+
include Alignment
|
|
71
72
|
include ConfigurableEnforcedStyle
|
|
72
73
|
include RangeHelp
|
|
73
74
|
extend AutoCorrector
|
|
@@ -154,6 +155,32 @@ module RuboCop
|
|
|
154
155
|
else
|
|
155
156
|
start_for_line_node(node)
|
|
156
157
|
end
|
|
158
|
+
|
|
159
|
+
if using_tabs? && (indentation = anchor_indentation(ancestor_node, node))
|
|
160
|
+
replace_end_indentation(corrector, node, indentation)
|
|
161
|
+
else
|
|
162
|
+
shift_end_to_start_col(corrector, ancestor_node, node)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def anchor_indentation(ancestor_node, node)
|
|
167
|
+
if style == :start_of_block
|
|
168
|
+
do_line_anchor_loc(node, node.loc.begin).source_line[/\A\s*/]
|
|
169
|
+
else
|
|
170
|
+
anchor_loc = (ancestor_node || node).source_range
|
|
171
|
+
anchor_loc.source_line[/\A\s*/] if begins_its_line?(anchor_loc)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def replace_end_indentation(corrector, node, indentation)
|
|
176
|
+
loc_end = node.loc.end
|
|
177
|
+
whitespace = range_between(loc_end.begin_pos - loc_end.column, loc_end.begin_pos)
|
|
178
|
+
return if whitespace.source == indentation
|
|
179
|
+
|
|
180
|
+
corrector.replace(whitespace, indentation)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def shift_end_to_start_col(corrector, ancestor_node, node)
|
|
157
184
|
start_col = compute_start_col(ancestor_node, node)
|
|
158
185
|
loc_end = node.loc.end
|
|
159
186
|
delta = start_col - loc_end.column
|