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
data/lib/rubocop/lsp/runtime.rb
CHANGED
|
@@ -17,27 +17,31 @@ module RuboCop
|
|
|
17
17
|
# Runtime for Language Server Protocol of RuboCop.
|
|
18
18
|
# @api private
|
|
19
19
|
class Runtime
|
|
20
|
-
attr_writer :safe_autocorrect, :lint_mode, :layout_mode
|
|
20
|
+
attr_writer :safe_autocorrect, :lint_mode, :layout_mode, :raise_cop_error
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
# Without `lsp_mode`, offenses keep the locations and messages the
|
|
23
|
+
# command line gives them, rather than the ones meant for an editor.
|
|
24
|
+
def initialize(config_store, lsp_mode: true)
|
|
25
|
+
RuboCop::LSP.enable if lsp_mode
|
|
24
26
|
|
|
25
27
|
@runner = RuboCop::Lsp::StdinRunner.new(config_store)
|
|
26
28
|
|
|
27
29
|
@safe_autocorrect = true
|
|
28
30
|
@lint_mode = false
|
|
29
31
|
@layout_mode = false
|
|
32
|
+
@raise_cop_error = true
|
|
30
33
|
end
|
|
31
34
|
|
|
32
|
-
def format(path, text, command:, prism_result: nil)
|
|
35
|
+
def format(path, text, command:, prism_result: nil, options: {})
|
|
33
36
|
safe_autocorrect = if command
|
|
34
37
|
command == 'rubocop.formatAutocorrects'
|
|
35
38
|
else
|
|
36
39
|
@safe_autocorrect
|
|
37
40
|
end
|
|
38
41
|
|
|
39
|
-
formatting_options = {
|
|
40
|
-
|
|
42
|
+
formatting_options = {
|
|
43
|
+
autocorrect: true, safe_autocorrect: safe_autocorrect, raise_cop_error: @raise_cop_error
|
|
44
|
+
}.merge(call_options(options))
|
|
41
45
|
|
|
42
46
|
@runner.run(path, text, formatting_options, prism_result: prism_result)
|
|
43
47
|
@runner.formatted_source
|
|
@@ -48,17 +52,39 @@ module RuboCop
|
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
def offenses(path, text, document_encoding = nil, prism_result: nil)
|
|
51
|
-
|
|
52
|
-
diagnostic_options[:only] = config_only_options if @lint_mode || @layout_mode
|
|
53
|
-
|
|
54
|
-
@runner.run(path, text, diagnostic_options, prism_result: prism_result)
|
|
55
|
+
found = raw_offenses(path, text, prism_result: prism_result)
|
|
55
56
|
processed_source = @runner.processed_source
|
|
56
57
|
config = @runner.config_for_working_directory
|
|
57
|
-
|
|
58
|
+
found.map do |offense|
|
|
58
59
|
build_diagnostic(offense, path, document_encoding, processed_source, config)
|
|
59
60
|
end
|
|
60
61
|
end
|
|
61
62
|
|
|
63
|
+
# The offenses before they are converted to LSP diagnostics, for callers
|
|
64
|
+
# that do not speak LSP.
|
|
65
|
+
def raw_offenses(path, text, prism_result: nil, options: {})
|
|
66
|
+
diagnostic_options = { raise_cop_error: @raise_cop_error }.merge(call_options(options))
|
|
67
|
+
|
|
68
|
+
@runner.run(path, text, diagnostic_options, prism_result: prism_result)
|
|
69
|
+
@runner.offenses
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The offenses the last `format` found but didn't correct, located in the
|
|
73
|
+
# source it returned.
|
|
74
|
+
def uncorrected_offenses
|
|
75
|
+
@runner.offenses.reject(&:corrected?)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# What went wrong in the last run. Cop errors only end up here when
|
|
79
|
+
# `raise_cop_error` is off; otherwise they are raised.
|
|
80
|
+
def errors
|
|
81
|
+
@runner.errors
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def warnings
|
|
85
|
+
@runner.warnings
|
|
86
|
+
end
|
|
87
|
+
|
|
62
88
|
private
|
|
63
89
|
|
|
64
90
|
def build_diagnostic(offense, path, document_encoding, processed_source, config)
|
|
@@ -71,6 +97,16 @@ module RuboCop
|
|
|
71
97
|
).to_lsp_diagnostic(config)
|
|
72
98
|
end
|
|
73
99
|
|
|
100
|
+
# What a caller adds for one call, such as `only` and `except` to select
|
|
101
|
+
# the cops, or `editing` to hold back the corrections of cops with
|
|
102
|
+
# `AutoCorrect: contextual`, as LSP mode does. Without `only`, the cops
|
|
103
|
+
# are the departments a lint or layout mode limits the server to.
|
|
104
|
+
def call_options(options)
|
|
105
|
+
return options if options[:only] || !(@lint_mode || @layout_mode)
|
|
106
|
+
|
|
107
|
+
options.merge(only: config_only_options)
|
|
108
|
+
end
|
|
109
|
+
|
|
74
110
|
def config_only_options
|
|
75
111
|
only_options = []
|
|
76
112
|
only_options << 'Lint' if @lint_mode
|
|
@@ -23,7 +23,6 @@ module RuboCop
|
|
|
23
23
|
stderr: true,
|
|
24
24
|
force_exclusion: true,
|
|
25
25
|
formatters: ['RuboCop::Formatter::BaseFormatter'],
|
|
26
|
-
raise_cop_error: true,
|
|
27
26
|
todo_file: nil,
|
|
28
27
|
todo_ignore_files: []
|
|
29
28
|
}.freeze
|
|
@@ -41,6 +40,13 @@ module RuboCop
|
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
def run(path, contents, options, prism_result: nil)
|
|
43
|
+
# The cops mobilized for a configuration are cached, which only holds while
|
|
44
|
+
# every run asks for the same ones.
|
|
45
|
+
selection = options.values_at(:only, :except)
|
|
46
|
+
unless selection == @cop_selection
|
|
47
|
+
forget_mobilized_cops
|
|
48
|
+
@cop_selection = selection
|
|
49
|
+
end
|
|
44
50
|
@options = options.merge(DEFAULT_RUBOCOP_OPTIONS)
|
|
45
51
|
@options[:stdin] = contents
|
|
46
52
|
|
|
@@ -86,10 +92,10 @@ module RuboCop
|
|
|
86
92
|
@offenses = offenses
|
|
87
93
|
end
|
|
88
94
|
|
|
89
|
-
def do_inspection_loop(file)
|
|
90
|
-
|
|
91
|
-
@processed_source =
|
|
92
|
-
[
|
|
95
|
+
def do_inspection_loop(file, source = nil)
|
|
96
|
+
processed_source, offenses = super
|
|
97
|
+
@processed_source = processed_source
|
|
98
|
+
[processed_source, offenses]
|
|
93
99
|
end
|
|
94
100
|
end
|
|
95
101
|
end
|
data/lib/rubocop/lsp.rb
CHANGED
|
@@ -12,6 +12,7 @@ module RuboCop
|
|
|
12
12
|
encoding: '(?:en)?coding',
|
|
13
13
|
frozen_string_literal: 'frozen[_-]string[_-]literal',
|
|
14
14
|
rbs_inline: 'rbs_inline',
|
|
15
|
+
warn_indent: 'warn[_-]indent',
|
|
15
16
|
shareable_constant_value: 'shareable[_-]constant[_-]value',
|
|
16
17
|
typed: 'typed'
|
|
17
18
|
}.freeze
|
|
@@ -38,6 +39,7 @@ module RuboCop
|
|
|
38
39
|
frozen_string_literal_specified? ||
|
|
39
40
|
encoding_specified? ||
|
|
40
41
|
rbs_inline_specified? ||
|
|
42
|
+
warn_indent_specified? ||
|
|
41
43
|
shareable_constant_value_specified? ||
|
|
42
44
|
typed_specified?
|
|
43
45
|
end
|
|
@@ -77,6 +79,13 @@ module RuboCop
|
|
|
77
79
|
specified?(frozen_string_literal)
|
|
78
80
|
end
|
|
79
81
|
|
|
82
|
+
# Was a warn_indent specified?
|
|
83
|
+
#
|
|
84
|
+
# @return [Boolean]
|
|
85
|
+
def warn_indent_specified?
|
|
86
|
+
specified?(warn_indent)
|
|
87
|
+
end
|
|
88
|
+
|
|
80
89
|
# Was a shareable_constant_value specified?
|
|
81
90
|
#
|
|
82
91
|
# @return [Boolean]
|
|
@@ -100,6 +109,13 @@ module RuboCop
|
|
|
100
109
|
end
|
|
101
110
|
end
|
|
102
111
|
|
|
112
|
+
# Expose the `warn_indent` value.
|
|
113
|
+
#
|
|
114
|
+
# @return [String] for warn_indent config
|
|
115
|
+
def warn_indent
|
|
116
|
+
extract_warn_indent
|
|
117
|
+
end
|
|
118
|
+
|
|
103
119
|
# Expose the `shareable_constant_value` value coerced to a boolean if possible.
|
|
104
120
|
#
|
|
105
121
|
# @return [String] for shareable_constant_value config
|
|
@@ -216,6 +232,10 @@ module RuboCop
|
|
|
216
232
|
# Emacs comments cannot specify RBS::inline behavior.
|
|
217
233
|
def extract_rbs_inline_value; end
|
|
218
234
|
|
|
235
|
+
def extract_warn_indent
|
|
236
|
+
match(KEYWORDS[:warn_indent])
|
|
237
|
+
end
|
|
238
|
+
|
|
219
239
|
def extract_shareable_constant_value
|
|
220
240
|
match(KEYWORDS[:shareable_constant_value])
|
|
221
241
|
end
|
|
@@ -258,6 +278,9 @@ module RuboCop
|
|
|
258
278
|
# Vim comments cannot specify RBS::inline behavior.
|
|
259
279
|
def extract_rbs_inline_value; end
|
|
260
280
|
|
|
281
|
+
# Vim comments cannot specify indentation warning behavior.
|
|
282
|
+
def warn_indent; end
|
|
283
|
+
|
|
261
284
|
# Vim comments cannot specify shareable constant values behavior.
|
|
262
285
|
def shareable_constant_value; end
|
|
263
286
|
|
|
@@ -316,6 +339,10 @@ module RuboCop
|
|
|
316
339
|
extract(/\A\s*#\s*#{KEYWORDS[:rbs_inline]}:\s*#{TOKEN}\s*\z/io)
|
|
317
340
|
end
|
|
318
341
|
|
|
342
|
+
def extract_warn_indent
|
|
343
|
+
extract(/\A\s*#\s*#{KEYWORDS[:warn_indent]}:\s*#{TOKEN}\s*\z/io)
|
|
344
|
+
end
|
|
345
|
+
|
|
319
346
|
def extract_shareable_constant_value
|
|
320
347
|
extract(/\A\s*#\s*#{KEYWORDS[:shareable_constant_value]}:\s*#{TOKEN}\s*\z/io)
|
|
321
348
|
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module MCP
|
|
5
|
+
# What an autocorrection request asks for, shared by every file it corrects.
|
|
6
|
+
# The keywords are the tool's arguments, so an unknown one is refused.
|
|
7
|
+
# @api private
|
|
8
|
+
class AutocorrectionRequest
|
|
9
|
+
PROPERTIES = {
|
|
10
|
+
safety: { type: 'boolean' },
|
|
11
|
+
contextual: { type: 'boolean' },
|
|
12
|
+
dry_run: { type: 'boolean' },
|
|
13
|
+
max_offenses_per_cop: { type: 'integer', minimum: 1 }
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
# The offenses left over come back after the files are written, so they're
|
|
17
|
+
# capped unless the agent asks otherwise: a result too big for the client
|
|
18
|
+
# would hide what was done.
|
|
19
|
+
DEFAULT_MAX_OFFENSES_PER_COP = 5
|
|
20
|
+
|
|
21
|
+
attr_reader :scope, :limit
|
|
22
|
+
|
|
23
|
+
def initialize(scope, safety: true, contextual: false, dry_run: false,
|
|
24
|
+
max_offenses_per_cop: DEFAULT_MAX_OFFENSES_PER_COP)
|
|
25
|
+
@scope = scope
|
|
26
|
+
@safety = safety
|
|
27
|
+
@contextual = contextual
|
|
28
|
+
@dry_run = dry_run
|
|
29
|
+
@limit = OffenseLimit.new(max_offenses_per_cop)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def dry_run?
|
|
33
|
+
@dry_run
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The options `LSP::Runtime#format` takes to apply the corrections
|
|
37
|
+
# `safety` and `contextual` allow, from the cops the scope selects.
|
|
38
|
+
def format_options
|
|
39
|
+
command = @safety ? 'rubocop.formatAutocorrects' : 'rubocop.formatAutocorrectsAll'
|
|
40
|
+
{ command: command, options: runtime_options }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The options the LSP runtime takes for each call the request makes.
|
|
44
|
+
# Cops with `AutoCorrect: contextual` hold back corrections that get in
|
|
45
|
+
# the way of code still being written, such as removing a variable that
|
|
46
|
+
# is about to be used, so an agent that is done editing has to ask for them.
|
|
47
|
+
def runtime_options
|
|
48
|
+
{ **@scope.cop_options, editing: !@contextual }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module MCP
|
|
5
|
+
# The `rubocop_explain` tool: what cops do, as `--explain` prints it.
|
|
6
|
+
# @api private
|
|
7
|
+
class ExplainTool
|
|
8
|
+
include RuboCop::CLI::Command::CopNames
|
|
9
|
+
|
|
10
|
+
DESCRIPTION =
|
|
11
|
+
'Explain what cops do: the problem each one targets, bad and good examples, ' \
|
|
12
|
+
'its configuration as this project resolves it, and whether it autocorrects. ' \
|
|
13
|
+
'Takes cop names as offenses report them, such as `Style/StringLiterals`. ' \
|
|
14
|
+
'Pass the `path` of a file to see the configuration that applies to it.'
|
|
15
|
+
INPUT_SCHEMA = {
|
|
16
|
+
properties: {
|
|
17
|
+
cop_names: { type: 'array', items: { type: 'string' }, minItems: 1 },
|
|
18
|
+
path: { type: 'string' }
|
|
19
|
+
},
|
|
20
|
+
required: ['cop_names'],
|
|
21
|
+
additionalProperties: false
|
|
22
|
+
}.freeze
|
|
23
|
+
ANNOTATIONS = {
|
|
24
|
+
title: "RuboCop's cop explanation", destructive_hint: false, idempotent_hint: true,
|
|
25
|
+
open_world_hint: false, read_only_hint: true
|
|
26
|
+
}.freeze
|
|
27
|
+
|
|
28
|
+
def initialize(config_store)
|
|
29
|
+
@config_store = config_store
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# The tool's block does not run in this instance, so it reaches
|
|
33
|
+
# `explain` through a method object it closes over.
|
|
34
|
+
def to_tool
|
|
35
|
+
explain = method(:explain)
|
|
36
|
+
|
|
37
|
+
::MCP::Tool.define(
|
|
38
|
+
name: 'rubocop_explain',
|
|
39
|
+
description: DESCRIPTION,
|
|
40
|
+
input_schema: INPUT_SCHEMA,
|
|
41
|
+
annotations: ANNOTATIONS
|
|
42
|
+
) do |cop_names:, path: nil|
|
|
43
|
+
::MCP::Tool::Response.new([{ type: 'text', text: explain.call(cop_names, path) }])
|
|
44
|
+
rescue RuboCop::Error => e
|
|
45
|
+
::MCP::Tool::Response.new([{ type: 'text', text: e.message }], error: true)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# Explains the cops it recognizes and then names the ones it does not, as
|
|
52
|
+
# `--explain` does, so a typo does not cost the explanations asked for
|
|
53
|
+
# alongside it. The configuration is loaded first, since that is what
|
|
54
|
+
# registers the cops of any plugins it names.
|
|
55
|
+
def explain(cop_names, path)
|
|
56
|
+
config = path ? @config_store.for_file(path) : @config_store.for_pwd
|
|
57
|
+
explanations = known_cop_classes(cop_names).map do |cop_class|
|
|
58
|
+
Cop::CopExplanation.new(cop_class, config).to_s
|
|
59
|
+
end
|
|
60
|
+
validate_cop_names!(cop_names)
|
|
61
|
+
|
|
62
|
+
explanations.join("\n\n")
|
|
63
|
+
rescue IncorrectCopNameError => e
|
|
64
|
+
raise RuboCop::Error, [*explanations, e.message].join("\n\n")
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module MCP
|
|
5
|
+
# What a request asks RuboCop to look at: which cops run, as `--only` and
|
|
6
|
+
# `--except` choose them, and, when checking files, whether to stick to the
|
|
7
|
+
# ones git says changed, as `--changed` does.
|
|
8
|
+
# @api private
|
|
9
|
+
class Scope
|
|
10
|
+
PROPERTIES = {
|
|
11
|
+
only: {
|
|
12
|
+
type: 'array', items: { type: 'string' },
|
|
13
|
+
description: 'Run only these cops or departments, ' \
|
|
14
|
+
'such as `Style/StringLiterals` or `Lint`.'
|
|
15
|
+
},
|
|
16
|
+
except: {
|
|
17
|
+
type: 'array', items: { type: 'string' },
|
|
18
|
+
description: 'Run every cop except these cops or departments.'
|
|
19
|
+
},
|
|
20
|
+
changed: {
|
|
21
|
+
type: %w[boolean string],
|
|
22
|
+
description: 'Check only the files git says changed: `true` for changes since the ' \
|
|
23
|
+
'last commit, or a revision to compare against, such as `main`.'
|
|
24
|
+
}
|
|
25
|
+
}.freeze
|
|
26
|
+
|
|
27
|
+
# An empty list would select no cops at all rather than leave the choice
|
|
28
|
+
# alone, so it counts as no list.
|
|
29
|
+
#
|
|
30
|
+
# @raise [RuboCop::Error] for a scope the command line would refuse
|
|
31
|
+
def initialize(inline:, only: nil, except: nil, changed: nil)
|
|
32
|
+
@only = only if only&.any?
|
|
33
|
+
@except = except if except&.any?
|
|
34
|
+
@changed = changed == true ? ChangedFiles::DEFAULT_REVISION : changed
|
|
35
|
+
validate(inline)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Hash] the cop selection, among the options the LSP runtime takes
|
|
39
|
+
def cop_options
|
|
40
|
+
{ only: @only, except: @except }.compact
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def select_files(files)
|
|
44
|
+
@changed ? ChangedFiles.new(@changed).filter(files) : files
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Refuses what the command line refuses for the same options. Cop names
|
|
50
|
+
# are left to the runner, which checks them the way `--only` does: short
|
|
51
|
+
# names allowed, and only once the configuration naming a plugin's cops
|
|
52
|
+
# has been loaded.
|
|
53
|
+
def validate(inline)
|
|
54
|
+
raise Error, '`changed` only applies when checking files.' if inline && @changed
|
|
55
|
+
raise Error, '`changed` takes `true` or a git revision.' if @changed == ''
|
|
56
|
+
|
|
57
|
+
validator = OptionsValidator.new(cop_options)
|
|
58
|
+
if validator.only_includes_redundant_disable?
|
|
59
|
+
raise Error, 'Lint/RedundantCopDisableDirective cannot be used with `only`.'
|
|
60
|
+
end
|
|
61
|
+
raise Error, 'Syntax checking cannot be turned off.' if validator.except_syntax?
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|